Upgrade config version and rename

This commit is contained in:
DHR60 2026-01-19 13:24:42 +08:00
parent 1c2d086a71
commit 2d450357d1
15 changed files with 152 additions and 114 deletions

View file

@ -237,6 +237,8 @@ public static class ConfigHandler
item.Security = profileItem.Security;
item.Flow = profileItem.Flow;
item.Password = profileItem.Password;
item.Network = profileItem.Network;
item.HeaderType = profileItem.HeaderType;
item.RequestHost = profileItem.RequestHost;
@ -258,7 +260,7 @@ public static class ConfigHandler
item.CertSha = profileItem.CertSha;
item.EchConfigList = profileItem.EchConfigList;
item.EchForceQuery = profileItem.EchForceQuery;
item.JsonData = profileItem.JsonData;
item.ProtoExtra = profileItem.ProtoExtra;
}
var ret = item.ConfigType switch
@ -963,11 +965,11 @@ public static class ConfigHandler
profileItem.Path = profileItem.Path.TrimEx();
profileItem.StreamSecurity = profileItem.StreamSecurity.TrimEx();
var extraItem = profileItem.GetExtraItem();
var protocolExtra = profileItem.GetProtocolExtra();
if (!Global.Flows.Contains(extraItem.Flow ?? string.Empty))
if (!Global.Flows.Contains(protocolExtra.Flow ?? string.Empty))
{
extraItem.Flow = Global.Flows.First();
protocolExtra.Flow = Global.Flows.First();
}
if (profileItem.Id.IsNullOrEmpty())
{
@ -978,7 +980,7 @@ public static class ConfigHandler
profileItem.Security = Global.None;
}
profileItem.SetExtraItem(extraItem);
profileItem.SetProtocolExtra(protocolExtra);
await AddServerCommon(config, profileItem, toFile);
@ -1033,7 +1035,7 @@ public static class ConfigHandler
/// <returns>0 if successful</returns>
public static async Task<int> AddServerCommon(Config config, ProfileItem profileItem, bool toFile = true)
{
profileItem.ConfigVersion = 2;
profileItem.ConfigVersion = 3;
if (profileItem.StreamSecurity.IsNotEmpty())
{
@ -1097,7 +1099,7 @@ public static class ConfigHandler
return false;
}
var extraItem = o.GetExtraItem();
var protocolExtra = o.GetProtocolExtra();
return o.ConfigType == n.ConfigType
&& AreEqual(o.Address, n.Address)
@ -1109,7 +1111,7 @@ public static class ConfigHandler
&& AreEqual(o.RequestHost, n.RequestHost)
&& AreEqual(o.Path, n.Path)
&& (o.ConfigType == EConfigType.Trojan || o.StreamSecurity == n.StreamSecurity)
&& AreEqual(extraItem.Flow, extraItem.Flow)
&& AreEqual(protocolExtra.Flow, protocolExtra.Flow)
&& AreEqual(o.Sni, n.Sni)
&& AreEqual(o.Alpn, n.Alpn)
&& AreEqual(o.Fingerprint, n.Fingerprint)
@ -1208,7 +1210,7 @@ public static class ConfigHandler
{
ChildItems = childProfileIndexId, MultipleLoad = multipleLoad,
};
profile.SetExtraItem(extraItem);
profile.SetProtocolExtra(extraItem);
var ret = await AddServerCommon(config, profile, true);
result.Success = ret == 0;
result.Data = indexId;

View file

@ -21,10 +21,10 @@ public class BaseFmt
protected static int ToUriQuery(ProfileItem item, string? securityDef, ref Dictionary<string, string> dicQuery)
{
var extraItem = item.GetExtraItem();
if (!extraItem.Flow.IsNullOrEmpty())
var protocolExtra = item.GetProtocolExtra();
if (!protocolExtra.Flow.IsNullOrEmpty())
{
dicQuery.Add("flow", extraItem.Flow);
dicQuery.Add("flow", protocolExtra.Flow);
}
if (item.StreamSecurity.IsNotEmpty())
@ -209,9 +209,9 @@ public class BaseFmt
protected static int ResolveUriQuery(NameValueCollection query, ref ProfileItem item)
{
var extraItem = item.GetExtraItem();
extraItem.Flow = GetQueryValue(query, "flow");
item.SetExtraItem(extraItem);
var protocolExtra = item.GetProtocolExtra();
protocolExtra.Flow = GetQueryValue(query, "flow");
item.SetProtocolExtra(protocolExtra);
item.StreamSecurity = GetQueryValue(query, "security");
item.Sni = GetQueryValue(query, "sni");
item.Alpn = GetQueryDecoded(query, "alpn");

View file

@ -32,7 +32,7 @@ public class Hysteria2Fmt : BaseFmt
{
Ports = GetQueryDecoded(query, "mport")
};
item.SetExtraItem(extraItem);
item.SetProtocolExtra(extraItem);
return item;
}
@ -59,10 +59,10 @@ public class Hysteria2Fmt : BaseFmt
dicQuery.Add("obfs", "salamander");
dicQuery.Add("obfs-password", Utils.UrlEncode(item.Path));
}
var extra = item.GetExtraItem();
if (extra?.Ports?.IsNotEmpty() ?? false)
var protocolExtra = item.GetProtocolExtra();
if (protocolExtra?.Ports?.IsNotEmpty() ?? false)
{
dicQuery.Add("mport", Utils.UrlEncode(extra.Ports.Replace(':', '-')));
dicQuery.Add("mport", Utils.UrlEncode(protocolExtra.Ports.Replace(':', '-')));
}
if (!item.CertSha.IsNullOrEmpty())
{

View file

@ -24,15 +24,15 @@ public class VmessFmt : BaseFmt
return null;
}
var extraItem = item?.GetExtraItem();
var protocolExtra = item?.GetProtocolExtra();
var vmessQRCode = new VmessQRCode
{
v = item.ConfigVersion,
v = 2,
ps = item.Remarks.TrimEx(),
add = item.Address,
port = item.Port,
id = item.Id,
aid = int.TryParse(extraItem?.AlterId, out var result) ? result : 0,
aid = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0,
scy = item.Security,
net = item.Network,
type = item.HeaderType,
@ -73,12 +73,12 @@ public class VmessFmt : BaseFmt
item.Network = Global.DefaultNetwork;
item.HeaderType = Global.None;
item.ConfigVersion = vmessQRCode.v;
//item.ConfigVersion = vmessQRCode.v;
item.Remarks = Utils.ToString(vmessQRCode.ps);
item.Address = Utils.ToString(vmessQRCode.add);
item.Port = vmessQRCode.port;
item.Id = Utils.ToString(vmessQRCode.id);
item.SetExtraItem(new ProtocolExtraItem
item.SetProtocolExtra(new ProtocolExtraItem
{
AlterId = vmessQRCode.aid.ToString(),
});

View file

@ -128,7 +128,7 @@ public class ActionPrecheckManager
}
}
var extraItem = item.GetExtraItem();
var protocolExtra = item.GetProtocolExtra();
switch (item.ConfigType)
{
@ -146,7 +146,7 @@ public class ActionPrecheckManager
errors.Add(string.Format(ResUI.InvalidProperty, "Id"));
}
if (!Global.Flows.Contains(extraItem.Flow ?? string.Empty))
if (!Global.Flows.Contains(protocolExtra.Flow ?? string.Empty))
{
errors.Add(string.Format(ResUI.InvalidProperty, "Flow"));
}
@ -204,7 +204,7 @@ public class ActionPrecheckManager
{
var errors = new List<string>();
var hasCycle = await GroupProfileManager.HasCycle(item.IndexId, item.GetExtraItem());
var hasCycle = await GroupProfileManager.HasCycle(item.IndexId, item.GetProtocolExtra());
if (hasCycle)
{
errors.Add(string.Format(ResUI.GroupSelfReference, item.Remarks));

View file

@ -81,7 +81,9 @@ public sealed class AppManager
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
SQLiteHelper.Instance.CreateTable<DNSItem>();
SQLiteHelper.Instance.CreateTable<FullConfigTemplateItem>();
#pragma warning disable CS0618
SQLiteHelper.Instance.CreateTable<ProfileGroupItem>();
#pragma warning restore CS0618
return true;
}
@ -259,36 +261,54 @@ public sealed class AppManager
public async Task MigrateProfileExtra()
{
var list = await SQLiteHelper.Instance.TableAsync<ProfileItem>().ToListAsync();
foreach (var item in list)
#pragma warning disable CS0618
const int pageSize = 500;
int offset = 0;
while (true)
{
if (!item.JsonData.IsNullOrEmpty())
var sql = $"SELECT * FROM ProfileItem WHERE ConfigVersion < 3 LIMIT {pageSize} OFFSET {offset}";
var batch = await SQLiteHelper.Instance.QueryAsync<ProfileItem>(sql);
if (batch is null || batch.Count == 0)
{
return;
break;
}
ProtocolExtraItem extra = new()
foreach (var item in batch)
{
AlterId = item.AlterId.ToString(),
Flow = item.Flow.IsNotEmpty() ? item.Flow : null,
Ports = item.Ports.IsNotEmpty() ? item.Ports : null,
};
if (item.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
{
extra.GroupType = nameof(item.ConfigType);
ProfileGroupItemManager.Instance.TryGet(item.IndexId, out var groupItem);
if (groupItem != null && !groupItem.NotHasChild())
ProtocolExtraItem extra = new()
{
extra.ChildItems = groupItem.ChildItems;
extra.SubChildItems = groupItem.SubChildItems;
extra.Filter = groupItem.Filter;
extra.MultipleLoad = groupItem.MultipleLoad;
AlterId = item.AlterId.ToString(),
Flow = item.Flow.IsNotEmpty() ? item.Flow : null,
Ports = item.Ports.IsNotEmpty() ? item.Ports : null,
};
if (item.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
{
extra.GroupType = nameof(item.ConfigType);
ProfileGroupItemManager.Instance.TryGet(item.IndexId, out var groupItem);
if (groupItem != null && !groupItem.NotHasChild())
{
extra.ChildItems = groupItem.ChildItems;
extra.SubChildItems = groupItem.SubChildItems;
extra.Filter = groupItem.Filter;
extra.MultipleLoad = groupItem.MultipleLoad;
}
}
item.SetProtocolExtra(extra);
item.Password = item.Id;
item.ConfigVersion = 3;
await SQLiteHelper.Instance.UpdateAsync(item);
}
item.SetExtraItem(extra);
await SQLiteHelper.Instance.UpdateAsync(item);
offset += pageSize;
}
await ProfileGroupItemManager.Instance.ClearAll();
//await ProfileGroupItemManager.Instance.ClearAll();
#pragma warning restore CS0618
}
#endregion SqliteHelper

View file

@ -4,7 +4,7 @@ public class GroupProfileManager
{
public static async Task<bool> HasCycle(ProfileItem item)
{
return await HasCycle(item.IndexId, item.GetExtraItem());
return await HasCycle(item.IndexId, item.GetProtocolExtra());
}
public static async Task<bool> HasCycle(string? indexId, ProtocolExtraItem? extraInfo)
@ -55,7 +55,7 @@ public class GroupProfileManager
foreach (var child in childIds)
{
var childItem = await AppManager.Instance.GetProfileItem(child);
if (await HasCycle(child, childItem?.GetExtraItem(), visited, stack))
if (await HasCycle(child, childItem?.GetProtocolExtra(), visited, stack))
{
return true;
}
@ -71,16 +71,12 @@ public class GroupProfileManager
public static async Task<(List<ProfileItem> Items, ProtocolExtraItem? Extra)> GetChildProfileItems(ProfileItem profileItem)
{
var profileExtra = profileItem?.GetExtraItem();
if (profileExtra == null)
{
return ([], null);
}
var items = await GetChildProfileItems(profileExtra);
var subItems = await GetSubChildProfileItems(profileExtra);
var protocolExtra = profileItem?.GetProtocolExtra();
var items = await GetChildProfileItems(protocolExtra);
var subItems = await GetSubChildProfileItems(protocolExtra);
items.AddRange(subItems);
return (items, profileExtra);
return (items, protocolExtra);
}
public static async Task<List<ProfileItem>> GetChildProfileItems(ProtocolExtraItem? extra)

View file

@ -1,5 +1,6 @@
namespace ServiceLib.Manager;
[Obsolete("Use GroupProfileManager instead.")]
public class ProfileGroupItemManager
{
private static readonly Lazy<ProfileGroupItemManager> _instance = new(() => new());

View file

@ -1,6 +1,6 @@
namespace ServiceLib.Models;
// deprecated
[Obsolete("Use ProtocolExtraItem instead.")]
[Serializable]
public class ProfileGroupItem
{

View file

@ -7,9 +7,10 @@ public class ProfileItem : ReactiveObject
{
IndexId = string.Empty;
ConfigType = EConfigType.VMess;
ConfigVersion = 2;
ConfigVersion = 3;
Address = string.Empty;
Port = 0;
Password = string.Empty;
Id = string.Empty;
AlterId = 0;
Security = string.Empty;
@ -94,7 +95,7 @@ public class ProfileItem : ReactiveObject
return false;
}
if (!Global.Flows.Contains(GetExtraItem().Flow ?? string.Empty))
if (!Global.Flows.Contains(GetProtocolExtra().Flow ?? string.Empty))
{
return false;
}
@ -125,18 +126,18 @@ public class ProfileItem : ReactiveObject
return true;
}
public void SetExtraItem(ProtocolExtraItem extraItem)
public void SetProtocolExtra(ProtocolExtraItem extraItem)
{
JsonData = JsonUtils.Serialize(extraItem, false);
ProtoExtra = JsonUtils.Serialize(extraItem, false);
}
public ProtocolExtraItem GetExtraItem()
public ProtocolExtraItem GetProtocolExtra()
{
if (JsonData.IsNullOrEmpty())
if (ProtoExtra.IsNullOrEmpty())
{
return new ProtocolExtraItem();
}
return JsonUtils.Deserialize<ProtocolExtraItem>(JsonData);
return JsonUtils.Deserialize<ProtocolExtraItem>(ProtoExtra);
}
#endregion function
@ -148,8 +149,7 @@ public class ProfileItem : ReactiveObject
public int ConfigVersion { get; set; }
public string Address { get; set; }
public int Port { get; set; }
public string Id { get; set; }
public string Security { get; set; }
public string Password { get; set; }
public string Network { get; set; }
public string Remarks { get; set; }
public string HeaderType { get; set; }
@ -175,9 +175,15 @@ public class ProfileItem : ReactiveObject
public string CertSha { get; set; }
public string EchConfigList { get; set; }
public string EchForceQuery { get; set; }
public string JsonData { get; set; }
// deprecated
public string ProtoExtra { get; set; }
[Obsolete("Use ProtocolExtraItem.Ports instead.")]
public string Ports { get; set; }
[Obsolete("Use ProtocolExtraItem.AlterId instead.")]
public int AlterId { get; set; }
[Obsolete("Use ProtocolExtraItem.Flow instead.")]
public string Flow { get; set; }
[Obsolete("Use ProfileItem.Password instead.")]
public string Id { get; set; }
[Obsolete("Use ProtocolExtraItem.xxx instead.")]
public string Security { get; set; }
}

View file

@ -4,13 +4,26 @@ public class ProtocolExtraItem
{
// vmess
public string? AlterId { get; set; }
public string? VmessSecurity { get; set; }
// vless
public string? Flow { get; set; }
public string? VlessEncryption { get; set; }
//public string? VisionSeed { get; set; }
// shadowsocks
//public string? PluginArgs { get; set; }
public string? SsMethod { get; set; }
// socks and http
public string? Username { get; set; }
// wireguard
public string? WgPublicKey { get; set; }
public string? WgPresharedKey { get; set; }
public string? WgInterfaceAddress { get; set; }
public string? WgReserved { get; set; }
public int? WgMtu { get; set; }
// hysteria2
public int? UpMbps { get; set; }

View file

@ -6,7 +6,7 @@ public partial class CoreConfigSingboxService
{
try
{
var extraItem = node.GetExtraItem();
var protocolExtra = node.GetProtocolExtra();
outbound.server = node.Address;
outbound.server_port = node.Port;
outbound.type = Global.ProtocolTypes[node.ConfigType];
@ -16,7 +16,7 @@ public partial class CoreConfigSingboxService
case EConfigType.VMess:
{
outbound.uuid = node.Id;
outbound.alter_id = int.TryParse(extraItem?.AlterId, out var result) ? result : 0;
outbound.alter_id = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0;
if (Global.VmessSecurities.Contains(node.Security))
{
outbound.security = node.Security;
@ -113,13 +113,13 @@ public partial class CoreConfigSingboxService
outbound.packet_encoding = "xudp";
if (extraItem.Flow.IsNullOrEmpty())
if (protocolExtra.Flow.IsNullOrEmpty())
{
await GenOutboundMux(node, outbound);
}
else
{
outbound.flow = extraItem.Flow;
outbound.flow = protocolExtra.Flow;
}
await GenOutboundTransport(node, outbound);
@ -146,13 +146,13 @@ public partial class CoreConfigSingboxService
};
}
outbound.up_mbps = extraItem?.UpMbps is { } su and >= 0
outbound.up_mbps = protocolExtra?.UpMbps is { } su and >= 0
? su
: _config.HysteriaItem.UpMbps > 0 ? _config.HysteriaItem.UpMbps : null;
outbound.down_mbps = extraItem?.DownMbps is { } sd and >= 0
outbound.down_mbps = protocolExtra?.DownMbps is { } sd and >= 0
? sd
: _config.HysteriaItem.DownMbps > 0 ? _config.HysteriaItem.DownMbps : null;
var ports = extraItem?.Ports?.IsNullOrEmpty() == false ? extraItem.Ports : null;
var ports = protocolExtra?.Ports?.IsNullOrEmpty() == false ? protocolExtra.Ports : null;
if ((!ports.IsNullOrEmpty()) && (ports.Contains(':') || ports.Contains('-') || ports.Contains(',')))
{
outbound.server_port = null;
@ -165,7 +165,7 @@ public partial class CoreConfigSingboxService
return port.Contains(':') ? port : $"{port}:{port}";
})
.ToList();
outbound.hop_interval = extraItem?.HopInterval is { } hi and >= 5
outbound.hop_interval = protocolExtra?.HopInterval is { } hi and >= 5
? $"{hi}s"
: _config.HysteriaItem.HopInterval >= 5 ? $"{_config.HysteriaItem.HopInterval}s" : $"{Global.Hysteria2DefaultHopInt}s";
}

View file

@ -6,7 +6,7 @@ public partial class CoreConfigV2rayService
{
try
{
var extraItem = node.GetExtraItem();
var protocolExtra = node.GetProtocolExtra();
var muxEnabled = node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled;
switch (node.ConfigType)
{
@ -37,7 +37,7 @@ public partial class CoreConfigV2rayService
}
usersItem.id = node.Id;
usersItem.alterId = int.TryParse(extraItem?.AlterId, out var result) ? result : 0;
usersItem.alterId = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0;
usersItem.email = Global.UserEMail;
if (Global.VmessSecurities.Contains(node.Security))
{
@ -143,13 +143,13 @@ public partial class CoreConfigV2rayService
usersItem.email = Global.UserEMail;
usersItem.encryption = node.Security;
if (extraItem.Flow.IsNullOrEmpty())
if (protocolExtra.Flow.IsNullOrEmpty())
{
await GenOutboundMux(node, outbound, muxEnabled, muxEnabled);
}
else
{
usersItem.flow = extraItem.Flow;
usersItem.flow = protocolExtra.Flow;
await GenOutboundMux(node, outbound, false, muxEnabled);
}
outbound.settings.servers = null;
@ -510,15 +510,15 @@ public partial class CoreConfigV2rayService
break;
case "hysteria":
var extraItem = node.GetExtraItem();
var ports = extraItem?.Ports;
int? upMbps = extraItem?.UpMbps is { } su and >= 0
var protocolExtra = node.GetProtocolExtra();
var ports = protocolExtra?.Ports;
int? upMbps = protocolExtra?.UpMbps is { } su and >= 0
? su
: _config.HysteriaItem.UpMbps > 0 ? _config.HysteriaItem.UpMbps : null;
int? downMbps = extraItem?.DownMbps is { } sd and >= 0
int? downMbps = protocolExtra?.DownMbps is { } sd and >= 0
? sd
: _config.HysteriaItem.DownMbps > 0 ? _config.HysteriaItem.DownMbps : null;
var hopInterval = extraItem?.HopInterval is { } hi and >= 5
var hopInterval = protocolExtra?.HopInterval is { } hi and >= 5
? hi
: _config.HysteriaItem.HopInterval >= 5 ? _config.HysteriaItem.HopInterval : Global.Hysteria2DefaultHopInt;
HysteriaUdpHop4Ray? udpHop = null;

View file

@ -79,8 +79,8 @@ public class AddGroupServerViewModel : MyReactiveObject
public async Task Init()
{
var extra = SelectedSource.GetExtraItem();
PolicyGroupType = (extra?.MultipleLoad ?? EMultipleLoad.LeastPing) switch
var protocolExtra = SelectedSource.GetProtocolExtra();
PolicyGroupType = (protocolExtra?.MultipleLoad ?? EMultipleLoad.LeastPing) switch
{
EMultipleLoad.LeastPing => ResUI.TbLeastPing,
EMultipleLoad.Fallback => ResUI.TbFallback,
@ -93,10 +93,10 @@ public class AddGroupServerViewModel : MyReactiveObject
var subs = await AppManager.Instance.SubItems();
subs.Add(new SubItem());
SubItems.AddRange(subs);
SelectedSubItem = SubItems.FirstOrDefault(s => s.Id == extra?.SubChildItems);
Filter = extra?.Filter;
SelectedSubItem = SubItems.FirstOrDefault(s => s.Id == protocolExtra?.SubChildItems);
Filter = protocolExtra?.Filter;
var childIndexIds = Utils.String2List(extra?.ChildItems) ?? [];
var childIndexIds = Utils.String2List(protocolExtra?.ChildItems) ?? [];
foreach (var item in childIndexIds)
{
var child = await AppManager.Instance.GetProfileItem(item);
@ -202,10 +202,10 @@ public class AddGroupServerViewModel : MyReactiveObject
return;
}
var extra = SelectedSource.GetExtraItem();
extra.ChildItems =
var protocolExtra = SelectedSource.GetProtocolExtra();
protocolExtra.ChildItems =
Utils.List2String(ChildItemsObs.Where(s => !s.IndexId.IsNullOrEmpty()).Select(s => s.IndexId).ToList());
extra.MultipleLoad = PolicyGroupType switch
protocolExtra.MultipleLoad = PolicyGroupType switch
{
var s when s == ResUI.TbLeastPing => EMultipleLoad.LeastPing,
var s when s == ResUI.TbFallback => EMultipleLoad.Fallback,
@ -215,17 +215,17 @@ public class AddGroupServerViewModel : MyReactiveObject
_ => EMultipleLoad.LeastPing,
};
extra.SubChildItems = SelectedSubItem?.Id;
extra.Filter = Filter;
protocolExtra.SubChildItems = SelectedSubItem?.Id;
protocolExtra.Filter = Filter;
var hasCycle = await GroupProfileManager.HasCycle(SelectedSource.IndexId, extra);
var hasCycle = await GroupProfileManager.HasCycle(SelectedSource.IndexId, protocolExtra);
if (hasCycle)
{
NoticeManager.Instance.Enqueue(string.Format(ResUI.GroupSelfReference, remarks));
return;
}
SelectedSource.SetExtraItem(extra);
SelectedSource.SetProtocolExtra(protocolExtra);
if (await ConfigHandler.AddServerCommon(_config, SelectedSource) == 0)
{

View file

@ -82,13 +82,13 @@ public class AddServerViewModel : MyReactiveObject
Cert = SelectedSource?.Cert?.ToString() ?? string.Empty;
CertSha = SelectedSource?.CertSha?.ToString() ?? string.Empty;
var extraItem = SelectedSource?.GetExtraItem();
Ports = extraItem?.Ports ?? string.Empty;
AlterId = int.TryParse(extraItem?.AlterId, out var result) ? result : 0;
Flow = extraItem?.Flow ?? string.Empty;
UpMbps = extraItem?.UpMbps ?? 0;
DownMbps = extraItem?.DownMbps ?? 0;
HopInterval = extraItem?.HopInterval ?? Global.Hysteria2DefaultHopInt;
var protocolExtra = SelectedSource?.GetProtocolExtra();
Ports = protocolExtra?.Ports ?? string.Empty;
AlterId = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0;
Flow = protocolExtra?.Flow ?? string.Empty;
UpMbps = protocolExtra?.UpMbps ?? 0;
DownMbps = protocolExtra?.DownMbps ?? 0;
HopInterval = protocolExtra?.HopInterval ?? Global.Hysteria2DefaultHopInt;
}
private async Task SaveServerAsync()
@ -135,14 +135,14 @@ public class AddServerViewModel : MyReactiveObject
SelectedSource.CoreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType);
SelectedSource.Cert = Cert.IsNullOrEmpty() ? string.Empty : Cert;
SelectedSource.CertSha = CertSha.IsNullOrEmpty() ? string.Empty : CertSha;
var extraItem = SelectedSource.GetExtraItem();
extraItem.Ports = Ports;
extraItem.AlterId = AlterId > 0 ? AlterId.ToString() : string.Empty;
extraItem.Flow = Flow;
extraItem.UpMbps = UpMbps;
extraItem.DownMbps = DownMbps;
extraItem.HopInterval = HopInterval >= 5 ? HopInterval : Global.Hysteria2DefaultHopInt;
SelectedSource.SetExtraItem(extraItem);
var protocolExtra = SelectedSource.GetProtocolExtra();
protocolExtra.Ports = Ports;
protocolExtra.AlterId = AlterId > 0 ? AlterId.ToString() : string.Empty;
protocolExtra.Flow = Flow;
protocolExtra.UpMbps = UpMbps;
protocolExtra.DownMbps = DownMbps;
protocolExtra.HopInterval = HopInterval >= 5 ? HopInterval : Global.Hysteria2DefaultHopInt;
SelectedSource.SetProtocolExtra(protocolExtra);
if (await ConfigHandler.AddServer(_config, SelectedSource) == 0)
{