The first letter of the guiconfig attribute must be capitalized.

pull/5891/head
2dust 2024-10-23 17:00:33 +08:00
parent 2d143687b8
commit 3c550c094a
75 changed files with 1355 additions and 1451 deletions

View File

@ -2,20 +2,20 @@
{ {
public enum EServerColName public enum EServerColName
{ {
def = 0, Def = 0,
configType, ConfigType,
remarks, Remarks,
address, Address,
port, Port,
network, Network,
streamSecurity, StreamSecurity,
subRemarks, SubRemarks,
delayVal, DelayVal,
speedVal, SpeedVal,
todayDown, TodayDown,
todayUp, TodayUp,
totalDown, TotalDown,
totalUp TotalUp
} }
} }

View File

@ -104,12 +104,12 @@
public async Task<List<SubItem>> SubItems() public async Task<List<SubItem>> SubItems()
{ {
return await SQLiteHelper.Instance.TableAsync<SubItem>().OrderBy(t => t.sort).ToListAsync(); return await SQLiteHelper.Instance.TableAsync<SubItem>().OrderBy(t => t.Sort).ToListAsync();
} }
public async Task<SubItem> GetSubItem(string subid) public async Task<SubItem> GetSubItem(string subid)
{ {
return await SQLiteHelper.Instance.TableAsync<SubItem>().FirstOrDefaultAsync(t => t.id == subid); return await SQLiteHelper.Instance.TableAsync<SubItem>().FirstOrDefaultAsync(t => t.Id == subid);
} }
public async Task<List<ProfileItem>> ProfileItems(string subid) public async Task<List<ProfileItem>> ProfileItems(string subid)
@ -120,7 +120,7 @@
} }
else else
{ {
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.subid == subid).ToListAsync(); return await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.Subid == subid).ToListAsync();
} }
} }
@ -129,13 +129,13 @@
if (Utils.IsNullOrEmpty(subid)) if (Utils.IsNullOrEmpty(subid))
{ {
return (await SQLiteHelper.Instance.TableAsync<ProfileItem>().ToListAsync()) return (await SQLiteHelper.Instance.TableAsync<ProfileItem>().ToListAsync())
.Select(t => t.indexId) .Select(t => t.IndexId)
.ToList(); .ToList();
} }
else else
{ {
return (await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.subid == subid).ToListAsync()) return (await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.Subid == subid).ToListAsync())
.Select(t => t.indexId) .Select(t => t.IndexId)
.ToList(); .ToList();
} }
} }
@ -172,32 +172,32 @@
var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? []; var lstServerStat = (_config.GuiItem.EnableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
var lstProfileExs = ProfileExHandler.Instance.ProfileExs; var lstProfileExs = ProfileExHandler.Instance.ProfileExs;
lstModel = (from t in lstModel lstModel = (from t in lstModel
join t2 in lstServerStat on t.indexId equals t2.indexId into t2b join t2 in lstServerStat on t.IndexId equals t2.IndexId into t2b
from t22 in t2b.DefaultIfEmpty() from t22 in t2b.DefaultIfEmpty()
join t3 in lstProfileExs on t.indexId equals t3.indexId into t3b join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
from t33 in t3b.DefaultIfEmpty() from t33 in t3b.DefaultIfEmpty()
select new ProfileItemModel select new ProfileItemModel
{ {
indexId = t.indexId, IndexId = t.IndexId,
configType = t.configType, ConfigType = t.ConfigType,
remarks = t.remarks, Remarks = t.Remarks,
address = t.address, Address = t.Address,
port = t.port, Port = t.Port,
security = t.security, Security = t.Security,
network = t.network, Network = t.Network,
streamSecurity = t.streamSecurity, StreamSecurity = t.StreamSecurity,
subid = t.subid, Subid = t.Subid,
subRemarks = t.subRemarks, SubRemarks = t.SubRemarks,
isActive = t.indexId == _config.IndexId, IsActive = t.IndexId == _config.IndexId,
sort = t33 == null ? 0 : t33.sort, Sort = t33 == null ? 0 : t33.Sort,
delay = t33 == null ? 0 : t33.delay, Delay = t33 == null ? 0 : t33.Delay,
delayVal = t33?.delay != 0 ? $"{t33?.delay} {Global.DelayUnit}" : string.Empty, DelayVal = t33?.Delay != 0 ? $"{t33?.Delay} {Global.DelayUnit}" : string.Empty,
speedVal = t33?.speed != 0 ? $"{t33?.speed} {Global.SpeedUnit}" : string.Empty, SpeedVal = t33?.Speed != 0 ? $"{t33?.Speed} {Global.SpeedUnit}" : string.Empty,
todayDown = t22 == null ? "" : Utils.HumanFy(t22.todayDown), TodayDown = t22 == null ? "" : Utils.HumanFy(t22.TodayDown),
todayUp = t22 == null ? "" : Utils.HumanFy(t22.todayUp), TodayUp = t22 == null ? "" : Utils.HumanFy(t22.TodayUp),
totalDown = t22 == null ? "" : Utils.HumanFy(t22.totalDown), TotalDown = t22 == null ? "" : Utils.HumanFy(t22.TotalDown),
totalUp = t22 == null ? "" : Utils.HumanFy(t22.totalUp) TotalUp = t22 == null ? "" : Utils.HumanFy(t22.TotalUp)
}).OrderBy(t => t.sort).ToList(); }).OrderBy(t => t.Sort).ToList();
return lstModel; return lstModel;
} }
@ -208,7 +208,7 @@
{ {
return null; return null;
} }
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.indexId == indexId); return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.IndexId == indexId);
} }
public async Task<ProfileItem?> GetProfileItemViaRemarks(string? remarks) public async Task<ProfileItem?> GetProfileItemViaRemarks(string? remarks)
@ -217,17 +217,17 @@
{ {
return null; return null;
} }
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.remarks == remarks); return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.Remarks == remarks);
} }
public async Task<List<RoutingItem>> RoutingItems() public async Task<List<RoutingItem>> RoutingItems()
{ {
return await SQLiteHelper.Instance.TableAsync<RoutingItem>().Where(it => it.locked == false).OrderBy(t => t.sort).ToListAsync(); return await SQLiteHelper.Instance.TableAsync<RoutingItem>().Where(it => it.Locked == false).OrderBy(t => t.Sort).ToListAsync();
} }
public async Task<RoutingItem> GetRoutingItem(string id) public async Task<RoutingItem> GetRoutingItem(string id)
{ {
return await SQLiteHelper.Instance.TableAsync<RoutingItem>().FirstOrDefaultAsync(it => it.locked == false && it.id == id); return await SQLiteHelper.Instance.TableAsync<RoutingItem>().FirstOrDefaultAsync(it => it.Locked == false && it.Id == id);
} }
public async Task<List<DNSItem>> DNSItems() public async Task<List<DNSItem>> DNSItems()
@ -237,7 +237,7 @@
public async Task<DNSItem> GetDNSItem(ECoreType eCoreType) public async Task<DNSItem> GetDNSItem(ECoreType eCoreType)
{ {
return await SQLiteHelper.Instance.TableAsync<DNSItem>().FirstOrDefaultAsync(it => it.coreType == eCoreType); return await SQLiteHelper.Instance.TableAsync<DNSItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
} }
#endregion SqliteHelper #endregion SqliteHelper
@ -263,9 +263,9 @@
public ECoreType GetCoreType(ProfileItem profileItem, EConfigType eConfigType) public ECoreType GetCoreType(ProfileItem profileItem, EConfigType eConfigType)
{ {
if (profileItem?.coreType != null) if (profileItem?.CoreType != null)
{ {
return (ECoreType)profileItem.coreType; return (ECoreType)profileItem.CoreType;
} }
if (_config.CoreTypeItem == null) if (_config.CoreTypeItem == null)

File diff suppressed because it is too large Load Diff

View File

@ -10,13 +10,13 @@
var config = AppHandler.Instance.Config; var config = AppHandler.Instance.Config;
var result = new RetResult(); var result = new RetResult();
if (node.configType == EConfigType.Custom) if (node.ConfigType == EConfigType.Custom)
{ {
if (node.coreType is ECoreType.mihomo) if (node.CoreType is ECoreType.mihomo)
{ {
result = await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName); result = await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName);
} }
if (node.coreType is ECoreType.sing_box) if (node.CoreType is ECoreType.sing_box)
{ {
result = await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName); result = await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName);
} }
@ -25,7 +25,7 @@
result = await GenerateClientCustomConfig(node, fileName); result = await GenerateClientCustomConfig(node, fileName);
} }
} }
else if (AppHandler.Instance.GetCoreType(node, node.configType) == ECoreType.sing_box) else if (AppHandler.Instance.GetCoreType(node, node.ConfigType) == ECoreType.sing_box)
{ {
result = await new CoreConfigSingboxService(config).GenerateClientConfigContent(node); result = await new CoreConfigSingboxService(config).GenerateClientConfigContent(node);
} }
@ -62,7 +62,7 @@
File.Delete(fileName); File.Delete(fileName);
} }
string addressFileName = node.address; string addressFileName = node.Address;
if (!File.Exists(addressFileName)) if (!File.Exists(addressFileName))
{ {
addressFileName = Utils.GetConfigPath(addressFileName); addressFileName = Utils.GetConfigPath(addressFileName);

View File

@ -181,11 +181,11 @@ namespace ServiceLib.Handler
//{ //{
// coreType = LazyConfig.Instance.GetCoreType(node, node.configType); // coreType = LazyConfig.Instance.GetCoreType(node, node.configType);
//} //}
var coreType = AppHandler.Instance.GetCoreType(node, node.configType); var coreType = AppHandler.Instance.GetCoreType(node, node.ConfigType);
_config.RunningCoreType = coreType; _config.RunningCoreType = coreType;
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType); var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(coreType);
var displayLog = node.configType != EConfigType.Custom || node.displayLog; var displayLog = node.ConfigType != EConfigType.Custom || node.DisplayLog;
var proc = RunProcess(node, coreInfo, "", displayLog); var proc = RunProcess(node, coreInfo, "", displayLog);
if (proc is null) if (proc is null)
{ {
@ -198,26 +198,26 @@ namespace ServiceLib.Handler
{ {
ProfileItem? itemSocks = null; ProfileItem? itemSocks = null;
var preCoreType = ECoreType.sing_box; var preCoreType = ECoreType.sing_box;
if (node.configType != EConfigType.Custom && coreType != ECoreType.sing_box && _config.TunModeItem.EnableTun) if (node.ConfigType != EConfigType.Custom && coreType != ECoreType.sing_box && _config.TunModeItem.EnableTun)
{ {
itemSocks = new ProfileItem() itemSocks = new ProfileItem()
{ {
coreType = preCoreType, CoreType = preCoreType,
configType = EConfigType.SOCKS, ConfigType = EConfigType.SOCKS,
address = Global.Loopback, Address = Global.Loopback,
sni = node.address, //Tun2SocksAddress Sni = node.Address, //Tun2SocksAddress
port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks) Port = AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)
}; };
} }
else if ((node.configType == EConfigType.Custom && node.preSocksPort > 0)) else if ((node.ConfigType == EConfigType.Custom && node.PreSocksPort > 0))
{ {
preCoreType = _config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray; preCoreType = _config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray;
itemSocks = new ProfileItem() itemSocks = new ProfileItem()
{ {
coreType = preCoreType, CoreType = preCoreType,
configType = EConfigType.SOCKS, ConfigType = EConfigType.SOCKS,
address = Global.Loopback, Address = Global.Loopback,
port = node.preSocksPort.Value, Port = node.PreSocksPort.Value,
}; };
_config.RunningCoreType = preCoreType; _config.RunningCoreType = preCoreType;
} }

View File

@ -16,14 +16,14 @@ namespace ServiceLib.Handler.Fmt
protected static int GetStdTransport(ProfileItem item, string? securityDef, ref Dictionary<string, string> dicQuery) protected static int GetStdTransport(ProfileItem item, string? securityDef, ref Dictionary<string, string> dicQuery)
{ {
if (Utils.IsNotEmpty(item.flow)) if (Utils.IsNotEmpty(item.Flow))
{ {
dicQuery.Add("flow", item.flow); dicQuery.Add("flow", item.Flow);
} }
if (Utils.IsNotEmpty(item.streamSecurity)) if (Utils.IsNotEmpty(item.StreamSecurity))
{ {
dicQuery.Add("security", item.streamSecurity); dicQuery.Add("security", item.StreamSecurity);
} }
else else
{ {
@ -32,95 +32,95 @@ namespace ServiceLib.Handler.Fmt
dicQuery.Add("security", securityDef); dicQuery.Add("security", securityDef);
} }
} }
if (Utils.IsNotEmpty(item.sni)) if (Utils.IsNotEmpty(item.Sni))
{ {
dicQuery.Add("sni", item.sni); dicQuery.Add("sni", item.Sni);
} }
if (Utils.IsNotEmpty(item.alpn)) if (Utils.IsNotEmpty(item.Alpn))
{ {
dicQuery.Add("alpn", Utils.UrlEncode(item.alpn)); dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn));
} }
if (Utils.IsNotEmpty(item.fingerprint)) if (Utils.IsNotEmpty(item.Fingerprint))
{ {
dicQuery.Add("fp", Utils.UrlEncode(item.fingerprint)); dicQuery.Add("fp", Utils.UrlEncode(item.Fingerprint));
} }
if (Utils.IsNotEmpty(item.publicKey)) if (Utils.IsNotEmpty(item.PublicKey))
{ {
dicQuery.Add("pbk", Utils.UrlEncode(item.publicKey)); dicQuery.Add("pbk", Utils.UrlEncode(item.PublicKey));
} }
if (Utils.IsNotEmpty(item.shortId)) if (Utils.IsNotEmpty(item.ShortId))
{ {
dicQuery.Add("sid", Utils.UrlEncode(item.shortId)); dicQuery.Add("sid", Utils.UrlEncode(item.ShortId));
} }
if (Utils.IsNotEmpty(item.spiderX)) if (Utils.IsNotEmpty(item.SpiderX))
{ {
dicQuery.Add("spx", Utils.UrlEncode(item.spiderX)); dicQuery.Add("spx", Utils.UrlEncode(item.SpiderX));
} }
if (item.allowInsecure.Equals("true")) if (item.AllowInsecure.Equals("true"))
{ {
dicQuery.Add("allowInsecure", "1"); dicQuery.Add("allowInsecure", "1");
} }
dicQuery.Add("type", Utils.IsNotEmpty(item.network) ? item.network : nameof(ETransport.tcp)); dicQuery.Add("type", Utils.IsNotEmpty(item.Network) ? item.Network : nameof(ETransport.tcp));
switch (item.network) switch (item.Network)
{ {
case nameof(ETransport.tcp): case nameof(ETransport.tcp):
dicQuery.Add("headerType", Utils.IsNotEmpty(item.headerType) ? item.headerType : Global.None); dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None);
if (Utils.IsNotEmpty(item.requestHost)) if (Utils.IsNotEmpty(item.RequestHost))
{ {
dicQuery.Add("host", Utils.UrlEncode(item.requestHost)); dicQuery.Add("host", Utils.UrlEncode(item.RequestHost));
} }
break; break;
case nameof(ETransport.kcp): case nameof(ETransport.kcp):
dicQuery.Add("headerType", Utils.IsNotEmpty(item.headerType) ? item.headerType : Global.None); dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None);
if (Utils.IsNotEmpty(item.path)) if (Utils.IsNotEmpty(item.Path))
{ {
dicQuery.Add("seed", Utils.UrlEncode(item.path)); dicQuery.Add("seed", Utils.UrlEncode(item.Path));
} }
break; break;
case nameof(ETransport.ws): case nameof(ETransport.ws):
case nameof(ETransport.httpupgrade): case nameof(ETransport.httpupgrade):
case nameof(ETransport.splithttp): case nameof(ETransport.splithttp):
if (Utils.IsNotEmpty(item.requestHost)) if (Utils.IsNotEmpty(item.RequestHost))
{ {
dicQuery.Add("host", Utils.UrlEncode(item.requestHost)); dicQuery.Add("host", Utils.UrlEncode(item.RequestHost));
} }
if (Utils.IsNotEmpty(item.path)) if (Utils.IsNotEmpty(item.Path))
{ {
dicQuery.Add("path", Utils.UrlEncode(item.path)); dicQuery.Add("path", Utils.UrlEncode(item.Path));
} }
break; break;
case nameof(ETransport.http): case nameof(ETransport.http):
case nameof(ETransport.h2): case nameof(ETransport.h2):
dicQuery["type"] = nameof(ETransport.http); dicQuery["type"] = nameof(ETransport.http);
if (Utils.IsNotEmpty(item.requestHost)) if (Utils.IsNotEmpty(item.RequestHost))
{ {
dicQuery.Add("host", Utils.UrlEncode(item.requestHost)); dicQuery.Add("host", Utils.UrlEncode(item.RequestHost));
} }
if (Utils.IsNotEmpty(item.path)) if (Utils.IsNotEmpty(item.Path))
{ {
dicQuery.Add("path", Utils.UrlEncode(item.path)); dicQuery.Add("path", Utils.UrlEncode(item.Path));
} }
break; break;
case nameof(ETransport.quic): case nameof(ETransport.quic):
dicQuery.Add("headerType", Utils.IsNotEmpty(item.headerType) ? item.headerType : Global.None); dicQuery.Add("headerType", Utils.IsNotEmpty(item.HeaderType) ? item.HeaderType : Global.None);
dicQuery.Add("quicSecurity", Utils.UrlEncode(item.requestHost)); dicQuery.Add("quicSecurity", Utils.UrlEncode(item.RequestHost));
dicQuery.Add("key", Utils.UrlEncode(item.path)); dicQuery.Add("key", Utils.UrlEncode(item.Path));
break; break;
case nameof(ETransport.grpc): case nameof(ETransport.grpc):
if (Utils.IsNotEmpty(item.path)) if (Utils.IsNotEmpty(item.Path))
{ {
dicQuery.Add("authority", Utils.UrlEncode(item.requestHost)); dicQuery.Add("authority", Utils.UrlEncode(item.RequestHost));
dicQuery.Add("serviceName", Utils.UrlEncode(item.path)); dicQuery.Add("serviceName", Utils.UrlEncode(item.Path));
if (item.headerType is Global.GrpcGunMode or Global.GrpcMultiMode) if (item.HeaderType is Global.GrpcGunMode or Global.GrpcMultiMode)
{ {
dicQuery.Add("mode", Utils.UrlEncode(item.headerType)); dicQuery.Add("mode", Utils.UrlEncode(item.HeaderType));
} }
} }
break; break;
@ -130,54 +130,54 @@ namespace ServiceLib.Handler.Fmt
protected static int ResolveStdTransport(NameValueCollection query, ref ProfileItem item) protected static int ResolveStdTransport(NameValueCollection query, ref ProfileItem item)
{ {
item.flow = query["flow"] ?? ""; item.Flow = query["flow"] ?? "";
item.streamSecurity = query["security"] ?? ""; item.StreamSecurity = query["security"] ?? "";
item.sni = query["sni"] ?? ""; item.Sni = query["sni"] ?? "";
item.alpn = Utils.UrlDecode(query["alpn"] ?? ""); item.Alpn = Utils.UrlDecode(query["alpn"] ?? "");
item.fingerprint = Utils.UrlDecode(query["fp"] ?? ""); item.Fingerprint = Utils.UrlDecode(query["fp"] ?? "");
item.publicKey = Utils.UrlDecode(query["pbk"] ?? ""); item.PublicKey = Utils.UrlDecode(query["pbk"] ?? "");
item.shortId = Utils.UrlDecode(query["sid"] ?? ""); item.ShortId = Utils.UrlDecode(query["sid"] ?? "");
item.spiderX = Utils.UrlDecode(query["spx"] ?? ""); item.SpiderX = Utils.UrlDecode(query["spx"] ?? "");
item.allowInsecure = (query["allowInsecure"] ?? "") == "1" ? "true" : ""; item.AllowInsecure = (query["allowInsecure"] ?? "") == "1" ? "true" : "";
item.network = query["type"] ?? nameof(ETransport.tcp); item.Network = query["type"] ?? nameof(ETransport.tcp);
switch (item.network) switch (item.Network)
{ {
case nameof(ETransport.tcp): case nameof(ETransport.tcp):
item.headerType = query["headerType"] ?? Global.None; item.HeaderType = query["headerType"] ?? Global.None;
item.requestHost = Utils.UrlDecode(query["host"] ?? ""); item.RequestHost = Utils.UrlDecode(query["host"] ?? "");
break; break;
case nameof(ETransport.kcp): case nameof(ETransport.kcp):
item.headerType = query["headerType"] ?? Global.None; item.HeaderType = query["headerType"] ?? Global.None;
item.path = Utils.UrlDecode(query["seed"] ?? ""); item.Path = Utils.UrlDecode(query["seed"] ?? "");
break; break;
case nameof(ETransport.ws): case nameof(ETransport.ws):
case nameof(ETransport.httpupgrade): case nameof(ETransport.httpupgrade):
case nameof(ETransport.splithttp): case nameof(ETransport.splithttp):
item.requestHost = Utils.UrlDecode(query["host"] ?? ""); item.RequestHost = Utils.UrlDecode(query["host"] ?? "");
item.path = Utils.UrlDecode(query["path"] ?? "/"); item.Path = Utils.UrlDecode(query["path"] ?? "/");
break; break;
case nameof(ETransport.http): case nameof(ETransport.http):
case nameof(ETransport.h2): case nameof(ETransport.h2):
item.network = nameof(ETransport.h2); item.Network = nameof(ETransport.h2);
item.requestHost = Utils.UrlDecode(query["host"] ?? ""); item.RequestHost = Utils.UrlDecode(query["host"] ?? "");
item.path = Utils.UrlDecode(query["path"] ?? "/"); item.Path = Utils.UrlDecode(query["path"] ?? "/");
break; break;
case nameof(ETransport.quic): case nameof(ETransport.quic):
item.headerType = query["headerType"] ?? Global.None; item.HeaderType = query["headerType"] ?? Global.None;
item.requestHost = query["quicSecurity"] ?? Global.None; item.RequestHost = query["quicSecurity"] ?? Global.None;
item.path = Utils.UrlDecode(query["key"] ?? ""); item.Path = Utils.UrlDecode(query["key"] ?? "");
break; break;
case nameof(ETransport.grpc): case nameof(ETransport.grpc):
item.requestHost = Utils.UrlDecode(query["authority"] ?? ""); item.RequestHost = Utils.UrlDecode(query["authority"] ?? "");
item.path = Utils.UrlDecode(query["serviceName"] ?? ""); item.Path = Utils.UrlDecode(query["serviceName"] ?? "");
item.headerType = Utils.UrlDecode(query["mode"] ?? Global.GrpcGunMode); item.HeaderType = Utils.UrlDecode(query["mode"] ?? Global.GrpcGunMode);
break; break;
default: default:

View File

@ -10,9 +10,9 @@
var profileItem = new ProfileItem var profileItem = new ProfileItem
{ {
coreType = ECoreType.mihomo, CoreType = ECoreType.mihomo,
address = fileName, Address = fileName,
remarks = subRemarks ?? "clash_custom" Remarks = subRemarks ?? "clash_custom"
}; };
return profileItem; return profileItem;
} }

View File

@ -6,7 +6,7 @@
{ {
try try
{ {
var url = item.configType switch var url = item.ConfigType switch
{ {
EConfigType.VMess => VmessFmt.ToUri(item), EConfigType.VMess => VmessFmt.ToUri(item),
EConfigType.Shadowsocks => ShadowsocksFmt.ToUri(item), EConfigType.Shadowsocks => ShadowsocksFmt.ToUri(item),

View File

@ -7,20 +7,20 @@
msg = ResUI.ConfigurationFormatIncorrect; msg = ResUI.ConfigurationFormatIncorrect;
ProfileItem item = new() ProfileItem item = new()
{ {
configType = EConfigType.Hysteria2 ConfigType = EConfigType.Hysteria2
}; };
Uri url = new(str); Uri url = new(str);
item.address = url.IdnHost; item.Address = url.IdnHost;
item.port = url.Port; item.Port = url.Port;
item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped); item.Remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
item.id = Utils.UrlDecode(url.UserInfo); item.Id = Utils.UrlDecode(url.UserInfo);
var query = Utils.ParseQueryString(url.Query); var query = Utils.ParseQueryString(url.Query);
ResolveStdTransport(query, ref item); ResolveStdTransport(query, ref item);
item.path = Utils.UrlDecode(query["obfs-password"] ?? ""); item.Path = Utils.UrlDecode(query["obfs-password"] ?? "");
item.allowInsecure = (query["insecure"] ?? "") == "1" ? "true" : "false"; item.AllowInsecure = (query["insecure"] ?? "") == "1" ? "true" : "false";
return item; return item;
} }
@ -31,27 +31,27 @@
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;
if (Utils.IsNotEmpty(item.remarks)) if (Utils.IsNotEmpty(item.Remarks))
{ {
remark = "#" + Utils.UrlEncode(item.remarks); remark = "#" + Utils.UrlEncode(item.Remarks);
} }
var dicQuery = new Dictionary<string, string>(); var dicQuery = new Dictionary<string, string>();
if (Utils.IsNotEmpty(item.sni)) if (Utils.IsNotEmpty(item.Sni))
{ {
dicQuery.Add("sni", item.sni); dicQuery.Add("sni", item.Sni);
} }
if (Utils.IsNotEmpty(item.alpn)) if (Utils.IsNotEmpty(item.Alpn))
{ {
dicQuery.Add("alpn", Utils.UrlEncode(item.alpn)); dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn));
} }
if (Utils.IsNotEmpty(item.path)) if (Utils.IsNotEmpty(item.Path))
{ {
dicQuery.Add("obfs", "salamander"); dicQuery.Add("obfs", "salamander");
dicQuery.Add("obfs-password", Utils.UrlEncode(item.path)); dicQuery.Add("obfs-password", Utils.UrlEncode(item.Path));
} }
dicQuery.Add("insecure", item.allowInsecure.ToLower() == "true" ? "1" : "0"); dicQuery.Add("insecure", item.AllowInsecure.ToLower() == "true" ? "1" : "0");
return ToUri(EConfigType.Hysteria2, item.address, item.port, item.id, dicQuery, remark); return ToUri(EConfigType.Hysteria2, item.Address, item.Port, item.Id, dicQuery, remark);
} }
public static ProfileItem? ResolveFull(string strData, string? subRemarks) public static ProfileItem? ResolveFull(string strData, string? subRemarks)
@ -62,9 +62,9 @@
var profileItem = new ProfileItem var profileItem = new ProfileItem
{ {
coreType = ECoreType.hysteria, CoreType = ECoreType.hysteria,
address = fileName, Address = fileName,
remarks = subRemarks ?? "hysteria_custom" Remarks = subRemarks ?? "hysteria_custom"
}; };
return profileItem; return profileItem;
} }
@ -80,9 +80,9 @@
var profileItem = new ProfileItem var profileItem = new ProfileItem
{ {
coreType = ECoreType.hysteria2, CoreType = ECoreType.hysteria2,
address = fileName, Address = fileName,
remarks = subRemarks ?? "hysteria2_custom" Remarks = subRemarks ?? "hysteria2_custom"
}; };
return profileItem; return profileItem;
} }

View File

@ -10,9 +10,9 @@
var profileItem = new ProfileItem var profileItem = new ProfileItem
{ {
coreType = ECoreType.naiveproxy, CoreType = ECoreType.naiveproxy,
address = fileName, Address = fileName,
remarks = subRemarks ?? "naiveproxy_custom" Remarks = subRemarks ?? "naiveproxy_custom"
}; };
return profileItem; return profileItem;
} }

View File

@ -14,12 +14,12 @@ namespace ServiceLib.Handler.Fmt
{ {
return null; return null;
} }
if (item.address.Length == 0 || item.port == 0 || item.security.Length == 0 || item.id.Length == 0) if (item.Address.Length == 0 || item.Port == 0 || item.Security.Length == 0 || item.Id.Length == 0)
{ {
return null; return null;
} }
item.configType = EConfigType.Shadowsocks; item.ConfigType = EConfigType.Shadowsocks;
return item; return item;
} }
@ -30,9 +30,9 @@ namespace ServiceLib.Handler.Fmt
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;
if (Utils.IsNotEmpty(item.remarks)) if (Utils.IsNotEmpty(item.Remarks))
{ {
remark = "#" + Utils.UrlEncode(item.remarks); remark = "#" + Utils.UrlEncode(item.Remarks);
} }
//url = string.Format("{0}:{1}@{2}:{3}", //url = string.Format("{0}:{1}@{2}:{3}",
// item.security, // item.security,
@ -41,8 +41,8 @@ namespace ServiceLib.Handler.Fmt
// item.port); // item.port);
//url = Utile.Base64Encode(url); //url = Utile.Base64Encode(url);
//new Sip002 //new Sip002
var pw = Utils.Base64Encode($"{item.security}:{item.id}"); var pw = Utils.Base64Encode($"{item.Security}:{item.Id}");
return ToUri(EConfigType.Shadowsocks, item.address, item.port, pw, null, remark); return ToUri(EConfigType.Shadowsocks, item.Address, item.Port, pw, null, remark);
} }
private static readonly Regex UrlFinder = new(@"ss://(?<base64>[A-Za-z0-9+-/=_]+)(?:#(?<tag>\S+))?", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex UrlFinder = new(@"ss://(?<base64>[A-Za-z0-9+-/=_]+)(?:#(?<tag>\S+))?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
@ -59,7 +59,7 @@ namespace ServiceLib.Handler.Fmt
var tag = match.Groups["tag"].Value; var tag = match.Groups["tag"].Value;
if (Utils.IsNotEmpty(tag)) if (Utils.IsNotEmpty(tag))
{ {
item.remarks = Utils.UrlDecode(tag); item.Remarks = Utils.UrlDecode(tag);
} }
Match details; Match details;
try try
@ -72,10 +72,10 @@ namespace ServiceLib.Handler.Fmt
} }
if (!details.Success) if (!details.Success)
return null; return null;
item.security = details.Groups["method"].Value; item.Security = details.Groups["method"].Value;
item.id = details.Groups["password"].Value; item.Id = details.Groups["password"].Value;
item.address = details.Groups["hostname"].Value; item.Address = details.Groups["hostname"].Value;
item.port = Utils.ToInt(details.Groups["port"].Value); item.Port = Utils.ToInt(details.Groups["port"].Value);
return item; return item;
} }
@ -92,9 +92,9 @@ namespace ServiceLib.Handler.Fmt
} }
ProfileItem item = new() ProfileItem item = new()
{ {
remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped), Remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
address = parsedUrl.IdnHost, Address = parsedUrl.IdnHost,
port = parsedUrl.Port, Port = parsedUrl.Port,
}; };
var rawUserInfo = Utils.UrlDecode(parsedUrl.UserInfo); var rawUserInfo = Utils.UrlDecode(parsedUrl.UserInfo);
//2022-blake3 //2022-blake3
@ -105,8 +105,8 @@ namespace ServiceLib.Handler.Fmt
{ {
return null; return null;
} }
item.security = userInfoParts[0]; item.Security = userInfoParts[0];
item.id = Utils.UrlDecode(userInfoParts[1]); item.Id = Utils.UrlDecode(userInfoParts[1]);
} }
else else
{ {
@ -117,8 +117,8 @@ namespace ServiceLib.Handler.Fmt
{ {
return null; return null;
} }
item.security = userInfoParts[0]; item.Security = userInfoParts[0];
item.id = userInfoParts[1]; item.Id = userInfoParts[1];
} }
var queryParameters = Utils.ParseQueryString(parsedUrl.Query); var queryParameters = Utils.ParseQueryString(parsedUrl.Query);
@ -129,9 +129,9 @@ namespace ServiceLib.Handler.Fmt
if (queryParameters["plugin"].Contains("obfs=http") && Utils.IsNotEmpty(obfsHost)) if (queryParameters["plugin"].Contains("obfs=http") && Utils.IsNotEmpty(obfsHost))
{ {
obfsHost = obfsHost?.Replace("obfs-host=", ""); obfsHost = obfsHost?.Replace("obfs-host=", "");
item.network = Global.DefaultNetwork; item.Network = Global.DefaultNetwork;
item.headerType = Global.TcpHeaderHttp; item.HeaderType = Global.TcpHeaderHttp;
item.requestHost = obfsHost ?? ""; item.RequestHost = obfsHost ?? "";
} }
else else
{ {
@ -162,11 +162,11 @@ namespace ServiceLib.Handler.Fmt
{ {
var ssItem = new ProfileItem() var ssItem = new ProfileItem()
{ {
remarks = it.remarks, Remarks = it.remarks,
security = it.method, Security = it.method,
id = it.password, Id = it.password,
address = it.server, Address = it.server,
port = Utils.ToInt(it.server_port) Port = Utils.ToInt(it.server_port)
}; };
lst.Add(ssItem); lst.Add(ssItem);
} }

View File

@ -20,9 +20,9 @@
var profileIt = new ProfileItem var profileIt = new ProfileItem
{ {
coreType = ECoreType.sing_box, CoreType = ECoreType.sing_box,
address = fileName, Address = fileName,
remarks = subRemarks ?? "singbox_custom", Remarks = subRemarks ?? "singbox_custom",
}; };
lstResult.Add(profileIt); lstResult.Add(profileIt);
} }
@ -42,9 +42,9 @@
var fileName = WriteAllText(strData); var fileName = WriteAllText(strData);
var profileItem = new ProfileItem var profileItem = new ProfileItem
{ {
coreType = ECoreType.sing_box, CoreType = ECoreType.sing_box,
address = fileName, Address = fileName,
remarks = subRemarks ?? "singbox_custom" Remarks = subRemarks ?? "singbox_custom"
}; };
return profileItem; return profileItem;

View File

@ -12,12 +12,12 @@
{ {
return null; return null;
} }
if (item.address.Length == 0 || item.port == 0) if (item.Address.Length == 0 || item.Port == 0)
{ {
return null; return null;
} }
item.configType = EConfigType.SOCKS; item.ConfigType = EConfigType.SOCKS;
return item; return item;
} }
@ -28,9 +28,9 @@
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;
if (Utils.IsNotEmpty(item.remarks)) if (Utils.IsNotEmpty(item.Remarks))
{ {
remark = "#" + Utils.UrlEncode(item.remarks); remark = "#" + Utils.UrlEncode(item.Remarks);
} }
//url = string.Format("{0}:{1}@{2}:{3}", //url = string.Format("{0}:{1}@{2}:{3}",
// item.security, // item.security,
@ -39,15 +39,15 @@
// item.port); // item.port);
//url = Utile.Base64Encode(url); //url = Utile.Base64Encode(url);
//new //new
var pw = Utils.Base64Encode($"{item.security}:{item.id}"); var pw = Utils.Base64Encode($"{item.Security}:{item.Id}");
return ToUri(EConfigType.SOCKS, item.address, item.port, pw, null, remark); return ToUri(EConfigType.SOCKS, item.Address, item.Port, pw, null, remark);
} }
private static ProfileItem? ResolveSocks(string result) private static ProfileItem? ResolveSocks(string result)
{ {
ProfileItem item = new() ProfileItem item = new()
{ {
configType = EConfigType.SOCKS ConfigType = EConfigType.SOCKS
}; };
result = result[Global.ProtocolShares[EConfigType.SOCKS].Length..]; result = result[Global.ProtocolShares[EConfigType.SOCKS].Length..];
//remark //remark
@ -56,7 +56,7 @@
{ {
try try
{ {
item.remarks = Utils.UrlDecode(result.Substring(indexRemark + 1, result.Length - indexRemark - 1)); item.Remarks = Utils.UrlDecode(result.Substring(indexRemark + 1, result.Length - indexRemark - 1));
} }
catch { } catch { }
result = result[..indexRemark]; result = result[..indexRemark];
@ -83,10 +83,10 @@
{ {
return null; return null;
} }
item.address = arr1[1][..indexPort]; item.Address = arr1[1][..indexPort];
item.port = Utils.ToInt(arr1[1][(indexPort + 1)..]); item.Port = Utils.ToInt(arr1[1][(indexPort + 1)..]);
item.security = arr21[0]; item.Security = arr21[0];
item.id = arr21[1]; item.Id = arr21[1];
return item; return item;
} }
@ -104,9 +104,9 @@
} }
ProfileItem item = new() ProfileItem item = new()
{ {
remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped), Remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
address = parsedUrl.IdnHost, Address = parsedUrl.IdnHost,
port = parsedUrl.Port, Port = parsedUrl.Port,
}; };
// parse base64 UserInfo // parse base64 UserInfo
@ -115,8 +115,8 @@
var userInfoParts = userInfo.Split(new[] { ':' }, 2); var userInfoParts = userInfo.Split(new[] { ':' }, 2);
if (userInfoParts.Length == 2) if (userInfoParts.Length == 2)
{ {
item.security = userInfoParts[0]; item.Security = userInfoParts[0];
item.id = userInfoParts[1]; item.Id = userInfoParts[1];
} }
return item; return item;

View File

@ -8,15 +8,15 @@
ProfileItem item = new() ProfileItem item = new()
{ {
configType = EConfigType.Trojan ConfigType = EConfigType.Trojan
}; };
Uri url = new(str); Uri url = new(str);
item.address = url.IdnHost; item.Address = url.IdnHost;
item.port = url.Port; item.Port = url.Port;
item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped); item.Remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
item.id = Utils.UrlDecode(url.UserInfo); item.Id = Utils.UrlDecode(url.UserInfo);
var query = Utils.ParseQueryString(url.Query); var query = Utils.ParseQueryString(url.Query);
ResolveStdTransport(query, ref item); ResolveStdTransport(query, ref item);
@ -30,14 +30,14 @@
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;
if (Utils.IsNotEmpty(item.remarks)) if (Utils.IsNotEmpty(item.Remarks))
{ {
remark = "#" + Utils.UrlEncode(item.remarks); remark = "#" + Utils.UrlEncode(item.Remarks);
} }
var dicQuery = new Dictionary<string, string>(); var dicQuery = new Dictionary<string, string>();
GetStdTransport(item, null, ref dicQuery); GetStdTransport(item, null, ref dicQuery);
return ToUri(EConfigType.Trojan, item.address, item.port, item.id, dicQuery, remark); return ToUri(EConfigType.Trojan, item.Address, item.Port, item.Id, dicQuery, remark);
} }
} }
} }

View File

@ -8,25 +8,25 @@
ProfileItem item = new() ProfileItem item = new()
{ {
configType = EConfigType.TUIC ConfigType = EConfigType.TUIC
}; };
Uri url = new(str); Uri url = new(str);
item.address = url.IdnHost; item.Address = url.IdnHost;
item.port = url.Port; item.Port = url.Port;
item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped); item.Remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
var rawUserInfo = Utils.UrlDecode(url.UserInfo); var rawUserInfo = Utils.UrlDecode(url.UserInfo);
var userInfoParts = rawUserInfo.Split(new[] { ':' }, 2); var userInfoParts = rawUserInfo.Split(new[] { ':' }, 2);
if (userInfoParts.Length == 2) if (userInfoParts.Length == 2)
{ {
item.id = userInfoParts[0]; item.Id = userInfoParts[0];
item.security = userInfoParts[1]; item.Security = userInfoParts[1];
} }
var query = Utils.ParseQueryString(url.Query); var query = Utils.ParseQueryString(url.Query);
ResolveStdTransport(query, ref item); ResolveStdTransport(query, ref item);
item.headerType = query["congestion_control"] ?? ""; item.HeaderType = query["congestion_control"] ?? "";
return item; return item;
} }
@ -37,22 +37,22 @@
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;
if (Utils.IsNotEmpty(item.remarks)) if (Utils.IsNotEmpty(item.Remarks))
{ {
remark = "#" + Utils.UrlEncode(item.remarks); remark = "#" + Utils.UrlEncode(item.Remarks);
} }
var dicQuery = new Dictionary<string, string>(); var dicQuery = new Dictionary<string, string>();
if (Utils.IsNotEmpty(item.sni)) if (Utils.IsNotEmpty(item.Sni))
{ {
dicQuery.Add("sni", item.sni); dicQuery.Add("sni", item.Sni);
} }
if (Utils.IsNotEmpty(item.alpn)) if (Utils.IsNotEmpty(item.Alpn))
{ {
dicQuery.Add("alpn", Utils.UrlEncode(item.alpn)); dicQuery.Add("alpn", Utils.UrlEncode(item.Alpn));
} }
dicQuery.Add("congestion_control", item.headerType); dicQuery.Add("congestion_control", item.HeaderType);
return ToUri(EConfigType.TUIC, item.address, item.port, $"{item.id}:{item.security}", dicQuery, remark); return ToUri(EConfigType.TUIC, item.Address, item.Port, $"{item.Id}:{item.Security}", dicQuery, remark);
} }
} }
} }

View File

@ -20,9 +20,9 @@
var profileIt = new ProfileItem var profileIt = new ProfileItem
{ {
coreType = ECoreType.Xray, CoreType = ECoreType.Xray,
address = fileName, Address = fileName,
remarks = v2rayCon.remarks ?? subRemarks ?? "v2ray_custom", Remarks = v2rayCon.remarks ?? subRemarks ?? "v2ray_custom",
}; };
lstResult.Add(profileIt); lstResult.Add(profileIt);
} }
@ -43,9 +43,9 @@
var profileItem = new ProfileItem var profileItem = new ProfileItem
{ {
coreType = ECoreType.Xray, CoreType = ECoreType.Xray,
address = fileName, Address = fileName,
remarks = v2rayConfig.remarks ?? subRemarks ?? "v2ray_custom" Remarks = v2rayConfig.remarks ?? subRemarks ?? "v2ray_custom"
}; };
return profileItem; return profileItem;

View File

@ -8,20 +8,20 @@
ProfileItem item = new() ProfileItem item = new()
{ {
configType = EConfigType.VLESS, ConfigType = EConfigType.VLESS,
security = Global.None Security = Global.None
}; };
Uri url = new(str); Uri url = new(str);
item.address = url.IdnHost; item.Address = url.IdnHost;
item.port = url.Port; item.Port = url.Port;
item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped); item.Remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
item.id = Utils.UrlDecode(url.UserInfo); item.Id = Utils.UrlDecode(url.UserInfo);
var query = Utils.ParseQueryString(url.Query); var query = Utils.ParseQueryString(url.Query);
item.security = query["encryption"] ?? Global.None; item.Security = query["encryption"] ?? Global.None;
item.streamSecurity = query["security"] ?? ""; item.StreamSecurity = query["security"] ?? "";
ResolveStdTransport(query, ref item); ResolveStdTransport(query, ref item);
return item; return item;
@ -33,14 +33,14 @@
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;
if (Utils.IsNotEmpty(item.remarks)) if (Utils.IsNotEmpty(item.Remarks))
{ {
remark = "#" + Utils.UrlEncode(item.remarks); remark = "#" + Utils.UrlEncode(item.Remarks);
} }
var dicQuery = new Dictionary<string, string>(); var dicQuery = new Dictionary<string, string>();
if (Utils.IsNotEmpty(item.security)) if (Utils.IsNotEmpty(item.Security))
{ {
dicQuery.Add("encryption", item.security); dicQuery.Add("encryption", item.Security);
} }
else else
{ {
@ -48,7 +48,7 @@
} }
GetStdTransport(item, Global.None, ref dicQuery); GetStdTransport(item, Global.None, ref dicQuery);
return ToUri(EConfigType.VLESS, item.address, item.port, item.id, dicQuery, remark); return ToUri(EConfigType.VLESS, item.Address, item.Port, item.Id, dicQuery, remark);
} }
} }
} }

View File

@ -24,21 +24,21 @@
VmessQRCode vmessQRCode = new() VmessQRCode vmessQRCode = new()
{ {
v = item.configVersion, v = item.ConfigVersion,
ps = item.remarks.TrimEx(), ps = item.Remarks.TrimEx(),
add = item.address, add = item.Address,
port = item.port, port = item.Port,
id = item.id, id = item.Id,
aid = item.alterId, aid = item.AlterId,
scy = item.security, scy = item.Security,
net = item.network, net = item.Network,
type = item.headerType, type = item.HeaderType,
host = item.requestHost, host = item.RequestHost,
path = item.path, path = item.Path,
tls = item.streamSecurity, tls = item.StreamSecurity,
sni = item.sni, sni = item.Sni,
alpn = item.alpn, alpn = item.Alpn,
fp = item.fingerprint fp = item.Fingerprint
}; };
url = JsonUtils.Serialize(vmessQRCode); url = JsonUtils.Serialize(vmessQRCode);
@ -53,7 +53,7 @@
msg = string.Empty; msg = string.Empty;
var item = new ProfileItem var item = new ProfileItem
{ {
configType = EConfigType.VMess ConfigType = EConfigType.VMess
}; };
result = result[Global.ProtocolShares[EConfigType.VMess].Length..]; result = result[Global.ProtocolShares[EConfigType.VMess].Length..];
@ -66,33 +66,33 @@
return null; return null;
} }
item.network = Global.DefaultNetwork; item.Network = Global.DefaultNetwork;
item.headerType = Global.None; item.HeaderType = Global.None;
item.configVersion = vmessQRCode.v; item.ConfigVersion = vmessQRCode.v;
item.remarks = Utils.ToString(vmessQRCode.ps); item.Remarks = Utils.ToString(vmessQRCode.ps);
item.address = Utils.ToString(vmessQRCode.add); item.Address = Utils.ToString(vmessQRCode.add);
item.port = vmessQRCode.port; item.Port = vmessQRCode.port;
item.id = Utils.ToString(vmessQRCode.id); item.Id = Utils.ToString(vmessQRCode.id);
item.alterId = vmessQRCode.aid; item.AlterId = vmessQRCode.aid;
item.security = Utils.ToString(vmessQRCode.scy); item.Security = Utils.ToString(vmessQRCode.scy);
item.security = Utils.IsNotEmpty(vmessQRCode.scy) ? vmessQRCode.scy : Global.DefaultSecurity; item.Security = Utils.IsNotEmpty(vmessQRCode.scy) ? vmessQRCode.scy : Global.DefaultSecurity;
if (Utils.IsNotEmpty(vmessQRCode.net)) if (Utils.IsNotEmpty(vmessQRCode.net))
{ {
item.network = vmessQRCode.net; item.Network = vmessQRCode.net;
} }
if (Utils.IsNotEmpty(vmessQRCode.type)) if (Utils.IsNotEmpty(vmessQRCode.type))
{ {
item.headerType = vmessQRCode.type; item.HeaderType = vmessQRCode.type;
} }
item.requestHost = Utils.ToString(vmessQRCode.host); item.RequestHost = Utils.ToString(vmessQRCode.host);
item.path = Utils.ToString(vmessQRCode.path); item.Path = Utils.ToString(vmessQRCode.path);
item.streamSecurity = Utils.ToString(vmessQRCode.tls); item.StreamSecurity = Utils.ToString(vmessQRCode.tls);
item.sni = Utils.ToString(vmessQRCode.sni); item.Sni = Utils.ToString(vmessQRCode.sni);
item.alpn = Utils.ToString(vmessQRCode.alpn); item.Alpn = Utils.ToString(vmessQRCode.alpn);
item.fingerprint = Utils.ToString(vmessQRCode.fp); item.Fingerprint = Utils.ToString(vmessQRCode.fp);
return item; return item;
} }
@ -101,16 +101,16 @@
{ {
ProfileItem item = new() ProfileItem item = new()
{ {
configType = EConfigType.VMess, ConfigType = EConfigType.VMess,
security = "auto" Security = "auto"
}; };
Uri url = new(str); Uri url = new(str);
item.address = url.IdnHost; item.Address = url.IdnHost;
item.port = url.Port; item.Port = url.Port;
item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped); item.Remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
item.id = Utils.UrlDecode(url.UserInfo); item.Id = Utils.UrlDecode(url.UserInfo);
var query = Utils.ParseQueryString(url.Query); var query = Utils.ParseQueryString(url.Query);
ResolveStdTransport(query, ref item); ResolveStdTransport(query, ref item);

View File

@ -8,22 +8,22 @@
ProfileItem item = new() ProfileItem item = new()
{ {
configType = EConfigType.WireGuard ConfigType = EConfigType.WireGuard
}; };
Uri url = new(str); Uri url = new(str);
item.address = url.IdnHost; item.Address = url.IdnHost;
item.port = url.Port; item.Port = url.Port;
item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped); item.Remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);
item.id = Utils.UrlDecode(url.UserInfo); item.Id = Utils.UrlDecode(url.UserInfo);
var query = Utils.ParseQueryString(url.Query); var query = Utils.ParseQueryString(url.Query);
item.publicKey = Utils.UrlDecode(query["publickey"] ?? ""); item.PublicKey = Utils.UrlDecode(query["publickey"] ?? "");
item.path = Utils.UrlDecode(query["reserved"] ?? ""); item.Path = Utils.UrlDecode(query["reserved"] ?? "");
item.requestHost = Utils.UrlDecode(query["address"] ?? ""); item.RequestHost = Utils.UrlDecode(query["address"] ?? "");
item.shortId = Utils.UrlDecode(query["mtu"] ?? ""); item.ShortId = Utils.UrlDecode(query["mtu"] ?? "");
return item; return item;
} }
@ -34,29 +34,29 @@
string url = string.Empty; string url = string.Empty;
string remark = string.Empty; string remark = string.Empty;
if (Utils.IsNotEmpty(item.remarks)) if (Utils.IsNotEmpty(item.Remarks))
{ {
remark = "#" + Utils.UrlEncode(item.remarks); remark = "#" + Utils.UrlEncode(item.Remarks);
} }
var dicQuery = new Dictionary<string, string>(); var dicQuery = new Dictionary<string, string>();
if (Utils.IsNotEmpty(item.publicKey)) if (Utils.IsNotEmpty(item.PublicKey))
{ {
dicQuery.Add("publickey", Utils.UrlEncode(item.publicKey)); dicQuery.Add("publickey", Utils.UrlEncode(item.PublicKey));
} }
if (Utils.IsNotEmpty(item.path)) if (Utils.IsNotEmpty(item.Path))
{ {
dicQuery.Add("reserved", Utils.UrlEncode(item.path)); dicQuery.Add("reserved", Utils.UrlEncode(item.Path));
} }
if (Utils.IsNotEmpty(item.requestHost)) if (Utils.IsNotEmpty(item.RequestHost))
{ {
dicQuery.Add("address", Utils.UrlEncode(item.requestHost)); dicQuery.Add("address", Utils.UrlEncode(item.RequestHost));
} }
if (Utils.IsNotEmpty(item.shortId)) if (Utils.IsNotEmpty(item.ShortId))
{ {
dicQuery.Add("mtu", Utils.UrlEncode(item.shortId)); dicQuery.Add("mtu", Utils.UrlEncode(item.ShortId));
} }
return ToUri(EConfigType.WireGuard, item.address, item.port, item.id, dicQuery, remark); return ToUri(EConfigType.WireGuard, item.Address, item.Port, item.Id, dicQuery, remark);
} }
} }
} }

View File

@ -57,8 +57,8 @@ namespace ServiceLib.Handler
for (int i = 0; i < cnt; i++) for (int i = 0; i < cnt; i++)
{ {
var id = _queIndexIds.Dequeue(); var id = _queIndexIds.Dequeue();
var item = lstExists.FirstOrDefault(t => t.indexId == id); var item = lstExists.FirstOrDefault(t => t.IndexId == id);
var itemNew = _lstProfileEx?.FirstOrDefault(t => t.indexId == id); var itemNew = _lstProfileEx?.FirstOrDefault(t => t.IndexId == id);
if (itemNew is null) if (itemNew is null)
{ {
continue; continue;
@ -92,10 +92,10 @@ namespace ServiceLib.Handler
{ {
profileEx = new() profileEx = new()
{ {
indexId = indexId, IndexId = indexId,
delay = 0, Delay = 0,
speed = 0, Speed = 0,
sort = 0 Sort = 0
}; };
_lstProfileEx.Add(profileEx); _lstProfileEx.Add(profileEx);
IndexIdEnqueue(indexId); IndexIdEnqueue(indexId);
@ -121,49 +121,49 @@ namespace ServiceLib.Handler
public void SetTestDelay(string indexId, string delayVal) public void SetTestDelay(string indexId, string delayVal)
{ {
var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId); var profileEx = _lstProfileEx.FirstOrDefault(t => t.IndexId == indexId);
if (profileEx == null) if (profileEx == null)
{ {
AddProfileEx(indexId, ref profileEx); AddProfileEx(indexId, ref profileEx);
} }
int.TryParse(delayVal, out int delay); int.TryParse(delayVal, out int delay);
profileEx.delay = delay; profileEx.Delay = delay;
IndexIdEnqueue(indexId); IndexIdEnqueue(indexId);
} }
public void SetTestSpeed(string indexId, string speedVal) public void SetTestSpeed(string indexId, string speedVal)
{ {
var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId); var profileEx = _lstProfileEx.FirstOrDefault(t => t.IndexId == indexId);
if (profileEx == null) if (profileEx == null)
{ {
AddProfileEx(indexId, ref profileEx); AddProfileEx(indexId, ref profileEx);
} }
decimal.TryParse(speedVal, out decimal speed); decimal.TryParse(speedVal, out decimal speed);
profileEx.speed = speed; profileEx.Speed = speed;
IndexIdEnqueue(indexId); IndexIdEnqueue(indexId);
} }
public void SetSort(string indexId, int sort) public void SetSort(string indexId, int sort)
{ {
var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId); var profileEx = _lstProfileEx.FirstOrDefault(t => t.IndexId == indexId);
if (profileEx == null) if (profileEx == null)
{ {
AddProfileEx(indexId, ref profileEx); AddProfileEx(indexId, ref profileEx);
} }
profileEx.sort = sort; profileEx.Sort = sort;
IndexIdEnqueue(indexId); IndexIdEnqueue(indexId);
} }
public int GetSort(string indexId) public int GetSort(string indexId)
{ {
var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId); var profileEx = _lstProfileEx.FirstOrDefault(t => t.IndexId == indexId);
if (profileEx == null) if (profileEx == null)
{ {
return 0; return 0;
} }
return profileEx.sort; return profileEx.Sort;
} }
public int GetMaxSort() public int GetMaxSort()
@ -172,7 +172,7 @@ namespace ServiceLib.Handler
{ {
return 0; return 0;
} }
return _lstProfileEx.Max(t => t == null ? 0 : t.sort); return _lstProfileEx.Max(t => t == null ? 0 : t.Sort);
} }
} }
} }

View File

@ -89,52 +89,52 @@
} }
if (server.proxyUp != 0 || server.proxyDown != 0) if (server.proxyUp != 0 || server.proxyDown != 0)
{ {
_serverStatItem.todayUp += server.proxyUp; _serverStatItem.TodayUp += server.proxyUp;
_serverStatItem.todayDown += server.proxyDown; _serverStatItem.TodayDown += server.proxyDown;
_serverStatItem.totalUp += server.proxyUp; _serverStatItem.TotalUp += server.proxyUp;
_serverStatItem.totalDown += server.proxyDown; _serverStatItem.TotalDown += server.proxyDown;
} }
server.indexId = _config.IndexId; server.IndexId = _config.IndexId;
server.todayUp = _serverStatItem.todayUp; server.TodayUp = _serverStatItem.TodayUp;
server.todayDown = _serverStatItem.todayDown; server.TodayDown = _serverStatItem.TodayDown;
server.totalUp = _serverStatItem.totalUp; server.TotalUp = _serverStatItem.TotalUp;
server.totalDown = _serverStatItem.totalDown; server.TotalDown = _serverStatItem.TotalDown;
_updateFunc?.Invoke(server); _updateFunc?.Invoke(server);
} }
private async Task GetServerStatItem(string indexId) private async Task GetServerStatItem(string indexId)
{ {
long ticks = DateTime.Now.Date.Ticks; long ticks = DateTime.Now.Date.Ticks;
if (_serverStatItem != null && _serverStatItem.indexId != indexId) if (_serverStatItem != null && _serverStatItem.IndexId != indexId)
{ {
_serverStatItem = null; _serverStatItem = null;
} }
if (_serverStatItem == null) if (_serverStatItem == null)
{ {
_serverStatItem = _lstServerStat.FirstOrDefault(t => t.indexId == indexId); _serverStatItem = _lstServerStat.FirstOrDefault(t => t.IndexId == indexId);
if (_serverStatItem == null) if (_serverStatItem == null)
{ {
_serverStatItem = new ServerStatItem _serverStatItem = new ServerStatItem
{ {
indexId = indexId, IndexId = indexId,
totalUp = 0, TotalUp = 0,
totalDown = 0, TotalDown = 0,
todayUp = 0, TodayUp = 0,
todayDown = 0, TodayDown = 0,
dateNow = ticks DateNow = ticks
}; };
await SQLiteHelper.Instance.ReplaceAsync(_serverStatItem); await SQLiteHelper.Instance.ReplaceAsync(_serverStatItem);
_lstServerStat.Add(_serverStatItem); _lstServerStat.Add(_serverStatItem);
} }
} }
if (_serverStatItem.dateNow != ticks) if (_serverStatItem.DateNow != ticks)
{ {
_serverStatItem.todayUp = 0; _serverStatItem.TodayUp = 0;
_serverStatItem.todayDown = 0; _serverStatItem.TodayDown = 0;
_serverStatItem.dateNow = ticks; _serverStatItem.DateNow = ticks;
} }
} }
} }

View File

@ -21,19 +21,19 @@
{ {
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(); var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
var lstSubs = (await AppHandler.Instance.SubItems()) var lstSubs = (await AppHandler.Instance.SubItems())
.Where(t => t.autoUpdateInterval > 0) .Where(t => t.AutoUpdateInterval > 0)
.Where(t => updateTime - t.updateTime >= t.autoUpdateInterval * 60) .Where(t => updateTime - t.UpdateTime >= t.AutoUpdateInterval * 60)
.ToList(); .ToList();
foreach (var item in lstSubs) foreach (var item in lstSubs)
{ {
await updateHandle.UpdateSubscriptionProcess(config, item.id, true, (bool success, string msg) => await updateHandle.UpdateSubscriptionProcess(config, item.Id, true, (bool success, string msg) =>
{ {
updateFunc?.Invoke(success, msg); updateFunc?.Invoke(success, msg);
if (success) if (success)
Logging.SaveLog("subscription" + msg); Logging.SaveLog("subscription" + msg);
}); });
item.updateTime = updateTime; item.UpdateTime = updateTime;
await ConfigHandler.AddSubItem(config, item); await ConfigHandler.AddSubItem(config, item);
await Task.Delay(5000); await Task.Delay(5000);

View File

@ -13,6 +13,6 @@
public string? delayName { get; set; } public string? delayName { get; set; }
public bool isActive { get; set; } public bool IsActive { get; set; }
} }
} }

View File

@ -62,10 +62,10 @@
[Serializable] [Serializable]
public class GrpcItem public class GrpcItem
{ {
public int IdleTimeout { get; set; } public int? IdleTimeout { get; set; }
public int HealthCheckTimeout { get; set; } public int? HealthCheckTimeout { get; set; }
public bool PermitWithoutStream { get; set; } public bool? PermitWithoutStream { get; set; }
public int InitialWindowsSize { get; set; } public int? InitialWindowsSize { get; set; }
} }
[Serializable] [Serializable]

View File

@ -6,15 +6,15 @@ namespace ServiceLib.Models
public class DNSItem public class DNSItem
{ {
[PrimaryKey] [PrimaryKey]
public string id { get; set; } public string Id { get; set; }
public string remarks { get; set; } public string Remarks { get; set; }
public bool enabled { get; set; } = true; public bool Enabled { get; set; } = true;
public ECoreType coreType { get; set; } public ECoreType CoreType { get; set; }
public bool useSystemHosts { get; set; } public bool UseSystemHosts { get; set; }
public string? normalDNS { get; set; } public string? NormalDNS { get; set; }
public string? tunDNS { get; set; } public string? TunDNS { get; set; }
public string? domainStrategy4Freedom { get; set; } public string? DomainStrategy4Freedom { get; set; }
public string? domainDNSAddress { get; set; } public string? DomainDNSAddress { get; set; }
} }
} }

View File

@ -6,10 +6,10 @@ namespace ServiceLib.Models
public class ProfileExItem public class ProfileExItem
{ {
[PrimaryKey] [PrimaryKey]
public string indexId { get; set; } public string IndexId { get; set; }
public int delay { get; set; } public int Delay { get; set; }
public decimal speed { get; set; } public decimal Speed { get; set; }
public int sort { get; set; } public int Sort { get; set; }
} }
} }

View File

@ -7,31 +7,31 @@ namespace ServiceLib.Models
{ {
public ProfileItem() public ProfileItem()
{ {
indexId = string.Empty; IndexId = string.Empty;
configType = EConfigType.VMess; ConfigType = EConfigType.VMess;
configVersion = 2; ConfigVersion = 2;
address = string.Empty; Address = string.Empty;
port = 0; Port = 0;
id = string.Empty; Id = string.Empty;
alterId = 0; AlterId = 0;
security = string.Empty; Security = string.Empty;
network = string.Empty; Network = string.Empty;
remarks = string.Empty; Remarks = string.Empty;
headerType = string.Empty; HeaderType = string.Empty;
requestHost = string.Empty; RequestHost = string.Empty;
path = string.Empty; Path = string.Empty;
streamSecurity = string.Empty; StreamSecurity = string.Empty;
allowInsecure = string.Empty; AllowInsecure = string.Empty;
subid = string.Empty; Subid = string.Empty;
flow = string.Empty; Flow = string.Empty;
} }
#region function #region function
public string GetSummary() public string GetSummary()
{ {
string summary = string.Format("[{0}] ", (configType).ToString()); string summary = string.Format("[{0}] ", (ConfigType).ToString());
string[] arrAddr = address.Split('.'); string[] arrAddr = Address.Split('.');
string addr; string addr;
if (arrAddr.Length > 2) if (arrAddr.Length > 2)
{ {
@ -43,16 +43,16 @@ namespace ServiceLib.Models
} }
else else
{ {
addr = address; addr = Address;
} }
switch (configType) switch (ConfigType)
{ {
case EConfigType.Custom: case EConfigType.Custom:
summary += string.Format("[{1}]{0}", remarks, coreType.ToString()); summary += string.Format("[{1}]{0}", Remarks, CoreType.ToString());
break; break;
default: default:
summary += string.Format("{0}({1}:{2})", remarks, addr, port); summary += string.Format("{0}({1}:{2})", Remarks, addr, Port);
break; break;
} }
return summary; return summary;
@ -60,131 +60,55 @@ namespace ServiceLib.Models
public List<string>? GetAlpn() public List<string>? GetAlpn()
{ {
if (Utils.IsNullOrEmpty(alpn)) if (Utils.IsNullOrEmpty(Alpn))
{ {
return null; return null;
} }
else else
{ {
return Utils.String2List(alpn); return Utils.String2List(Alpn);
} }
} }
public string GetNetwork() public string GetNetwork()
{ {
if (Utils.IsNullOrEmpty(network) || !Global.Networks.Contains(network)) if (Utils.IsNullOrEmpty(Network) || !Global.Networks.Contains(Network))
{ {
return Global.DefaultNetwork; return Global.DefaultNetwork;
} }
return network.TrimEx(); return Network.TrimEx();
} }
#endregion function #endregion function
[PrimaryKey] [PrimaryKey]
public string indexId { get; set; } public string IndexId { get; set; }
/// <summary> public EConfigType ConfigType { get; set; }
/// config type(1=normal,2=custom) public int ConfigVersion { get; set; }
/// </summary> public string Address { get; set; }
public EConfigType configType { get; set; } public int Port { get; set; }
public string Id { get; set; }
/// <summary> public int AlterId { get; set; }
/// 版本(现在=2) public string Security { get; set; }
/// </summary> public string Network { get; set; }
public int configVersion { get; set; } public string Remarks { get; set; }
public string HeaderType { get; set; }
/// <summary> public string RequestHost { get; set; }
/// 远程服务器地址 public string Path { get; set; }
/// </summary> public string StreamSecurity { get; set; }
public string address { get; set; } public string AllowInsecure { get; set; }
public string Subid { get; set; }
/// <summary> public bool IsSub { get; set; } = true;
/// 远程服务器端口 public string Flow { get; set; }
/// </summary> public string Sni { get; set; }
public int port { get; set; } public string Alpn { get; set; } = string.Empty;
public ECoreType? CoreType { get; set; }
/// <summary> public int? PreSocksPort { get; set; }
/// 远程服务器ID public string Fingerprint { get; set; }
/// </summary> public bool DisplayLog { get; set; } = true;
public string id { get; set; } public string PublicKey { get; set; }
public string ShortId { get; set; }
/// <summary> public string SpiderX { get; set; }
/// 远程服务器额外ID
/// </summary>
public int alterId { get; set; }
/// <summary>
/// 本地安全策略
/// </summary>
public string security { get; set; }
/// <summary>
/// tcp,kcp,ws,h2,quic
/// </summary>
public string network { get; set; }
/// <summary>
///
/// </summary>
public string remarks { get; set; }
/// <summary>
/// 伪装类型
/// </summary>
public string headerType { get; set; }
/// <summary>
/// 伪装的域名
/// </summary>
public string requestHost { get; set; }
/// <summary>
/// ws h2 path
/// </summary>
public string path { get; set; }
/// <summary>
/// 传输层安全
/// </summary>
public string streamSecurity { get; set; }
/// <summary>
/// 是否允许不安全连接(用于客户端)
/// </summary>
public string allowInsecure { get; set; }
/// <summary>
/// SubItem id
/// </summary>
public string subid { get; set; }
public bool isSub { get; set; } = true;
/// <summary>
/// VLESS flow
/// </summary>
public string flow { get; set; }
/// <summary>
/// tls sni
/// </summary>
public string sni { get; set; }
/// <summary>
/// tls alpn
/// </summary>
public string alpn { get; set; } = string.Empty;
public ECoreType? coreType { get; set; }
public int? preSocksPort { get; set; }
public string fingerprint { get; set; }
public bool displayLog { get; set; } = true;
public string publicKey { get; set; }
public string shortId { get; set; }
public string spiderX { get; set; }
} }
} }

View File

@ -3,16 +3,16 @@
[Serializable] [Serializable]
public class ProfileItemModel : ProfileItem public class ProfileItemModel : ProfileItem
{ {
public bool isActive { get; set; } public bool IsActive { get; set; }
public string subRemarks { get; set; } public string SubRemarks { get; set; }
public int delay { get; set; } public int Delay { get; set; }
public decimal speed { get; set; } public decimal Speed { get; set; }
public int sort { get; set; } public int Sort { get; set; }
public string delayVal { get; set; } public string DelayVal { get; set; }
public string speedVal { get; set; } public string SpeedVal { get; set; }
public string todayUp { get; set; } public string TodayUp { get; set; }
public string todayDown { get; set; } public string TodayDown { get; set; }
public string totalUp { get; set; } public string TotalUp { get; set; }
public string totalDown { get; set; } public string TotalDown { get; set; }
} }
} }

View File

@ -6,18 +6,17 @@ namespace ServiceLib.Models
public class RoutingItem public class RoutingItem
{ {
[PrimaryKey] [PrimaryKey]
public string id { get; set; } public string Id { get; set; }
public string Remarks { get; set; }
public string remarks { get; set; } public string Url { get; set; }
public string url { get; set; } public string RuleSet { get; set; }
public string ruleSet { get; set; } public int RuleNum { get; set; }
public int ruleNum { get; set; } public bool Enabled { get; set; } = true;
public bool enabled { get; set; } = true; public bool Locked { get; set; }
public bool locked { get; set; } public string CustomIcon { get; set; }
public string customIcon { get; set; } public string CustomRulesetPath4Singbox { get; set; }
public string customRulesetPath4Singbox { get; set; } public string DomainStrategy { get; set; }
public string domainStrategy { get; set; } public string DomainStrategy4Singbox { get; set; }
public string domainStrategy4Singbox { get; set; } public int Sort { get; set; }
public int sort { get; set; }
} }
} }

View File

@ -3,6 +3,6 @@
[Serializable] [Serializable]
public class RoutingItemModel : RoutingItem public class RoutingItemModel : RoutingItem
{ {
public bool isActive { get; set; } public bool IsActive { get; set; }
} }
} }

View File

@ -13,7 +13,7 @@
public List<string>? domain { get; set; } public List<string>? domain { get; set; }
public List<string>? protocol { get; set; } public List<string>? protocol { get; set; }
public List<string>? process { get; set; } public List<string>? process { get; set; }
public bool enabled { get; set; } = true; public bool Enabled { get; set; } = true;
public string? remarks { get; set; } public string? Remarks { get; set; }
} }
} }

View File

@ -3,9 +3,9 @@
[Serializable] [Serializable]
public class RulesItemModel : RulesItem public class RulesItemModel : RulesItem
{ {
public string inboundTags { get; set; } public string InboundTags { get; set; }
public string ips { get; set; } public string Ips { get; set; }
public string domains { get; set; } public string Domains { get; set; }
public string protocols { get; set; } public string Protocols { get; set; }
} }
} }

View File

@ -6,34 +6,16 @@ namespace ServiceLib.Models
public class ServerStatItem public class ServerStatItem
{ {
[PrimaryKey] [PrimaryKey]
public string indexId public string IndexId { get; set; }
{
get; set;
}
public long totalUp public long TotalUp { get; set; }
{
get; set;
}
public long totalDown public long TotalDown { get; set; }
{
get; set;
}
public long todayUp public long TodayUp { get; set; }
{
get; set;
}
public long todayDown public long TodayDown { get; set; }
{
get; set;
}
public long dateNow public long DateNow { get; set; }
{
get; set;
}
} }
} }

View File

@ -6,32 +6,32 @@ namespace ServiceLib.Models
public class SubItem public class SubItem
{ {
[PrimaryKey] [PrimaryKey]
public string id { get; set; } public string Id { get; set; }
public string remarks { get; set; } public string Remarks { get; set; }
public string url { get; set; } public string Url { get; set; }
public string moreUrl { get; set; } public string MoreUrl { get; set; }
public bool enabled { get; set; } = true; public bool Enabled { get; set; } = true;
public string userAgent { get; set; } = string.Empty; public string UserAgent { get; set; } = string.Empty;
public int sort { get; set; } public int Sort { get; set; }
public string? filter { get; set; } public string? Filter { get; set; }
public int autoUpdateInterval { get; set; } public int AutoUpdateInterval { get; set; }
public long updateTime { get; set; } public long UpdateTime { get; set; }
public string? convertTarget { get; set; } public string? ConvertTarget { get; set; }
public string? prevProfile { get; set; } public string? PrevProfile { get; set; }
public string? nextProfile { get; set; } public string? NextProfile { get; set; }
public int? preSocksPort { get; set; } public int? PreSocksPort { get; set; }
} }
} }

View File

@ -678,10 +678,10 @@ namespace ServiceLib.Models
public string? authority { get; set; } public string? authority { get; set; }
public string? serviceName { get; set; } public string? serviceName { get; set; }
public bool multiMode { get; set; } public bool multiMode { get; set; }
public int idle_timeout { get; set; } public int? idle_timeout { get; set; }
public int health_check_timeout { get; set; } public int? health_check_timeout { get; set; }
public bool permit_without_stream { get; set; } public bool? permit_without_stream { get; set; }
public int initial_windows_size { get; set; } public int? initial_windows_size { get; set; }
} }
public class AccountsItem4Ray public class AccountsItem4Ray

View File

@ -43,7 +43,7 @@
File.Delete(fileName); File.Delete(fileName);
} }
string addressFileName = node.address; string addressFileName = node.Address;
if (Utils.IsNullOrEmpty(addressFileName)) if (Utils.IsNullOrEmpty(addressFileName))
{ {
ret.Msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;

View File

@ -21,7 +21,7 @@ namespace ServiceLib.Services.CoreConfig
try try
{ {
if (node == null if (node == null
|| node.port <= 0) || node.Port <= 0)
{ {
ret.Msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return ret; return ret;
@ -137,7 +137,7 @@ namespace ServiceLib.Services.CoreConfig
var item = await AppHandler.Instance.GetProfileItem(it.IndexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS) if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
{ {
if (item is null || Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id)) if (item is null || Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id))
{ {
continue; continue;
} }
@ -184,19 +184,19 @@ namespace ServiceLib.Services.CoreConfig
{ {
continue; continue;
} }
if (item.configType == EConfigType.Shadowsocks if (item.ConfigType == EConfigType.Shadowsocks
&& !Global.SsSecuritiesInSingbox.Contains(item.security)) && !Global.SsSecuritiesInSingbox.Contains(item.Security))
{ {
continue; continue;
} }
if (item.configType == EConfigType.VLESS if (item.ConfigType == EConfigType.VLESS
&& !Global.Flows.Contains(item.flow)) && !Global.Flows.Contains(item.Flow))
{ {
continue; continue;
} }
if (it.ConfigType is EConfigType.VLESS or EConfigType.Trojan if (it.ConfigType is EConfigType.VLESS or EConfigType.Trojan
&& item.streamSecurity == Global.StreamSecurityReality && item.StreamSecurity == Global.StreamSecurityReality
&& item.publicKey.IsNullOrEmpty()) && item.PublicKey.IsNullOrEmpty())
{ {
continue; continue;
} }
@ -278,32 +278,32 @@ namespace ServiceLib.Services.CoreConfig
var tagProxy = new List<string>(); var tagProxy = new List<string>();
foreach (var it in selecteds) foreach (var it in selecteds)
{ {
if (it.configType == EConfigType.Custom) if (it.ConfigType == EConfigType.Custom)
{ {
continue; continue;
} }
if (it.port <= 0) if (it.Port <= 0)
{ {
continue; continue;
} }
var item = await AppHandler.Instance.GetProfileItem(it.indexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (item is null) if (item is null)
{ {
continue; continue;
} }
if (it.configType is EConfigType.VMess or EConfigType.VLESS) if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
{ {
if (Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id)) if (Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id))
{ {
continue; continue;
} }
} }
if (item.configType == EConfigType.Shadowsocks if (item.ConfigType == EConfigType.Shadowsocks
&& !Global.SsSecuritiesInSingbox.Contains(item.security)) && !Global.SsSecuritiesInSingbox.Contains(item.Security))
{ {
continue; continue;
} }
if (item.configType == EConfigType.VLESS && !Global.Flows.Contains(item.flow)) if (item.ConfigType == EConfigType.VLESS && !Global.Flows.Contains(item.Flow))
{ {
continue; continue;
} }
@ -381,7 +381,7 @@ namespace ServiceLib.Services.CoreConfig
File.Delete(fileName); File.Delete(fileName);
} }
string addressFileName = node.address; string addressFileName = node.Address;
if (Utils.IsNullOrEmpty(addressFileName)) if (Utils.IsNullOrEmpty(addressFileName))
{ {
ret.Msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
@ -397,7 +397,7 @@ namespace ServiceLib.Services.CoreConfig
return ret; return ret;
} }
if (node.address == Global.CoreMultipleLoadConfigFileName) if (node.Address == Global.CoreMultipleLoadConfigFileName)
{ {
var txtFile = File.ReadAllText(addressFileName); var txtFile = File.ReadAllText(addressFileName);
var singboxConfig = JsonUtils.Deserialize<SingboxConfig>(txtFile); var singboxConfig = JsonUtils.Deserialize<SingboxConfig>(txtFile);
@ -502,9 +502,9 @@ namespace ServiceLib.Services.CoreConfig
if (_config.RoutingBasicItem.EnableRoutingAdvanced) if (_config.RoutingBasicItem.EnableRoutingAdvanced)
{ {
var routing = await ConfigHandler.GetDefaultRouting(_config); var routing = await ConfigHandler.GetDefaultRouting(_config);
if (Utils.IsNotEmpty(routing.domainStrategy4Singbox)) if (Utils.IsNotEmpty(routing.DomainStrategy4Singbox))
{ {
inbound.domain_strategy = routing.domainStrategy4Singbox; inbound.domain_strategy = routing.DomainStrategy4Singbox;
} }
} }
@ -584,19 +584,19 @@ namespace ServiceLib.Services.CoreConfig
{ {
try try
{ {
outbound.server = node.address; outbound.server = node.Address;
outbound.server_port = node.port; outbound.server_port = node.Port;
outbound.type = Global.ProtocolTypes[node.configType]; outbound.type = Global.ProtocolTypes[node.ConfigType];
switch (node.configType) switch (node.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
{ {
outbound.uuid = node.id; outbound.uuid = node.Id;
outbound.alter_id = node.alterId; outbound.alter_id = node.AlterId;
if (Global.VmessSecurities.Contains(node.security)) if (Global.VmessSecurities.Contains(node.Security))
{ {
outbound.security = node.security; outbound.security = node.Security;
} }
else else
{ {
@ -608,8 +608,8 @@ namespace ServiceLib.Services.CoreConfig
} }
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
{ {
outbound.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None; outbound.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.Security) ? node.Security : Global.None;
outbound.password = node.id; outbound.password = node.Id;
await GenOutboundMux(node, outbound); await GenOutboundMux(node, outbound);
break; break;
@ -617,57 +617,57 @@ namespace ServiceLib.Services.CoreConfig
case EConfigType.SOCKS: case EConfigType.SOCKS:
{ {
outbound.version = "5"; outbound.version = "5";
if (Utils.IsNotEmpty(node.security) if (Utils.IsNotEmpty(node.Security)
&& Utils.IsNotEmpty(node.id)) && Utils.IsNotEmpty(node.Id))
{ {
outbound.username = node.security; outbound.username = node.Security;
outbound.password = node.id; outbound.password = node.Id;
} }
break; break;
} }
case EConfigType.HTTP: case EConfigType.HTTP:
{ {
if (Utils.IsNotEmpty(node.security) if (Utils.IsNotEmpty(node.Security)
&& Utils.IsNotEmpty(node.id)) && Utils.IsNotEmpty(node.Id))
{ {
outbound.username = node.security; outbound.username = node.Security;
outbound.password = node.id; outbound.password = node.Id;
} }
break; break;
} }
case EConfigType.VLESS: case EConfigType.VLESS:
{ {
outbound.uuid = node.id; outbound.uuid = node.Id;
outbound.packet_encoding = "xudp"; outbound.packet_encoding = "xudp";
if (Utils.IsNullOrEmpty(node.flow)) if (Utils.IsNullOrEmpty(node.Flow))
{ {
await GenOutboundMux(node, outbound); await GenOutboundMux(node, outbound);
} }
else else
{ {
outbound.flow = node.flow; outbound.flow = node.Flow;
} }
break; break;
} }
case EConfigType.Trojan: case EConfigType.Trojan:
{ {
outbound.password = node.id; outbound.password = node.Id;
await GenOutboundMux(node, outbound); await GenOutboundMux(node, outbound);
break; break;
} }
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
{ {
outbound.password = node.id; outbound.password = node.Id;
if (Utils.IsNotEmpty(node.path)) if (Utils.IsNotEmpty(node.Path))
{ {
outbound.obfs = new() outbound.obfs = new()
{ {
type = "salamander", type = "salamander",
password = node.path.TrimEx(), password = node.Path.TrimEx(),
}; };
} }
@ -677,18 +677,18 @@ namespace ServiceLib.Services.CoreConfig
} }
case EConfigType.TUIC: case EConfigType.TUIC:
{ {
outbound.uuid = node.id; outbound.uuid = node.Id;
outbound.password = node.security; outbound.password = node.Security;
outbound.congestion_control = node.headerType; outbound.congestion_control = node.HeaderType;
break; break;
} }
case EConfigType.WireGuard: case EConfigType.WireGuard:
{ {
outbound.private_key = node.id; outbound.private_key = node.Id;
outbound.peer_public_key = node.publicKey; outbound.peer_public_key = node.PublicKey;
outbound.reserved = Utils.String2List(node.path)?.Select(int.Parse).ToList(); outbound.reserved = Utils.String2List(node.Path)?.Select(int.Parse).ToList();
outbound.local_address = Utils.String2List(node.requestHost); outbound.local_address = Utils.String2List(node.RequestHost);
outbound.mtu = Utils.ToInt(node.shortId.IsNullOrEmpty() ? Global.TunMtus.FirstOrDefault() : node.shortId); outbound.mtu = Utils.ToInt(node.ShortId.IsNullOrEmpty() ? Global.TunMtus.FirstOrDefault() : node.ShortId);
break; break;
} }
} }
@ -731,39 +731,39 @@ namespace ServiceLib.Services.CoreConfig
{ {
try try
{ {
if (node.streamSecurity == Global.StreamSecurityReality || node.streamSecurity == Global.StreamSecurity) if (node.StreamSecurity == Global.StreamSecurityReality || node.StreamSecurity == Global.StreamSecurity)
{ {
var server_name = string.Empty; var server_name = string.Empty;
if (Utils.IsNotEmpty(node.sni)) if (Utils.IsNotEmpty(node.Sni))
{ {
server_name = node.sni; server_name = node.Sni;
} }
else if (Utils.IsNotEmpty(node.requestHost)) else if (Utils.IsNotEmpty(node.RequestHost))
{ {
server_name = Utils.String2List(node.requestHost)?.First(); server_name = Utils.String2List(node.RequestHost)?.First();
} }
var tls = new Tls4Sbox() var tls = new Tls4Sbox()
{ {
enabled = true, enabled = true,
server_name = server_name, server_name = server_name,
insecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.allowInsecure), insecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
alpn = node.GetAlpn(), alpn = node.GetAlpn(),
}; };
if (Utils.IsNotEmpty(node.fingerprint)) if (Utils.IsNotEmpty(node.Fingerprint))
{ {
tls.utls = new Utls4Sbox() tls.utls = new Utls4Sbox()
{ {
enabled = true, enabled = true,
fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.fingerprint fingerprint = node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.Fingerprint
}; };
} }
if (node.streamSecurity == Global.StreamSecurityReality) if (node.StreamSecurity == Global.StreamSecurityReality)
{ {
tls.reality = new Reality4Sbox() tls.reality = new Reality4Sbox()
{ {
enabled = true, enabled = true,
public_key = node.publicKey, public_key = node.PublicKey,
short_id = node.shortId short_id = node.ShortId
}; };
tls.insecure = false; tls.insecure = false;
} }
@ -787,43 +787,43 @@ namespace ServiceLib.Services.CoreConfig
{ {
case nameof(ETransport.h2): case nameof(ETransport.h2):
transport.type = nameof(ETransport.http); transport.type = nameof(ETransport.http);
transport.host = Utils.IsNullOrEmpty(node.requestHost) ? null : Utils.String2List(node.requestHost); transport.host = Utils.IsNullOrEmpty(node.RequestHost) ? null : Utils.String2List(node.RequestHost);
transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path; transport.path = Utils.IsNullOrEmpty(node.Path) ? null : node.Path;
break; break;
case nameof(ETransport.tcp): //http case nameof(ETransport.tcp): //http
if (node.headerType == Global.TcpHeaderHttp) if (node.HeaderType == Global.TcpHeaderHttp)
{ {
if (node.configType == EConfigType.Shadowsocks) if (node.ConfigType == EConfigType.Shadowsocks)
{ {
outbound.plugin = "obfs-local"; outbound.plugin = "obfs-local";
outbound.plugin_opts = $"obfs=http;obfs-host={node.requestHost};"; outbound.plugin_opts = $"obfs=http;obfs-host={node.RequestHost};";
} }
else else
{ {
transport.type = nameof(ETransport.http); transport.type = nameof(ETransport.http);
transport.host = Utils.IsNullOrEmpty(node.requestHost) ? null : Utils.String2List(node.requestHost); transport.host = Utils.IsNullOrEmpty(node.RequestHost) ? null : Utils.String2List(node.RequestHost);
transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path; transport.path = Utils.IsNullOrEmpty(node.Path) ? null : node.Path;
} }
} }
break; break;
case nameof(ETransport.ws): case nameof(ETransport.ws):
transport.type = nameof(ETransport.ws); transport.type = nameof(ETransport.ws);
transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path; transport.path = Utils.IsNullOrEmpty(node.Path) ? null : node.Path;
if (Utils.IsNotEmpty(node.requestHost)) if (Utils.IsNotEmpty(node.RequestHost))
{ {
transport.headers = new() transport.headers = new()
{ {
Host = node.requestHost Host = node.RequestHost
}; };
} }
break; break;
case nameof(ETransport.httpupgrade): case nameof(ETransport.httpupgrade):
transport.type = nameof(ETransport.httpupgrade); transport.type = nameof(ETransport.httpupgrade);
transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path; transport.path = Utils.IsNullOrEmpty(node.Path) ? null : node.Path;
transport.host = Utils.IsNullOrEmpty(node.requestHost) ? null : node.requestHost; transport.host = Utils.IsNullOrEmpty(node.RequestHost) ? null : node.RequestHost;
break; break;
@ -833,9 +833,9 @@ namespace ServiceLib.Services.CoreConfig
case nameof(ETransport.grpc): case nameof(ETransport.grpc):
transport.type = nameof(ETransport.grpc); transport.type = nameof(ETransport.grpc);
transport.service_name = node.path; transport.service_name = node.Path;
transport.idle_timeout = _config.GrpcItem.IdleTimeout.ToString("##s"); transport.idle_timeout = _config.GrpcItem.IdleTimeout?.ToString("##s");
transport.ping_timeout = _config.GrpcItem.HealthCheckTimeout.ToString("##s"); transport.ping_timeout = _config.GrpcItem.HealthCheckTimeout?.ToString("##s");
transport.permit_without_stream = _config.GrpcItem.PermitWithoutStream; transport.permit_without_stream = _config.GrpcItem.PermitWithoutStream;
break; break;
@ -856,13 +856,13 @@ namespace ServiceLib.Services.CoreConfig
private async Task<int> GenMoreOutbounds(ProfileItem node, SingboxConfig singboxConfig) private async Task<int> GenMoreOutbounds(ProfileItem node, SingboxConfig singboxConfig)
{ {
if (node.subid.IsNullOrEmpty()) if (node.Subid.IsNullOrEmpty())
{ {
return 0; return 0;
} }
try try
{ {
var subItem = await AppHandler.Instance.GetSubItem(node.subid); var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
if (subItem is null) if (subItem is null)
{ {
return 0; return 0;
@ -873,9 +873,9 @@ namespace ServiceLib.Services.CoreConfig
var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound); var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound);
//Previous proxy //Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.prevProfile); var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
if (prevNode is not null if (prevNode is not null
&& prevNode.configType != EConfigType.Custom) && prevNode.ConfigType != EConfigType.Custom)
{ {
var prevOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var prevOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
await GenOutbound(prevNode, prevOutbound); await GenOutbound(prevNode, prevOutbound);
@ -886,9 +886,9 @@ namespace ServiceLib.Services.CoreConfig
} }
//Next proxy //Next proxy
var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.nextProfile); var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.NextProfile);
if (nextNode is not null if (nextNode is not null
&& nextNode.configType != EConfigType.Custom) && nextNode.ConfigType != EConfigType.Custom)
{ {
var nextOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var nextOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
await GenOutbound(nextNode, nextOutbound); await GenOutbound(nextNode, nextOutbound);
@ -963,10 +963,10 @@ namespace ServiceLib.Services.CoreConfig
var routing = await ConfigHandler.GetDefaultRouting(_config); var routing = await ConfigHandler.GetDefaultRouting(_config);
if (routing != null) if (routing != null)
{ {
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.ruleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item in rules ?? []) foreach (var item in rules ?? [])
{ {
if (item.enabled) if (item.Enabled)
{ {
await GenRoutingUserRule(item, singboxConfig.route.rules); await GenRoutingUserRule(item, singboxConfig.route.rules);
} }
@ -978,7 +978,7 @@ namespace ServiceLib.Services.CoreConfig
var lockedItem = await ConfigHandler.GetLockedRoutingItem(_config); var lockedItem = await ConfigHandler.GetLockedRoutingItem(_config);
if (lockedItem != null) if (lockedItem != null)
{ {
var rules = JsonUtils.Deserialize<List<RulesItem>>(lockedItem.ruleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(lockedItem.RuleSet);
foreach (var item in rules ?? []) foreach (var item in rules ?? [])
{ {
await GenRoutingUserRule(item, singboxConfig.route.rules); await GenRoutingUserRule(item, singboxConfig.route.rules);
@ -1185,11 +1185,11 @@ namespace ServiceLib.Services.CoreConfig
var strDNS = string.Empty; var strDNS = string.Empty;
if (_config.TunModeItem.EnableTun) if (_config.TunModeItem.EnableTun)
{ {
strDNS = Utils.IsNullOrEmpty(item?.tunDNS) ? Utils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.tunDNS; strDNS = Utils.IsNullOrEmpty(item?.TunDNS) ? Utils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.TunDNS;
} }
else else
{ {
strDNS = Utils.IsNullOrEmpty(item?.normalDNS) ? Utils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.normalDNS; strDNS = Utils.IsNullOrEmpty(item?.NormalDNS) ? Utils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.NormalDNS;
} }
var dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(strDNS); var dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(strDNS);
@ -1218,9 +1218,9 @@ namespace ServiceLib.Services.CoreConfig
dns4Sbox.servers.Add(new() dns4Sbox.servers.Add(new()
{ {
tag = tag, tag = tag,
address = Utils.IsNullOrEmpty(dNSItem?.domainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : dNSItem?.domainDNSAddress, address = Utils.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.SingboxDomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
detour = Global.DirectTag, detour = Global.DirectTag,
strategy = Utils.IsNullOrEmpty(dNSItem?.domainStrategy4Freedom) ? null : dNSItem?.domainStrategy4Freedom, strategy = Utils.IsNullOrEmpty(dNSItem?.DomainStrategy4Freedom) ? null : dNSItem?.DomainStrategy4Freedom,
}); });
dns4Sbox.rules.Insert(0, new() dns4Sbox.rules.Insert(0, new()
{ {
@ -1248,12 +1248,12 @@ namespace ServiceLib.Services.CoreConfig
} }
//Tun2SocksAddress //Tun2SocksAddress
if (_config.TunModeItem.EnableTun && node?.configType == EConfigType.SOCKS && Utils.IsDomain(node?.sni)) if (_config.TunModeItem.EnableTun && node?.ConfigType == EConfigType.SOCKS && Utils.IsDomain(node?.Sni))
{ {
dns4Sbox.rules.Insert(0, new() dns4Sbox.rules.Insert(0, new()
{ {
server = tag, server = tag,
domain = [node?.sni] domain = [node?.Sni]
}); });
} }
@ -1337,9 +1337,9 @@ namespace ServiceLib.Services.CoreConfig
if (_config.RoutingBasicItem.EnableRoutingAdvanced) if (_config.RoutingBasicItem.EnableRoutingAdvanced)
{ {
var routing = await ConfigHandler.GetDefaultRouting(_config); var routing = await ConfigHandler.GetDefaultRouting(_config);
if (Utils.IsNotEmpty(routing.customRulesetPath4Singbox)) if (Utils.IsNotEmpty(routing.CustomRulesetPath4Singbox))
{ {
var result = Utils.LoadResource(routing.customRulesetPath4Singbox); var result = Utils.LoadResource(routing.CustomRulesetPath4Singbox);
if (Utils.IsNotEmpty(result)) if (Utils.IsNotEmpty(result))
{ {
customRulesets = (JsonUtils.Deserialize<List<Ruleset4Sbox>>(result) ?? []) customRulesets = (JsonUtils.Deserialize<List<Ruleset4Sbox>>(result) ?? [])

View File

@ -21,7 +21,7 @@ namespace ServiceLib.Services.CoreConfig
try try
{ {
if (node == null if (node == null
|| node.port <= 0) || node.Port <= 0)
{ {
ret.Msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return ret; return ret;
@ -109,36 +109,36 @@ namespace ServiceLib.Services.CoreConfig
var tagProxy = new List<string>(); var tagProxy = new List<string>();
foreach (var it in selecteds) foreach (var it in selecteds)
{ {
if (it.configType == EConfigType.Custom) if (it.ConfigType == EConfigType.Custom)
{ {
continue; continue;
} }
if (it.configType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard) if (it.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard)
{ {
continue; continue;
} }
if (it.port <= 0) if (it.Port <= 0)
{ {
continue; continue;
} }
var item = await AppHandler.Instance.GetProfileItem(it.indexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (item is null) if (item is null)
{ {
continue; continue;
} }
if (it.configType is EConfigType.VMess or EConfigType.VLESS) if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
{ {
if (Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id)) if (Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id))
{ {
continue; continue;
} }
} }
if (item.configType == EConfigType.Shadowsocks if (item.ConfigType == EConfigType.Shadowsocks
&& !Global.SsSecuritiesInSingbox.Contains(item.security)) && !Global.SsSecuritiesInSingbox.Contains(item.Security))
{ {
continue; continue;
} }
if (item.configType == EConfigType.VLESS && !Global.Flows.Contains(item.flow)) if (item.ConfigType == EConfigType.VLESS && !Global.Flows.Contains(item.Flow))
{ {
continue; continue;
} }
@ -256,7 +256,7 @@ namespace ServiceLib.Services.CoreConfig
var item = await AppHandler.Instance.GetProfileItem(it.IndexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS) if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
{ {
if (item is null || Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id)) if (item is null || Utils.IsNullOrEmpty(item.Id) || !Utils.IsGuidByParse(item.Id))
{ {
continue; continue;
} }
@ -303,19 +303,19 @@ namespace ServiceLib.Services.CoreConfig
{ {
continue; continue;
} }
if (item.configType == EConfigType.Shadowsocks if (item.ConfigType == EConfigType.Shadowsocks
&& !Global.SsSecuritiesInXray.Contains(item.security)) && !Global.SsSecuritiesInXray.Contains(item.Security))
{ {
continue; continue;
} }
if (item.configType == EConfigType.VLESS if (item.ConfigType == EConfigType.VLESS
&& !Global.Flows.Contains(item.flow)) && !Global.Flows.Contains(item.Flow))
{ {
continue; continue;
} }
if (it.ConfigType is EConfigType.VLESS or EConfigType.Trojan if (it.ConfigType is EConfigType.VLESS or EConfigType.Trojan
&& item.streamSecurity == Global.StreamSecurityReality && item.StreamSecurity == Global.StreamSecurityReality
&& item.publicKey.IsNullOrEmpty()) && item.PublicKey.IsNullOrEmpty())
{ {
continue; continue;
} }
@ -465,14 +465,14 @@ namespace ServiceLib.Services.CoreConfig
var routing = await ConfigHandler.GetDefaultRouting(_config); var routing = await ConfigHandler.GetDefaultRouting(_config);
if (routing != null) if (routing != null)
{ {
if (Utils.IsNotEmpty(routing.domainStrategy)) if (Utils.IsNotEmpty(routing.DomainStrategy))
{ {
v2rayConfig.routing.domainStrategy = routing.domainStrategy; v2rayConfig.routing.domainStrategy = routing.DomainStrategy;
} }
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.ruleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item in rules) foreach (var item in rules)
{ {
if (item.enabled) if (item.Enabled)
{ {
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item)); var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
await GenRoutingUserRule(item2, v2rayConfig); await GenRoutingUserRule(item2, v2rayConfig);
@ -485,7 +485,7 @@ namespace ServiceLib.Services.CoreConfig
var lockedItem = await ConfigHandler.GetLockedRoutingItem(_config); var lockedItem = await ConfigHandler.GetLockedRoutingItem(_config);
if (lockedItem != null) if (lockedItem != null)
{ {
var rules = JsonUtils.Deserialize<List<RulesItem>>(lockedItem.ruleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(lockedItem.RuleSet);
foreach (var item in rules) foreach (var item in rules)
{ {
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item)); var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
@ -584,7 +584,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
try try
{ {
switch (node.configType) switch (node.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
{ {
@ -598,8 +598,8 @@ namespace ServiceLib.Services.CoreConfig
{ {
vnextItem = outbound.settings.vnext[0]; vnextItem = outbound.settings.vnext[0];
} }
vnextItem.address = node.address; vnextItem.address = node.Address;
vnextItem.port = node.port; vnextItem.port = node.Port;
UsersItem4Ray usersItem; UsersItem4Ray usersItem;
if (vnextItem.users.Count <= 0) if (vnextItem.users.Count <= 0)
@ -612,12 +612,12 @@ namespace ServiceLib.Services.CoreConfig
usersItem = vnextItem.users[0]; usersItem = vnextItem.users[0];
} }
//远程服务器用户ID //远程服务器用户ID
usersItem.id = node.id; usersItem.id = node.Id;
usersItem.alterId = node.alterId; usersItem.alterId = node.AlterId;
usersItem.email = Global.UserEMail; usersItem.email = Global.UserEMail;
if (Global.VmessSecurities.Contains(node.security)) if (Global.VmessSecurities.Contains(node.Security))
{ {
usersItem.security = node.security; usersItem.security = node.Security;
} }
else else
{ {
@ -641,10 +641,10 @@ namespace ServiceLib.Services.CoreConfig
{ {
serversItem = outbound.settings.servers[0]; serversItem = outbound.settings.servers[0];
} }
serversItem.address = node.address; serversItem.address = node.Address;
serversItem.port = node.port; serversItem.port = node.Port;
serversItem.password = node.id; serversItem.password = node.Id;
serversItem.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : "none"; serversItem.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.Security) ? node.Security : "none";
serversItem.ota = false; serversItem.ota = false;
serversItem.level = 1; serversItem.level = 1;
@ -667,18 +667,18 @@ namespace ServiceLib.Services.CoreConfig
{ {
serversItem = outbound.settings.servers[0]; serversItem = outbound.settings.servers[0];
} }
serversItem.address = node.address; serversItem.address = node.Address;
serversItem.port = node.port; serversItem.port = node.Port;
serversItem.method = null; serversItem.method = null;
serversItem.password = null; serversItem.password = null;
if (Utils.IsNotEmpty(node.security) if (Utils.IsNotEmpty(node.Security)
&& Utils.IsNotEmpty(node.id)) && Utils.IsNotEmpty(node.Id))
{ {
SocksUsersItem4Ray socksUsersItem = new() SocksUsersItem4Ray socksUsersItem = new()
{ {
user = node.security, user = node.Security,
pass = node.id, pass = node.Id,
level = 1 level = 1
}; };
@ -702,8 +702,8 @@ namespace ServiceLib.Services.CoreConfig
{ {
vnextItem = outbound.settings.vnext[0]; vnextItem = outbound.settings.vnext[0];
} }
vnextItem.address = node.address; vnextItem.address = node.Address;
vnextItem.port = node.port; vnextItem.port = node.Port;
UsersItem4Ray usersItem; UsersItem4Ray usersItem;
if (vnextItem.users.Count <= 0) if (vnextItem.users.Count <= 0)
@ -715,23 +715,23 @@ namespace ServiceLib.Services.CoreConfig
{ {
usersItem = vnextItem.users[0]; usersItem = vnextItem.users[0];
} }
usersItem.id = node.id; usersItem.id = node.Id;
usersItem.email = Global.UserEMail; usersItem.email = Global.UserEMail;
usersItem.encryption = node.security; usersItem.encryption = node.Security;
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled); await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
if (node.streamSecurity == Global.StreamSecurityReality if (node.StreamSecurity == Global.StreamSecurityReality
|| node.streamSecurity == Global.StreamSecurity) || node.StreamSecurity == Global.StreamSecurity)
{ {
if (Utils.IsNotEmpty(node.flow)) if (Utils.IsNotEmpty(node.Flow))
{ {
usersItem.flow = node.flow; usersItem.flow = node.Flow;
await GenOutboundMux(node, outbound, false); await GenOutboundMux(node, outbound, false);
} }
} }
if (node.streamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.flow)) if (node.StreamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.Flow))
{ {
await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled); await GenOutboundMux(node, outbound, _config.CoreBasicItem.MuxEnabled);
} }
@ -751,9 +751,9 @@ namespace ServiceLib.Services.CoreConfig
{ {
serversItem = outbound.settings.servers[0]; serversItem = outbound.settings.servers[0];
} }
serversItem.address = node.address; serversItem.address = node.Address;
serversItem.port = node.port; serversItem.port = node.Port;
serversItem.password = node.id; serversItem.password = node.Id;
serversItem.ota = false; serversItem.ota = false;
serversItem.level = 1; serversItem.level = 1;
@ -765,7 +765,7 @@ namespace ServiceLib.Services.CoreConfig
} }
} }
outbound.protocol = Global.ProtocolTypes[node.configType]; outbound.protocol = Global.ProtocolTypes[node.ConfigType];
await GenBoundStreamSettings(node, outbound.streamSettings); await GenBoundStreamSettings(node, outbound.streamSettings);
} }
catch (Exception ex) catch (Exception ex)
@ -804,8 +804,8 @@ namespace ServiceLib.Services.CoreConfig
try try
{ {
streamSettings.network = node.GetNetwork(); streamSettings.network = node.GetNetwork();
string host = node.requestHost.TrimEx(); string host = node.RequestHost.TrimEx();
string sni = node.sni; string sni = node.Sni;
string useragent = ""; string useragent = "";
if (!_config.CoreBasicItem.DefUserAgent.IsNullOrEmpty()) if (!_config.CoreBasicItem.DefUserAgent.IsNullOrEmpty())
{ {
@ -820,15 +820,15 @@ namespace ServiceLib.Services.CoreConfig
} }
//if tls //if tls
if (node.streamSecurity == Global.StreamSecurity) if (node.StreamSecurity == Global.StreamSecurity)
{ {
streamSettings.security = node.streamSecurity; streamSettings.security = node.StreamSecurity;
TlsSettings4Ray tlsSettings = new() TlsSettings4Ray tlsSettings = new()
{ {
allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.allowInsecure), allowInsecure = Utils.ToBool(node.AllowInsecure.IsNullOrEmpty() ? _config.CoreBasicItem.DefAllowInsecure.ToString().ToLower() : node.AllowInsecure),
alpn = node.GetAlpn(), alpn = node.GetAlpn(),
fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.fingerprint fingerprint = node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.Fingerprint
}; };
if (Utils.IsNotEmpty(sni)) if (Utils.IsNotEmpty(sni))
{ {
@ -842,17 +842,17 @@ namespace ServiceLib.Services.CoreConfig
} }
//if Reality //if Reality
if (node.streamSecurity == Global.StreamSecurityReality) if (node.StreamSecurity == Global.StreamSecurityReality)
{ {
streamSettings.security = node.streamSecurity; streamSettings.security = node.StreamSecurity;
TlsSettings4Ray realitySettings = new() TlsSettings4Ray realitySettings = new()
{ {
fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.fingerprint, fingerprint = node.Fingerprint.IsNullOrEmpty() ? _config.CoreBasicItem.DefFingerprint : node.Fingerprint,
serverName = sni, serverName = sni,
publicKey = node.publicKey, publicKey = node.PublicKey,
shortId = node.shortId, shortId = node.ShortId,
spiderX = node.spiderX, spiderX = node.SpiderX,
show = false, show = false,
}; };
@ -877,11 +877,11 @@ namespace ServiceLib.Services.CoreConfig
kcpSettings.writeBufferSize = _config.KcpItem.WriteBufferSize; kcpSettings.writeBufferSize = _config.KcpItem.WriteBufferSize;
kcpSettings.header = new Header4Ray kcpSettings.header = new Header4Ray
{ {
type = node.headerType type = node.HeaderType
}; };
if (Utils.IsNotEmpty(node.path)) if (Utils.IsNotEmpty(node.Path))
{ {
kcpSettings.seed = node.path; kcpSettings.seed = node.Path;
} }
streamSettings.kcpSettings = kcpSettings; streamSettings.kcpSettings = kcpSettings;
break; break;
@ -889,7 +889,7 @@ namespace ServiceLib.Services.CoreConfig
case nameof(ETransport.ws): case nameof(ETransport.ws):
WsSettings4Ray wsSettings = new(); WsSettings4Ray wsSettings = new();
wsSettings.headers = new Headers4Ray(); wsSettings.headers = new Headers4Ray();
string path = node.path; string path = node.Path;
if (Utils.IsNotEmpty(host)) if (Utils.IsNotEmpty(host))
{ {
wsSettings.headers.Host = host; wsSettings.headers.Host = host;
@ -909,9 +909,9 @@ namespace ServiceLib.Services.CoreConfig
case nameof(ETransport.httpupgrade): case nameof(ETransport.httpupgrade):
HttpupgradeSettings4Ray httpupgradeSettings = new(); HttpupgradeSettings4Ray httpupgradeSettings = new();
if (Utils.IsNotEmpty(node.path)) if (Utils.IsNotEmpty(node.Path))
{ {
httpupgradeSettings.path = node.path; httpupgradeSettings.path = node.Path;
} }
if (Utils.IsNotEmpty(host)) if (Utils.IsNotEmpty(host))
{ {
@ -928,9 +928,9 @@ namespace ServiceLib.Services.CoreConfig
maxConcurrentUploads = 10 maxConcurrentUploads = 10
}; };
if (Utils.IsNotEmpty(node.path)) if (Utils.IsNotEmpty(node.Path))
{ {
splithttpSettings.path = node.path; splithttpSettings.path = node.Path;
} }
if (Utils.IsNotEmpty(host)) if (Utils.IsNotEmpty(host))
{ {
@ -947,7 +947,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
httpSettings.host = Utils.String2List(host); httpSettings.host = Utils.String2List(host);
} }
httpSettings.path = node.path; httpSettings.path = node.Path;
streamSettings.httpSettings = httpSettings; streamSettings.httpSettings = httpSettings;
@ -957,14 +957,14 @@ namespace ServiceLib.Services.CoreConfig
QuicSettings4Ray quicsettings = new() QuicSettings4Ray quicsettings = new()
{ {
security = host, security = host,
key = node.path, key = node.Path,
header = new Header4Ray header = new Header4Ray
{ {
type = node.headerType type = node.HeaderType
} }
}; };
streamSettings.quicSettings = quicsettings; streamSettings.quicSettings = quicsettings;
if (node.streamSecurity == Global.StreamSecurity) if (node.StreamSecurity == Global.StreamSecurity)
{ {
if (Utils.IsNotEmpty(sni)) if (Utils.IsNotEmpty(sni))
{ {
@ -972,7 +972,7 @@ namespace ServiceLib.Services.CoreConfig
} }
else else
{ {
streamSettings.tlsSettings.serverName = node.address; streamSettings.tlsSettings.serverName = node.Address;
} }
} }
break; break;
@ -981,8 +981,8 @@ namespace ServiceLib.Services.CoreConfig
GrpcSettings4Ray grpcSettings = new() GrpcSettings4Ray grpcSettings = new()
{ {
authority = Utils.IsNullOrEmpty(host) ? null : host, authority = Utils.IsNullOrEmpty(host) ? null : host,
serviceName = node.path, serviceName = node.Path,
multiMode = node.headerType == Global.GrpcMultiMode, multiMode = node.HeaderType == Global.GrpcMultiMode,
idle_timeout = _config.GrpcItem.IdleTimeout, idle_timeout = _config.GrpcItem.IdleTimeout,
health_check_timeout = _config.GrpcItem.HealthCheckTimeout, health_check_timeout = _config.GrpcItem.HealthCheckTimeout,
permit_without_stream = _config.GrpcItem.PermitWithoutStream, permit_without_stream = _config.GrpcItem.PermitWithoutStream,
@ -993,13 +993,13 @@ namespace ServiceLib.Services.CoreConfig
default: default:
//tcp //tcp
if (node.headerType == Global.TcpHeaderHttp) if (node.HeaderType == Global.TcpHeaderHttp)
{ {
TcpSettings4Ray tcpSettings = new() TcpSettings4Ray tcpSettings = new()
{ {
header = new Header4Ray header = new Header4Ray
{ {
type = node.headerType type = node.HeaderType
} }
}; };
@ -1012,9 +1012,9 @@ namespace ServiceLib.Services.CoreConfig
request = request.Replace("$requestUserAgent$", $"\"{useragent}\""); request = request.Replace("$requestUserAgent$", $"\"{useragent}\"");
//Path //Path
string pathHttp = @"/"; string pathHttp = @"/";
if (Utils.IsNotEmpty(node.path)) if (Utils.IsNotEmpty(node.Path))
{ {
string[] arrPath = node.path.Split(','); string[] arrPath = node.Path.Split(',');
pathHttp = string.Join("\",\"", arrPath); pathHttp = string.Join("\",\"", arrPath);
} }
request = request.Replace("$requestPath$", $"\"{pathHttp}\""); request = request.Replace("$requestPath$", $"\"{pathHttp}\"");
@ -1037,8 +1037,8 @@ namespace ServiceLib.Services.CoreConfig
try try
{ {
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray); var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
var normalDNS = item?.normalDNS; var normalDNS = item?.NormalDNS;
var domainStrategy4Freedom = item?.domainStrategy4Freedom; var domainStrategy4Freedom = item?.DomainStrategy4Freedom;
if (Utils.IsNullOrEmpty(normalDNS)) if (Utils.IsNullOrEmpty(normalDNS))
{ {
normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName); normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName);
@ -1066,7 +1066,7 @@ namespace ServiceLib.Services.CoreConfig
} }
// 追加至 dns 设置 // 追加至 dns 设置
if (item.useSystemHosts) if (item.UseSystemHosts)
{ {
var systemHosts = Utils.GetSystemHosts(); var systemHosts = Utils.GetSystemHosts();
if (systemHosts.Count > 0) if (systemHosts.Count > 0)
@ -1102,12 +1102,12 @@ namespace ServiceLib.Services.CoreConfig
var servers = dns["servers"]; var servers = dns["servers"];
if (servers != null) if (servers != null)
{ {
if (Utils.IsDomain(node.address)) if (Utils.IsDomain(node.Address))
{ {
var dnsServer = new DnsServer4Ray() var dnsServer = new DnsServer4Ray()
{ {
address = Utils.IsNullOrEmpty(dNSItem?.domainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.domainDNSAddress, address = Utils.IsNullOrEmpty(dNSItem?.DomainDNSAddress) ? Global.DomainDNSAddress.FirstOrDefault() : dNSItem?.DomainDNSAddress,
domains = [node.address] domains = [node.Address]
}; };
servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer)); servers.AsArray().Add(JsonUtils.SerializeToNode(dnsServer));
} }
@ -1194,13 +1194,13 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
if (node.subid.IsNullOrEmpty()) if (node.Subid.IsNullOrEmpty())
{ {
return 0; return 0;
} }
try try
{ {
var subItem = await AppHandler.Instance.GetSubItem(node.subid); var subItem = await AppHandler.Instance.GetSubItem(node.Subid);
if (subItem is null) if (subItem is null)
{ {
return 0; return 0;
@ -1211,12 +1211,12 @@ namespace ServiceLib.Services.CoreConfig
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound); var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
//Previous proxy //Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.prevProfile); var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
if (prevNode is not null if (prevNode is not null
&& prevNode.configType != EConfigType.Custom && prevNode.ConfigType != EConfigType.Custom
&& prevNode.configType != EConfigType.Hysteria2 && prevNode.ConfigType != EConfigType.Hysteria2
&& prevNode.configType != EConfigType.TUIC && prevNode.ConfigType != EConfigType.TUIC
&& prevNode.configType != EConfigType.WireGuard) && prevNode.ConfigType != EConfigType.WireGuard)
{ {
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound); var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
await GenOutbound(prevNode, prevOutbound); await GenOutbound(prevNode, prevOutbound);
@ -1230,12 +1230,12 @@ namespace ServiceLib.Services.CoreConfig
} }
//Next proxy //Next proxy
var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.nextProfile); var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.NextProfile);
if (nextNode is not null if (nextNode is not null
&& nextNode.configType != EConfigType.Custom && nextNode.ConfigType != EConfigType.Custom
&& nextNode.configType != EConfigType.Hysteria2 && nextNode.ConfigType != EConfigType.Hysteria2
&& nextNode.configType != EConfigType.TUIC && nextNode.ConfigType != EConfigType.TUIC
&& nextNode.configType != EConfigType.WireGuard) && nextNode.ConfigType != EConfigType.WireGuard)
{ {
var nextOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound); var nextOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
await GenOutbound(nextNode, nextOutbound); await GenOutbound(nextNode, nextOutbound);

View File

@ -22,20 +22,20 @@ namespace ServiceLib.Services
_selecteds = new List<ServerTestItem>(); _selecteds = new List<ServerTestItem>();
foreach (var it in selecteds) foreach (var it in selecteds)
{ {
if (it.configType == EConfigType.Custom) if (it.ConfigType == EConfigType.Custom)
{ {
continue; continue;
} }
if (it.port <= 0) if (it.Port <= 0)
{ {
continue; continue;
} }
_selecteds.Add(new ServerTestItem() _selecteds.Add(new ServerTestItem()
{ {
IndexId = it.indexId, IndexId = it.IndexId,
Address = it.address, Address = it.Address,
Port = it.port, Port = it.Port,
ConfigType = it.configType ConfigType = it.ConfigType
}); });
} }
//clear test result //clear test result

View File

@ -122,11 +122,11 @@ namespace ServiceLib.Services
foreach (var item in subItem) foreach (var item in subItem)
{ {
string id = item.id.TrimEx(); string id = item.Id.TrimEx();
string url = item.url.TrimEx(); string url = item.Url.TrimEx();
string userAgent = item.userAgent.TrimEx(); string userAgent = item.UserAgent.TrimEx();
string hashCode = $"{item.remarks}->"; string hashCode = $"{item.Remarks}->";
if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || Utils.IsNotEmpty(subId) && item.id != subId) if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || Utils.IsNotEmpty(subId) && item.Id != subId)
{ {
//_updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgNoValidSubscription}"); //_updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgNoValidSubscription}");
continue; continue;
@ -135,7 +135,7 @@ namespace ServiceLib.Services
{ {
continue; continue;
} }
if (item.enabled == false) if (item.Enabled == false)
{ {
_updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgSkipSubscriptionUpdate}"); _updateFunc?.Invoke(false, $"{hashCode}{ResUI.MsgSkipSubscriptionUpdate}");
continue; continue;
@ -152,13 +152,13 @@ namespace ServiceLib.Services
//one url //one url
url = Utils.GetPunycode(url); url = Utils.GetPunycode(url);
//convert //convert
if (Utils.IsNotEmpty(item.convertTarget)) if (Utils.IsNotEmpty(item.ConvertTarget))
{ {
var subConvertUrl = Utils.IsNullOrEmpty(config.ConstItem.SubConvertUrl) ? Global.SubConvertUrls.FirstOrDefault() : config.ConstItem.SubConvertUrl; var subConvertUrl = Utils.IsNullOrEmpty(config.ConstItem.SubConvertUrl) ? Global.SubConvertUrls.FirstOrDefault() : config.ConstItem.SubConvertUrl;
url = string.Format(subConvertUrl!, Utils.UrlEncode(url)); url = string.Format(subConvertUrl!, Utils.UrlEncode(url));
if (!url.Contains("target=")) if (!url.Contains("target="))
{ {
url += string.Format("&target={0}", item.convertTarget); url += string.Format("&target={0}", item.ConvertTarget);
} }
if (!url.Contains("config=")) if (!url.Contains("config="))
{ {
@ -172,14 +172,14 @@ namespace ServiceLib.Services
} }
//more url //more url
if (Utils.IsNullOrEmpty(item.convertTarget) && Utils.IsNotEmpty(item.moreUrl.TrimEx())) if (Utils.IsNullOrEmpty(item.ConvertTarget) && Utils.IsNotEmpty(item.MoreUrl.TrimEx()))
{ {
if (Utils.IsNotEmpty(result) && Utils.IsBase64String(result)) if (Utils.IsNotEmpty(result) && Utils.IsBase64String(result))
{ {
result = Utils.Base64Decode(result); result = Utils.Base64Decode(result);
} }
var lstUrl = item.moreUrl.TrimEx().Split(",") ?? []; var lstUrl = item.MoreUrl.TrimEx().Split(",") ?? [];
foreach (var it in lstUrl) foreach (var it in lstUrl)
{ {
var url2 = Utils.GetPunycode(it); var url2 = Utils.GetPunycode(it);
@ -480,7 +480,7 @@ namespace ServiceLib.Services
var routingItems = await AppHandler.Instance.RoutingItems(); var routingItems = await AppHandler.Instance.RoutingItems();
foreach (var routing in routingItems) foreach (var routing in routingItems)
{ {
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.ruleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
foreach (var item in rules ?? []) foreach (var item in rules ?? [])
{ {
foreach (var ip in item.ip ?? []) foreach (var ip in item.ip ?? [])

View File

@ -35,25 +35,25 @@ namespace ServiceLib.ViewModels
await SaveServerAsync(); await SaveServerAsync();
}); });
SelectedSource = profileItem.indexId.IsNullOrEmpty() ? profileItem : JsonUtils.DeepCopy(profileItem); SelectedSource = profileItem.IndexId.IsNullOrEmpty() ? profileItem : JsonUtils.DeepCopy(profileItem);
CoreType = SelectedSource?.coreType?.ToString(); CoreType = SelectedSource?.CoreType?.ToString();
} }
private async Task SaveServerAsync() private async Task SaveServerAsync()
{ {
string remarks = SelectedSource.remarks; string remarks = SelectedSource.Remarks;
if (Utils.IsNullOrEmpty(remarks)) if (Utils.IsNullOrEmpty(remarks))
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks);
return; return;
} }
if (Utils.IsNullOrEmpty(SelectedSource.address)) if (Utils.IsNullOrEmpty(SelectedSource.Address))
{ {
NoticeHandler.Instance.Enqueue(ResUI.FillServerAddressCustom); NoticeHandler.Instance.Enqueue(ResUI.FillServerAddressCustom);
return; return;
} }
SelectedSource.coreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType); SelectedSource.CoreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType);
if (await ConfigHandler.EditCustomServer(_config, SelectedSource) == 0) if (await ConfigHandler.EditCustomServer(_config, SelectedSource) == 0)
{ {
@ -73,13 +73,13 @@ namespace ServiceLib.ViewModels
return; return;
} }
var item = await AppHandler.Instance.GetProfileItem(SelectedSource.indexId); var item = await AppHandler.Instance.GetProfileItem(SelectedSource.IndexId);
item ??= SelectedSource; item ??= SelectedSource;
item.address = fileName; item.Address = fileName;
if (await ConfigHandler.AddCustomServer(_config, item, false) == 0) if (await ConfigHandler.AddCustomServer(_config, item, false) == 0)
{ {
NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedCustomServer); NoticeHandler.Instance.Enqueue(ResUI.SuccessfullyImportedCustomServer);
if (Utils.IsNotEmpty(item.indexId)) if (Utils.IsNotEmpty(item.IndexId))
{ {
SelectedSource = JsonUtils.DeepCopy(item); SelectedSource = JsonUtils.DeepCopy(item);
} }
@ -93,7 +93,7 @@ namespace ServiceLib.ViewModels
private async Task EditServer() private async Task EditServer()
{ {
var address = SelectedSource.address; var address = SelectedSource.Address;
if (Utils.IsNullOrEmpty(address)) if (Utils.IsNullOrEmpty(address))
{ {
NoticeHandler.Instance.Enqueue(ResUI.FillServerAddressCustom); NoticeHandler.Instance.Enqueue(ResUI.FillServerAddressCustom);

View File

@ -24,64 +24,64 @@ namespace ServiceLib.ViewModels
await SaveServerAsync(); await SaveServerAsync();
}); });
if (profileItem.indexId.IsNullOrEmpty()) if (profileItem.IndexId.IsNullOrEmpty())
{ {
profileItem.network = Global.DefaultNetwork; profileItem.Network = Global.DefaultNetwork;
profileItem.headerType = Global.None; profileItem.HeaderType = Global.None;
profileItem.requestHost = ""; profileItem.RequestHost = "";
profileItem.streamSecurity = ""; profileItem.StreamSecurity = "";
SelectedSource = profileItem; SelectedSource = profileItem;
} }
else else
{ {
SelectedSource = JsonUtils.DeepCopy(profileItem); SelectedSource = JsonUtils.DeepCopy(profileItem);
} }
CoreType = SelectedSource?.coreType?.ToString(); CoreType = SelectedSource?.CoreType?.ToString();
} }
private async Task SaveServerAsync() private async Task SaveServerAsync()
{ {
if (Utils.IsNullOrEmpty(SelectedSource.remarks)) if (Utils.IsNullOrEmpty(SelectedSource.Remarks))
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks);
return; return;
} }
if (Utils.IsNullOrEmpty(SelectedSource.address)) if (Utils.IsNullOrEmpty(SelectedSource.Address))
{ {
NoticeHandler.Instance.Enqueue(ResUI.FillServerAddress); NoticeHandler.Instance.Enqueue(ResUI.FillServerAddress);
return; return;
} }
var port = SelectedSource.port.ToString(); var port = SelectedSource.Port.ToString();
if (Utils.IsNullOrEmpty(port) || !Utils.IsNumeric(port) if (Utils.IsNullOrEmpty(port) || !Utils.IsNumeric(port)
|| SelectedSource.port <= 0 || SelectedSource.port >= Global.MaxPort) || SelectedSource.Port <= 0 || SelectedSource.Port >= Global.MaxPort)
{ {
NoticeHandler.Instance.Enqueue(ResUI.FillCorrectServerPort); NoticeHandler.Instance.Enqueue(ResUI.FillCorrectServerPort);
return; return;
} }
if (SelectedSource.configType == EConfigType.Shadowsocks) if (SelectedSource.ConfigType == EConfigType.Shadowsocks)
{ {
if (Utils.IsNullOrEmpty(SelectedSource.id)) if (Utils.IsNullOrEmpty(SelectedSource.Id))
{ {
NoticeHandler.Instance.Enqueue(ResUI.FillPassword); NoticeHandler.Instance.Enqueue(ResUI.FillPassword);
return; return;
} }
if (Utils.IsNullOrEmpty(SelectedSource.security)) if (Utils.IsNullOrEmpty(SelectedSource.Security))
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectEncryption); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectEncryption);
return; return;
} }
} }
if (SelectedSource.configType != EConfigType.SOCKS if (SelectedSource.ConfigType != EConfigType.SOCKS
&& SelectedSource.configType != EConfigType.HTTP) && SelectedSource.ConfigType != EConfigType.HTTP)
{ {
if (Utils.IsNullOrEmpty(SelectedSource.id)) if (Utils.IsNullOrEmpty(SelectedSource.Id))
{ {
NoticeHandler.Instance.Enqueue(ResUI.FillUUID); NoticeHandler.Instance.Enqueue(ResUI.FillUUID);
return; return;
} }
} }
SelectedSource.coreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType); SelectedSource.CoreType = CoreType.IsNullOrEmpty() ? null : (ECoreType)Enum.Parse(typeof(ECoreType), CoreType);
if (await ConfigHandler.AddServer(_config, SelectedSource) == 0) if (await ConfigHandler.AddServer(_config, SelectedSource) == 0)
{ {

View File

@ -273,7 +273,7 @@ namespace ServiceLib.ViewModels
var lstDetails = new List<ClashProxyModel>(); var lstDetails = new List<ClashProxyModel>();
foreach (var item in proxy.all) foreach (var item in proxy.all)
{ {
var isActive = item == proxy.now; var IsActive = item == proxy.now;
var proxy2 = TryGetProxy(item); var proxy2 = TryGetProxy(item);
if (proxy2 == null) if (proxy2 == null)
@ -288,7 +288,7 @@ namespace ServiceLib.ViewModels
lstDetails.Add(new ClashProxyModel() lstDetails.Add(new ClashProxyModel()
{ {
isActive = isActive, IsActive = IsActive,
name = item, name = item,
type = proxy2.type, type = proxy2.type,
delay = delay <= 0 ? _delayTimeout : delay, delay = delay <= 0 ? _delayTimeout : delay,

View File

@ -46,16 +46,16 @@ namespace ServiceLib.ViewModels
private async Task Init() private async Task Init()
{ {
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray); var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
useSystemHosts = item.useSystemHosts; useSystemHosts = item.UseSystemHosts;
domainStrategy4Freedom = item?.domainStrategy4Freedom ?? string.Empty; domainStrategy4Freedom = item?.DomainStrategy4Freedom ?? string.Empty;
domainDNSAddress = item?.domainDNSAddress ?? string.Empty; domainDNSAddress = item?.DomainDNSAddress ?? string.Empty;
normalDNS = item?.normalDNS ?? string.Empty; normalDNS = item?.NormalDNS ?? string.Empty;
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box); var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
domainStrategy4Freedom2 = item2?.domainStrategy4Freedom ?? string.Empty; domainStrategy4Freedom2 = item2?.DomainStrategy4Freedom ?? string.Empty;
domainDNSAddress2 = item2?.domainDNSAddress ?? string.Empty; domainDNSAddress2 = item2?.DomainDNSAddress ?? string.Empty;
normalDNS2 = item2?.normalDNS ?? string.Empty; normalDNS2 = item2?.NormalDNS ?? string.Empty;
tunDNS2 = item2?.tunDNS ?? string.Empty; tunDNS2 = item2?.TunDNS ?? string.Empty;
} }
private async Task SaveSettingAsync() private async Task SaveSettingAsync()
@ -95,17 +95,17 @@ namespace ServiceLib.ViewModels
} }
var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray); var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
item.domainStrategy4Freedom = domainStrategy4Freedom; item.DomainStrategy4Freedom = domainStrategy4Freedom;
item.domainDNSAddress = domainDNSAddress; item.DomainDNSAddress = domainDNSAddress;
item.useSystemHosts = useSystemHosts; item.UseSystemHosts = useSystemHosts;
item.normalDNS = normalDNS; item.NormalDNS = normalDNS;
await ConfigHandler.SaveDNSItems(_config, item); await ConfigHandler.SaveDNSItems(_config, item);
var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box); var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
item2.domainStrategy4Freedom = domainStrategy4Freedom2; item2.DomainStrategy4Freedom = domainStrategy4Freedom2;
item2.domainDNSAddress = domainDNSAddress2; item2.DomainDNSAddress = domainDNSAddress2;
item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2)); item2.NormalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2));
item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); ; item2.TunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); ;
await ConfigHandler.SaveDNSItems(_config, item2); await ConfigHandler.SaveDNSItems(_config, item2);
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);

View File

@ -351,9 +351,9 @@ namespace ServiceLib.ViewModels
{ {
ProfileItem item = new() ProfileItem item = new()
{ {
subid = _config.SubIndexId, Subid = _config.SubIndexId,
configType = eConfigType, ConfigType = eConfigType,
isSub = false, IsSub = false,
}; };
bool? ret = false; bool? ret = false;
@ -368,7 +368,7 @@ namespace ServiceLib.ViewModels
if (ret == true) if (ret == true)
{ {
RefreshServers(); RefreshServers();
if (item.indexId == _config.IndexId) if (item.IndexId == _config.IndexId)
{ {
await Reload(); await Reload();
} }

View File

@ -103,15 +103,15 @@ namespace ServiceLib.ViewModels
var canEditRemove = this.WhenAnyValue( var canEditRemove = this.WhenAnyValue(
x => x.SelectedProfile, x => x.SelectedProfile,
selectedSource => selectedSource != null && !selectedSource.indexId.IsNullOrEmpty()); selectedSource => selectedSource != null && !selectedSource.IndexId.IsNullOrEmpty());
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedSub, x => x.SelectedSub,
y => y != null && !y.remarks.IsNullOrEmpty() && _config.SubIndexId != y.id) y => y != null && !y.Remarks.IsNullOrEmpty() && _config.SubIndexId != y.Id)
.Subscribe(async c => await SubSelectedChangedAsync(c)); .Subscribe(async c => await SubSelectedChangedAsync(c));
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedMoveToGroup, x => x.SelectedMoveToGroup,
y => y != null && !y.remarks.IsNullOrEmpty()) y => y != null && !y.Remarks.IsNullOrEmpty())
.Subscribe(async c => await MoveToGroup(c)); .Subscribe(async c => await MoveToGroup(c));
this.WhenAnyValue( this.WhenAnyValue(
@ -195,7 +195,7 @@ namespace ServiceLib.ViewModels
}, canEditRemove); }, canEditRemove);
SortServerResultCmd = ReactiveCommand.CreateFromTask(async () => SortServerResultCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await SortServer(EServerColName.delayVal.ToString()); await SortServer(EServerColName.DelayVal.ToString());
}); });
//servers export //servers export
Export2ClientConfigCmd = ReactiveCommand.CreateFromTask(async () => Export2ClientConfigCmd = ReactiveCommand.CreateFromTask(async () =>
@ -273,18 +273,18 @@ namespace ServiceLib.ViewModels
NoticeHandler.Instance.Enqueue(result.Delay); NoticeHandler.Instance.Enqueue(result.Delay);
return; return;
} }
var item = _profileItems.Where(it => it.indexId == result.IndexId).FirstOrDefault(); var item = _profileItems.Where(it => it.IndexId == result.IndexId).FirstOrDefault();
if (item != null) if (item != null)
{ {
if (Utils.IsNotEmpty(result.Delay)) if (Utils.IsNotEmpty(result.Delay))
{ {
int.TryParse(result.Delay, out int temp); int.TryParse(result.Delay, out int temp);
item.delay = temp; item.Delay = temp;
item.delayVal = $"{result.Delay} {Global.DelayUnit}"; item.DelayVal = $"{result.Delay} {Global.DelayUnit}";
} }
if (Utils.IsNotEmpty(result.Speed)) if (Utils.IsNotEmpty(result.Speed))
{ {
item.speedVal = $"{result.Speed} {Global.SpeedUnit}"; item.SpeedVal = $"{result.Speed} {Global.SpeedUnit}";
} }
_profileItems.Replace(item, JsonUtils.DeepCopy(item)); _profileItems.Replace(item, JsonUtils.DeepCopy(item));
} }
@ -294,15 +294,15 @@ namespace ServiceLib.ViewModels
{ {
try try
{ {
var item = _profileItems.Where(it => it.indexId == update.indexId).FirstOrDefault(); var item = _profileItems.Where(it => it.IndexId == update.IndexId).FirstOrDefault();
if (item != null) if (item != null)
{ {
item.todayDown = Utils.HumanFy(update.todayDown); item.TodayDown = Utils.HumanFy(update.TodayDown);
item.todayUp = Utils.HumanFy(update.todayUp); item.TodayUp = Utils.HumanFy(update.TodayUp);
item.totalDown = Utils.HumanFy(update.totalDown); item.TotalDown = Utils.HumanFy(update.TotalDown);
item.totalUp = Utils.HumanFy(update.totalUp); item.TotalUp = Utils.HumanFy(update.TotalUp);
if (SelectedProfile?.indexId == item.indexId) if (SelectedProfile?.IndexId == item.IndexId)
{ {
var temp = JsonUtils.DeepCopy(item); var temp = JsonUtils.DeepCopy(item);
_profileItems.Replace(item, temp); _profileItems.Replace(item, temp);
@ -334,7 +334,7 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
_config.SubIndexId = SelectedSub?.id; _config.SubIndexId = SelectedSub?.Id;
RefreshServers(); RefreshServers();
@ -368,7 +368,7 @@ namespace ServiceLib.ViewModels
_profileItems.AddRange(lstModel); _profileItems.AddRange(lstModel);
if (lstModel.Count > 0) if (lstModel.Count > 0)
{ {
var selected = lstModel.FirstOrDefault(t => t.indexId == _config.IndexId); var selected = lstModel.FirstOrDefault(t => t.IndexId == _config.IndexId);
if (selected != null) if (selected != null)
{ {
SelectedProfile = selected; SelectedProfile = selected;
@ -384,15 +384,15 @@ namespace ServiceLib.ViewModels
{ {
_subItems.Clear(); _subItems.Clear();
_subItems.Add(new SubItem { remarks = ResUI.AllGroupServers }); _subItems.Add(new SubItem { Remarks = ResUI.AllGroupServers });
foreach (var item in await AppHandler.Instance.SubItems()) foreach (var item in await AppHandler.Instance.SubItems())
{ {
_subItems.Add(item); _subItems.Add(item);
} }
if (_config.SubIndexId != null && _subItems.FirstOrDefault(t => t.id == _config.SubIndexId) != null) if (_config.SubIndexId != null && _subItems.FirstOrDefault(t => t.Id == _config.SubIndexId) != null)
{ {
SelectedSub = _subItems.FirstOrDefault(t => t.id == _config.SubIndexId); SelectedSub = _subItems.FirstOrDefault(t => t.Id == _config.SubIndexId);
} }
else else
{ {
@ -412,12 +412,12 @@ namespace ServiceLib.ViewModels
return null; return null;
} }
var orderProfiles = SelectedProfiles?.OrderBy(t => t.sort); var orderProfiles = SelectedProfiles?.OrderBy(t => t.Sort);
if (latest) if (latest)
{ {
foreach (var profile in orderProfiles) foreach (var profile in orderProfiles)
{ {
var item = await AppHandler.Instance.GetProfileItem(profile.indexId); var item = await AppHandler.Instance.GetProfileItem(profile.IndexId);
if (item is not null) if (item is not null)
{ {
lstSelecteds.Add(item); lstSelecteds.Add(item);
@ -434,17 +434,17 @@ namespace ServiceLib.ViewModels
public async Task EditServerAsync(EConfigType eConfigType) public async Task EditServerAsync(EConfigType eConfigType)
{ {
if (Utils.IsNullOrEmpty(SelectedProfile?.indexId)) if (Utils.IsNullOrEmpty(SelectedProfile?.IndexId))
{ {
return; return;
} }
var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.indexId); var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.IndexId);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
return; return;
} }
eConfigType = item.configType; eConfigType = item.ConfigType;
bool? ret = false; bool? ret = false;
if (eConfigType == EConfigType.Custom) if (eConfigType == EConfigType.Custom)
@ -458,7 +458,7 @@ namespace ServiceLib.ViewModels
if (ret == true) if (ret == true)
{ {
RefreshServers(); RefreshServers();
if (item.indexId == _config.IndexId) if (item.IndexId == _config.IndexId)
{ {
Reload(); Reload();
} }
@ -476,7 +476,7 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
var exists = lstSelecteds.Exists(t => t.indexId == _config.IndexId); var exists = lstSelecteds.Exists(t => t.IndexId == _config.IndexId);
await ConfigHandler.RemoveServer(_config, lstSelecteds); await ConfigHandler.RemoveServer(_config, lstSelecteds);
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
@ -512,11 +512,11 @@ namespace ServiceLib.ViewModels
public async Task SetDefaultServer() public async Task SetDefaultServer()
{ {
if (Utils.IsNullOrEmpty(SelectedProfile?.indexId)) if (Utils.IsNullOrEmpty(SelectedProfile?.IndexId))
{ {
return; return;
} }
await SetDefaultServer(SelectedProfile.indexId); await SetDefaultServer(SelectedProfile.IndexId);
} }
public async Task SetDefaultServer(string indexId) public async Task SetDefaultServer(string indexId)
@ -562,7 +562,7 @@ namespace ServiceLib.ViewModels
public async Task ShareServerAsync() public async Task ShareServerAsync()
{ {
var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.indexId); var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.IndexId);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
@ -633,7 +633,7 @@ namespace ServiceLib.ViewModels
return; return;
} }
await ConfigHandler.MoveToGroup(_config, lstSelecteds, SelectedMoveToGroup.id); await ConfigHandler.MoveToGroup(_config, lstSelecteds, SelectedMoveToGroup.Id);
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
RefreshServers(); RefreshServers();
@ -643,7 +643,7 @@ namespace ServiceLib.ViewModels
public async Task MoveServer(EMove eMove) public async Task MoveServer(EMove eMove)
{ {
var item = _lstProfile.FirstOrDefault(t => t.indexId == SelectedProfile.indexId); var item = _lstProfile.FirstOrDefault(t => t.IndexId == SelectedProfile.IndexId);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
@ -696,7 +696,7 @@ namespace ServiceLib.ViewModels
private async Task Export2ClientConfigAsync(bool blClipboard) private async Task Export2ClientConfigAsync(bool blClipboard)
{ {
var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.indexId); var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.IndexId);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);

View File

@ -40,7 +40,7 @@ namespace ServiceLib.ViewModels
{ {
rulesItem.id = Utils.GetGuid(false); rulesItem.id = Utils.GetGuid(false);
rulesItem.outboundTag = Global.ProxyTag; rulesItem.outboundTag = Global.ProxyTag;
rulesItem.enabled = true; rulesItem.Enabled = true;
SelectedSource = rulesItem; SelectedSource = rulesItem;
} }
else else

View File

@ -92,7 +92,7 @@ namespace ServiceLib.ViewModels
SelectedSource = new(); SelectedSource = new();
SelectedRouting = routingItem; SelectedRouting = routingItem;
_rules = routingItem.id.IsNullOrEmpty() ? new() : JsonUtils.Deserialize<List<RulesItem>>(SelectedRouting.ruleSet); _rules = routingItem.Id.IsNullOrEmpty() ? new() : JsonUtils.Deserialize<List<RulesItem>>(SelectedRouting.RuleSet);
RefreshRulesItems(); RefreshRulesItems();
} }
@ -109,12 +109,12 @@ namespace ServiceLib.ViewModels
outboundTag = item.outboundTag, outboundTag = item.outboundTag,
port = item.port, port = item.port,
network = item.network, network = item.network,
protocols = Utils.List2String(item.protocol), Protocols = Utils.List2String(item.protocol),
inboundTags = Utils.List2String(item.inboundTag), InboundTags = Utils.List2String(item.inboundTag),
domains = Utils.List2String(item.domain), Domains = Utils.List2String(item.domain),
ips = Utils.List2String(item.ip), Ips = Utils.List2String(item.ip),
enabled = item.enabled, Enabled = item.Enabled,
remarks = item.remarks, Remarks = item.Remarks,
}; };
_rulesItems.Add(it); _rulesItems.Add(it);
} }
@ -214,7 +214,7 @@ namespace ServiceLib.ViewModels
private async Task SaveRoutingAsync() private async Task SaveRoutingAsync()
{ {
string remarks = SelectedRouting.remarks; string remarks = SelectedRouting.Remarks;
if (Utils.IsNullOrEmpty(remarks)) if (Utils.IsNullOrEmpty(remarks))
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks);
@ -225,8 +225,8 @@ namespace ServiceLib.ViewModels
{ {
it.id = Utils.GetGuid(false); it.id = Utils.GetGuid(false);
} }
item.ruleNum = _rules.Count; item.RuleNum = _rules.Count;
item.ruleSet = JsonUtils.Serialize(_rules, false); item.RuleSet = JsonUtils.Serialize(_rules, false);
if (await ConfigHandler.SaveRoutingItem(_config, item) == 0) if (await ConfigHandler.SaveRoutingItem(_config, item) == 0)
{ {
@ -278,7 +278,7 @@ namespace ServiceLib.ViewModels
private async Task ImportRulesFromUrl() private async Task ImportRulesFromUrl()
{ {
var url = SelectedRouting.url; var url = SelectedRouting.Url;
if (Utils.IsNullOrEmpty(url)) if (Utils.IsNullOrEmpty(url))
{ {
NoticeHandler.Instance.Enqueue(ResUI.MsgNeedUrl); NoticeHandler.Instance.Enqueue(ResUI.MsgNeedUrl);

View File

@ -71,7 +71,7 @@ namespace ServiceLib.ViewModels
var canEditRemove = this.WhenAnyValue( var canEditRemove = this.WhenAnyValue(
x => x.SelectedSource, x => x.SelectedSource,
selectedSource => selectedSource != null && !selectedSource.remarks.IsNullOrEmpty()); selectedSource => selectedSource != null && !selectedSource.Remarks.IsNullOrEmpty());
this.WhenAnyValue( this.WhenAnyValue(
x => x.enableRoutingAdvanced) x => x.enableRoutingAdvanced)
@ -130,16 +130,16 @@ namespace ServiceLib.ViewModels
{ {
_lockedItem = new RoutingItem() _lockedItem = new RoutingItem()
{ {
remarks = "locked", Remarks = "locked",
url = string.Empty, Url = string.Empty,
locked = true, Locked = true,
}; };
await ConfigHandler.AddBatchRoutingRules(_lockedItem, Utils.GetEmbedText(Global.CustomRoutingFileName + "locked")); await ConfigHandler.AddBatchRoutingRules(_lockedItem, Utils.GetEmbedText(Global.CustomRoutingFileName + "locked"));
} }
if (_lockedItem != null) if (_lockedItem != null)
{ {
_lockedRules = JsonUtils.Deserialize<List<RulesItem>>(_lockedItem.ruleSet); _lockedRules = JsonUtils.Deserialize<List<RulesItem>>(_lockedItem.RuleSet);
ProxyDomain = Utils.List2String(_lockedRules[0].domain, true); ProxyDomain = Utils.List2String(_lockedRules[0].domain, true);
ProxyIP = Utils.List2String(_lockedRules[0].ip, true); ProxyIP = Utils.List2String(_lockedRules[0].ip, true);
@ -164,7 +164,7 @@ namespace ServiceLib.ViewModels
_lockedRules[2].domain = Utils.String2List(Utils.Convert2Comma(BlockDomain.TrimEx())); _lockedRules[2].domain = Utils.String2List(Utils.Convert2Comma(BlockDomain.TrimEx()));
_lockedRules[2].ip = Utils.String2List(Utils.Convert2Comma(BlockIP.TrimEx())); _lockedRules[2].ip = Utils.String2List(Utils.Convert2Comma(BlockIP.TrimEx()));
_lockedItem.ruleSet = JsonUtils.Serialize(_lockedRules, false); _lockedItem.RuleSet = JsonUtils.Serialize(_lockedRules, false);
await ConfigHandler.SaveRoutingItem(_config, _lockedItem); await ConfigHandler.SaveRoutingItem(_config, _lockedItem);
} }
@ -182,21 +182,21 @@ namespace ServiceLib.ViewModels
foreach (var item in routings) foreach (var item in routings)
{ {
bool def = false; bool def = false;
if (item.id == _config.RoutingBasicItem.RoutingIndexId) if (item.Id == _config.RoutingBasicItem.RoutingIndexId)
{ {
def = true; def = true;
} }
var it = new RoutingItemModel() var it = new RoutingItemModel()
{ {
isActive = def, IsActive = def,
ruleNum = item.ruleNum, RuleNum = item.RuleNum,
id = item.id, Id = item.Id,
remarks = item.remarks, Remarks = item.Remarks,
url = item.url, Url = item.Url,
customIcon = item.customIcon, CustomIcon = item.CustomIcon,
customRulesetPath4Singbox = item.customRulesetPath4Singbox, CustomRulesetPath4Singbox = item.CustomRulesetPath4Singbox,
sort = item.sort, Sort = item.Sort,
}; };
_routingItems.Add(it); _routingItems.Add(it);
} }
@ -245,7 +245,7 @@ namespace ServiceLib.ViewModels
} }
else else
{ {
item = await AppHandler.Instance.GetRoutingItem(SelectedSource?.id); item = await AppHandler.Instance.GetRoutingItem(SelectedSource?.Id);
if (item is null) if (item is null)
{ {
return; return;
@ -260,7 +260,7 @@ namespace ServiceLib.ViewModels
public async Task RoutingAdvancedRemoveAsync() public async Task RoutingAdvancedRemoveAsync()
{ {
if (SelectedSource is null || SelectedSource.remarks.IsNullOrEmpty()) if (SelectedSource is null || SelectedSource.Remarks.IsNullOrEmpty())
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules);
return; return;
@ -271,7 +271,7 @@ namespace ServiceLib.ViewModels
} }
foreach (var it in SelectedSources ?? [SelectedSource]) foreach (var it in SelectedSources ?? [SelectedSource])
{ {
var item = await AppHandler.Instance.GetRoutingItem(it?.id); var item = await AppHandler.Instance.GetRoutingItem(it?.Id);
if (item != null) if (item != null)
{ {
await ConfigHandler.RemoveRoutingItem(item); await ConfigHandler.RemoveRoutingItem(item);
@ -284,7 +284,7 @@ namespace ServiceLib.ViewModels
public async Task RoutingAdvancedSetDefault() public async Task RoutingAdvancedSetDefault()
{ {
var item = await AppHandler.Instance.GetRoutingItem(SelectedSource?.id); var item = await AppHandler.Instance.GetRoutingItem(SelectedSource?.Id);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules);

View File

@ -109,7 +109,7 @@ namespace ServiceLib.ViewModels
this.WhenAnyValue( this.WhenAnyValue(
x => x.SelectedRouting, x => x.SelectedRouting,
y => y != null && !y.remarks.IsNullOrEmpty()) y => y != null && !y.Remarks.IsNullOrEmpty())
.Subscribe(async c => await RoutingSelectedChangedAsync(c)); .Subscribe(async c => await RoutingSelectedChangedAsync(c));
this.WhenAnyValue( this.WhenAnyValue(
@ -263,9 +263,9 @@ namespace ServiceLib.ViewModels
ProfileItem it = lstModel[k]; ProfileItem it = lstModel[k];
string name = it.GetSummary(); string name = it.GetSummary();
var item = new ComboItem() { ID = it.indexId, Text = name }; var item = new ComboItem() { ID = it.IndexId, Text = name };
_servers.Add(item); _servers.Add(item);
if (_config.IndexId == it.indexId) if (_config.IndexId == it.IndexId)
{ {
SelectedServer = item; SelectedServer = item;
} }
@ -358,7 +358,7 @@ namespace ServiceLib.ViewModels
foreach (var item in routings) foreach (var item in routings)
{ {
_routingItems.Add(item); _routingItems.Add(item);
if (item.id == _config.RoutingBasicItem.RoutingIndexId) if (item.Id == _config.RoutingBasicItem.RoutingIndexId)
{ {
SelectedRouting = item; SelectedRouting = item;
} }
@ -377,12 +377,12 @@ namespace ServiceLib.ViewModels
return; return;
} }
var item = await AppHandler.Instance.GetRoutingItem(SelectedRouting?.id); var item = await AppHandler.Instance.GetRoutingItem(SelectedRouting?.Id);
if (item is null) if (item is null)
{ {
return; return;
} }
if (_config.RoutingBasicItem.RoutingIndexId == item.id) if (_config.RoutingBasicItem.RoutingIndexId == item.Id)
{ {
return; return;
} }

View File

@ -21,12 +21,12 @@ namespace ServiceLib.ViewModels
await SaveSubAsync(); await SaveSubAsync();
}); });
SelectedSource = subItem.id.IsNullOrEmpty() ? subItem : JsonUtils.DeepCopy(subItem); SelectedSource = subItem.Id.IsNullOrEmpty() ? subItem : JsonUtils.DeepCopy(subItem);
} }
private async Task SaveSubAsync() private async Task SaveSubAsync()
{ {
var remarks = SelectedSource.remarks; var remarks = SelectedSource.Remarks;
if (Utils.IsNullOrEmpty(remarks)) if (Utils.IsNullOrEmpty(remarks))
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks);

View File

@ -29,7 +29,7 @@ namespace ServiceLib.ViewModels
var canEditRemove = this.WhenAnyValue( var canEditRemove = this.WhenAnyValue(
x => x.SelectedSource, x => x.SelectedSource,
selectedSource => selectedSource != null && !selectedSource.id.IsNullOrEmpty()); selectedSource => selectedSource != null && !selectedSource.Id.IsNullOrEmpty());
SubAddCmd = ReactiveCommand.CreateFromTask(async () => SubAddCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
@ -45,7 +45,7 @@ namespace ServiceLib.ViewModels
}, canEditRemove); }, canEditRemove);
SubShareCmd = ReactiveCommand.CreateFromTask(async () => SubShareCmd = ReactiveCommand.CreateFromTask(async () =>
{ {
await _updateView?.Invoke(EViewAction.ShareSub, SelectedSource?.url); await _updateView?.Invoke(EViewAction.ShareSub, SelectedSource?.Url);
}, canEditRemove); }, canEditRemove);
Init(); Init();
@ -73,7 +73,7 @@ namespace ServiceLib.ViewModels
} }
else else
{ {
item = await AppHandler.Instance.GetSubItem(SelectedSource?.id); item = await AppHandler.Instance.GetSubItem(SelectedSource?.Id);
if (item is null) if (item is null)
{ {
return; return;
@ -95,7 +95,7 @@ namespace ServiceLib.ViewModels
foreach (var it in SelectedSources ?? [SelectedSource]) foreach (var it in SelectedSources ?? [SelectedSource])
{ {
await ConfigHandler.DeleteSubItem(_config, it.id); await ConfigHandler.DeleteSubItem(_config, it.Id);
} }
await RefreshSubItems(); await RefreshSubItems();
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);

View File

@ -31,11 +31,11 @@ namespace v2rayN.Desktop.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.address, v => v.txtAddress.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Address, v => v.txtAddress.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType, v => v.cmbCoreType.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType, v => v.cmbCoreType.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.displayLog, v => v.togDisplayLog.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.DisplayLog, v => v.togDisplayLog.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.preSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PreSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.BrowseServerCmd, v => v.btnBrowse).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.BrowseServerCmd, v => v.btnBrowse).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);

View File

@ -26,7 +26,7 @@ namespace v2rayN.Desktop.Views
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler); ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
if (profileItem.configType == EConfigType.VLESS) if (profileItem.ConfigType == EConfigType.VLESS)
{ {
Global.CoreTypes4VLESS.ForEach(it => Global.CoreTypes4VLESS.ForEach(it =>
{ {
@ -63,7 +63,7 @@ namespace v2rayN.Desktop.Views
cmbAlpn.Items.Add(it); cmbAlpn.Items.Add(it);
}); });
switch (profileItem.configType) switch (profileItem.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
gridVMess.IsVisible = true; gridVMess.IsVisible = true;
@ -71,9 +71,9 @@ namespace v2rayN.Desktop.Views
{ {
cmbSecurity.Items.Add(it); cmbSecurity.Items.Add(it);
}); });
if (profileItem.security.IsNullOrEmpty()) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.security = Global.DefaultSecurity; profileItem.Security = Global.DefaultSecurity;
} }
break; break;
@ -97,9 +97,9 @@ namespace v2rayN.Desktop.Views
{ {
cmbFlow5.Items.Add(it); cmbFlow5.Items.Add(it);
}); });
if (profileItem.security.IsNullOrEmpty()) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.security = Global.None; profileItem.Security = Global.None;
} }
break; break;
@ -151,80 +151,80 @@ namespace v2rayN.Desktop.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.CoreType, v => v.cmbCoreType.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType, v => v.cmbCoreType.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.address, v => v.txtAddress.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Address, v => v.txtAddress.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Port, v => v.txtPort.Text).DisposeWith(disposables);
switch (profileItem.configType) switch (profileItem.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.alterId, v => v.txtAlterId.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.AlterId, v => v.txtAlterId.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.cmbSecurity.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.cmbSecurity.SelectedValue).DisposeWith(disposables);
break; break;
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId3.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId3.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.cmbSecurity3.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.cmbSecurity3.SelectedValue).DisposeWith(disposables);
break; break;
case EConfigType.SOCKS: case EConfigType.SOCKS:
case EConfigType.HTTP: case EConfigType.HTTP:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId4.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId4.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity4.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.txtSecurity4.Text).DisposeWith(disposables);
break; break;
case EConfigType.VLESS: case EConfigType.VLESS:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId5.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId5.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.flow, v => v.cmbFlow5.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Flow, v => v.cmbFlow5.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity5.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.txtSecurity5.Text).DisposeWith(disposables);
break; break;
case EConfigType.Trojan: case EConfigType.Trojan:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId6.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId6.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.flow, v => v.cmbFlow6.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Flow, v => v.cmbFlow6.SelectedValue).DisposeWith(disposables);
break; break;
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.path, v => v.txtPath7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables);
break; break;
case EConfigType.TUIC: case EConfigType.TUIC:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId8.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId8.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity8.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.txtSecurity8.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.headerType, v => v.cmbHeaderType8.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType8.SelectedValue).DisposeWith(disposables);
break; break;
case EConfigType.WireGuard: case EConfigType.WireGuard:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.publicKey, v => v.txtPublicKey9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PublicKey, v => v.txtPublicKey9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.path, v => v.txtPath9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.requestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.shortId, v => v.txtShortId9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
break; break;
} }
this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.headerType, v => v.cmbHeaderType.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.requestHost, v => v.txtRequestHost.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.path, v => v.txtPath.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.streamSecurity, v => v.cmbStreamSecurity.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.StreamSecurity, v => v.cmbStreamSecurity.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.sni, v => v.txtSNI.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Sni, v => v.txtSNI.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.allowInsecure, v => v.cmbAllowInsecure.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.AllowInsecure, v => v.cmbAllowInsecure.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.fingerprint, v => v.cmbFingerprint.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Fingerprint, v => v.cmbFingerprint.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.alpn, v => v.cmbAlpn.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Alpn, v => v.cmbAlpn.SelectedValue).DisposeWith(disposables);
//reality //reality
this.Bind(ViewModel, vm => vm.SelectedSource.sni, v => v.txtSNI2.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Sni, v => v.txtSNI2.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.fingerprint, v => v.cmbFingerprint2.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Fingerprint, v => v.cmbFingerprint2.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.publicKey, v => v.txtPublicKey.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PublicKey, v => v.txtPublicKey.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.shortId, v => v.txtShortId.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.spiderX, v => v.txtSpiderX.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.SpiderX, v => v.txtSpiderX.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });
this.Title = $"{profileItem.configType}"; this.Title = $"{profileItem.ConfigType}";
} }
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj) private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@ -154,7 +154,7 @@
Background="YellowGreen" Background="YellowGreen"
CornerRadius="4" CornerRadius="4"
DockPanel.Dock="Left" DockPanel.Dock="Left"
IsVisible="{Binding isActive}" /> IsVisible="{Binding IsActive}" />
<Grid Classes="Margin8"> <Grid Classes="Margin8">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="1*" /> <RowDefinition Height="1*" />

View File

@ -20,7 +20,7 @@
<ListBox <ListBox
x:Name="lstGroup" x:Name="lstGroup"
MaxHeight="200" MaxHeight="200"
DisplayMemberBinding="{Binding remarks}" DisplayMemberBinding="{Binding Remarks}"
ItemsSource="{Binding SubItems}" ItemsSource="{Binding SubItems}"
Theme="{DynamicResource PureCardRadioGroupListBox}" /> Theme="{DynamicResource PureCardRadioGroupListBox}" />
@ -124,7 +124,7 @@
<ComboBox <ComboBox
x:Name="cmbMoveToGroup" x:Name="cmbMoveToGroup"
Width="200" Width="200"
DisplayMemberBinding="{Binding remarks}" DisplayMemberBinding="{Binding Remarks}"
ItemsSource="{Binding SubItems}" ItemsSource="{Binding SubItems}"
ToolTip.Tip="{x:Static resx:ResUI.menuSubscription}" /> ToolTip.Tip="{x:Static resx:ResUI.menuSubscription}" />
</DockPanel> </DockPanel>
@ -153,11 +153,11 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn <DataGridTextColumn
Width="80" Width="80"
Binding="{Binding configType}" Binding="{Binding ConfigType}"
Header="{x:Static resx:ResUI.LvServiceType}" Header="{x:Static resx:ResUI.LvServiceType}"
Tag="configType" /> Tag="ConfigType" />
<DataGridTemplateColumn SortMemberPath="remarks" Tag="remarks"> <DataGridTemplateColumn SortMemberPath="Remarks" Tag="Remarks">
<DataGridTemplateColumn.Header> <DataGridTemplateColumn.Header>
<TextBlock Text="{x:Static resx:ResUI.LvRemarks}" /> <TextBlock Text="{x:Static resx:ResUI.LvRemarks}" />
</DataGridTemplateColumn.Header> </DataGridTemplateColumn.Header>
@ -168,12 +168,12 @@
Margin="0,0,8,0" Margin="0,0,8,0"
Classes="Solid Red" Classes="Solid Red"
Content="{x:Static resx:ResUI.TipActiveServer}" Content="{x:Static resx:ResUI.TipActiveServer}"
IsVisible="{Binding isActive}" IsVisible="{Binding IsActive}"
Theme="{StaticResource TagLabel}" /> Theme="{StaticResource TagLabel}" />
<TextBlock <TextBlock
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{Binding remarks}" /> Text="{Binding Remarks}" />
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
@ -181,30 +181,30 @@
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
Binding="{Binding address}" Binding="{Binding Address}"
Header="{x:Static resx:ResUI.LvAddress}" Header="{x:Static resx:ResUI.LvAddress}"
Tag="address" /> Tag="Address" />
<DataGridTextColumn <DataGridTextColumn
Width="60" Width="60"
Binding="{Binding port}" Binding="{Binding Port}"
Header="{x:Static resx:ResUI.LvPort}" Header="{x:Static resx:ResUI.LvPort}"
Tag="port" /> Tag="Port" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding network}" Binding="{Binding Network}"
Header="{x:Static resx:ResUI.LvTransportProtocol}" Header="{x:Static resx:ResUI.LvTransportProtocol}"
Tag="network" /> Tag="Network" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding streamSecurity}" Binding="{Binding StreamSecurity}"
Header="{x:Static resx:ResUI.LvTLS}" Header="{x:Static resx:ResUI.LvTLS}"
Tag="streamSecurity" /> Tag="StreamSecurity" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding subRemarks}" Binding="{Binding SubRemarks}"
Header="{x:Static resx:ResUI.LvSubscription}" Header="{x:Static resx:ResUI.LvSubscription}"
Tag="subRemarks" /> Tag="SubRemarks" />
<DataGridTemplateColumn SortMemberPath="delay" Tag="delay"> <DataGridTemplateColumn SortMemberPath="Delay" Tag="Delay">
<DataGridTemplateColumn.Header> <DataGridTemplateColumn.Header>
<TextBlock Text="{x:Static resx:ResUI.LvTestDelay}" /> <TextBlock Text="{x:Static resx:ResUI.LvTestDelay}" />
</DataGridTemplateColumn.Header> </DataGridTemplateColumn.Header>
@ -214,37 +214,37 @@
Margin="8,0" Margin="8,0"
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{Binding delay, Converter={StaticResource DelayColorConverter}}" Foreground="{Binding Delay, Converter={StaticResource DelayColorConverter}}"
Text="{Binding Path=delayVal, Mode=OneWay}" /> Text="{Binding Path=DelayVal, Mode=OneWay}" />
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding speedVal}" Binding="{Binding SpeedVal}"
Header="{x:Static resx:ResUI.LvTestSpeed}" Header="{x:Static resx:ResUI.LvTestSpeed}"
Tag="speedVal" /> Tag="SpeedVal" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding todayUp}" Binding="{Binding TodayUp}"
Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}" Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}"
Tag="todayUp" /> Tag="TodayUp" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding todayDown}" Binding="{Binding TodayDown}"
Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}" Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}"
Tag="todayDown" /> Tag="TodayDown" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding totalUp}" Binding="{Binding TotalUp}"
Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}" Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}"
Tag="totalUp" /> Tag="TotalUp" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding totalDown}" Binding="{Binding TotalDown}"
Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}" Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}"
Tag="totalDown" /> Tag="TotalDown" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
</DockPanel> </DockPanel>

View File

@ -53,11 +53,11 @@ namespace v2rayN.Desktop.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.outboundTag, v => v.cmbOutboundTag.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.outboundTag, v => v.cmbOutboundTag.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables);

View File

@ -210,11 +210,11 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridCheckBoxColumn <DataGridCheckBoxColumn
Width="60" Width="60"
Binding="{Binding enabled}" Binding="{Binding Enabled}"
Header="" /> Header="" />
<DataGridTextColumn <DataGridTextColumn
Width="150" Width="150"
Binding="{Binding remarks}" Binding="{Binding Remarks}"
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
@ -226,11 +226,11 @@
Header="port" /> Header="port" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding protocols}" Binding="{Binding Protocols}"
Header="protocol" /> Header="protocol" />
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
Binding="{Binding inboundTags}" Binding="{Binding InboundTags}"
Header="inboundTag" /> Header="inboundTag" />
<DataGridTextColumn <DataGridTextColumn
Width="90" Width="90"
@ -238,11 +238,11 @@
Header="network" /> Header="network" />
<DataGridTextColumn <DataGridTextColumn
Width="200" Width="200"
Binding="{Binding domains}" Binding="{Binding Domains}"
Header="domain" /> Header="domain" />
<DataGridTextColumn <DataGridTextColumn
Width="200" Width="200"
Binding="{Binding ips}" Binding="{Binding Ips}"
Header="ip" /> Header="ip" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View File

@ -46,14 +46,14 @@ namespace v2rayN.Desktop.Views
this.OneWayBind(ViewModel, vm => vm.RulesItems, v => v.lstRules.ItemsSource).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.RulesItems, v => v.lstRules.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRules.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRules.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.domainStrategy, v => v.cmbdomainStrategy.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.DomainStrategy, v => v.cmbdomainStrategy.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.domainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.url, v => v.txtUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.Url, v => v.txtUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.customIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.CustomIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.customRulesetPath4Singbox, v => v.txtCustomRulesetPath4Singbox.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.CustomRulesetPath4Singbox, v => v.txtCustomRulesetPath4Singbox.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.sort, v => v.txtSort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.Sort, v => v.txtSort.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RuleAddCmd, v => v.menuRuleAdd).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RuleAddCmd, v => v.menuRuleAdd).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportRulesFromFileCmd, v => v.menuImportRulesFromFile).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportRulesFromFileCmd, v => v.menuImportRulesFromFile).DisposeWith(disposables);

View File

@ -109,26 +109,26 @@
</DataGrid.ContextMenu> </DataGrid.ContextMenu>
<DataGrid.Columns> <DataGrid.Columns>
<DataGridCheckBoxColumn Width="40" Binding="{Binding isActive}" /> <DataGridCheckBoxColumn Width="40" Binding="{Binding IsActive}" />
<DataGridTextColumn <DataGridTextColumn
Width="250" Width="250"
Binding="{Binding remarks}" Binding="{Binding Remarks}"
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn <DataGridTextColumn
Width="60" Width="60"
Binding="{Binding ruleNum}" Binding="{Binding RuleNum}"
Header="{x:Static resx:ResUI.LvCount}" /> Header="{x:Static resx:ResUI.LvCount}" />
<DataGridTextColumn <DataGridTextColumn
Width="60" Width="60"
Binding="{Binding sort}" Binding="{Binding Sort}"
Header="{x:Static resx:ResUI.LvSort}" /> Header="{x:Static resx:ResUI.LvSort}" />
<DataGridTextColumn <DataGridTextColumn
Width="300" Width="300"
Binding="{Binding url}" Binding="{Binding Url}"
Header="{x:Static resx:ResUI.LvUrl}" /> Header="{x:Static resx:ResUI.LvUrl}" />
<DataGridTextColumn <DataGridTextColumn
Width="300" Width="300"
Binding="{Binding customIcon}" Binding="{Binding CustomIcon}"
Header="{x:Static resx:ResUI.LvCustomIcon}" /> Header="{x:Static resx:ResUI.LvCustomIcon}" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View File

@ -69,7 +69,7 @@
x:Name="cmbRoutings2" x:Name="cmbRoutings2"
Width="160" Width="160"
Margin="8,0" Margin="8,0"
DisplayMemberBinding="{Binding remarks}" DisplayMemberBinding="{Binding Remarks}"
ItemsSource="{Binding RoutingItems}" ItemsSource="{Binding RoutingItems}"
ToolTip.Tip="{x:Static resx:ResUI.menuRouting}" /> ToolTip.Tip="{x:Static resx:ResUI.menuRouting}" />
</StackPanel> </StackPanel>

View File

@ -29,18 +29,18 @@ namespace v2rayN.Desktop.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.url, v => v.txtUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Url, v => v.txtUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.moreUrl, v => v.txtMoreUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.MoreUrl, v => v.txtMoreUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnable.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnable.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.autoUpdateInterval, v => v.txtAutoUpdateInterval.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.AutoUpdateInterval, v => v.txtAutoUpdateInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.userAgent, v => v.txtUserAgent.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.UserAgent, v => v.txtUserAgent.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.sort, v => v.txtSort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Sort, v => v.txtSort.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.filter, v => v.txtFilter.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Filter, v => v.txtFilter.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.convertTarget, v => v.cmbConvertTarget.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.ConvertTarget, v => v.cmbConvertTarget.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.prevProfile, v => v.txtPrevProfile.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PrevProfile, v => v.txtPrevProfile.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.nextProfile, v => v.txtNextProfile.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.NextProfile, v => v.txtNextProfile.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.preSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PreSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });

View File

@ -50,27 +50,27 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
Binding="{Binding remarks}" Binding="{Binding Remarks}"
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn <DataGridTextColumn
Width="150" Width="150"
Binding="{Binding url}" Binding="{Binding Url}"
Header="{x:Static resx:ResUI.LvUrl}" /> Header="{x:Static resx:ResUI.LvUrl}" />
<DataGridCheckBoxColumn <DataGridCheckBoxColumn
Width="100" Width="100"
Binding="{Binding enabled}" Binding="{Binding Enabled}"
Header="{x:Static resx:ResUI.LvEnabled}" /> Header="{x:Static resx:ResUI.LvEnabled}" />
<DataGridTextColumn <DataGridTextColumn
Width="150" Width="150"
Binding="{Binding autoUpdateInterval}" Binding="{Binding AutoUpdateInterval}"
Header="{x:Static resx:ResUI.LvAutoUpdateInterval}" /> Header="{x:Static resx:ResUI.LvAutoUpdateInterval}" />
<DataGridTextColumn <DataGridTextColumn
Width="150" Width="150"
Binding="{Binding userAgent}" Binding="{Binding UserAgent}"
Header="{x:Static resx:ResUI.LvUserAgent}" /> Header="{x:Static resx:ResUI.LvUserAgent}" />
<DataGridTextColumn <DataGridTextColumn
Width="80" Width="80"
Binding="{Binding sort}" Binding="{Binding Sort}"
Header="{x:Static resx:ResUI.LvSort}" /> Header="{x:Static resx:ResUI.LvSort}" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View File

@ -60,7 +60,7 @@ namespace v2rayN.Handler
} }
var item = await ConfigHandler.GetDefaultRouting(config); var item = await ConfigHandler.GetDefaultRouting(config);
if (item == null || Utils.IsNullOrEmpty(item.customIcon) || !File.Exists(item.customIcon)) if (item == null || Utils.IsNullOrEmpty(item.CustomIcon) || !File.Exists(item.CustomIcon))
{ {
return null; return null;
} }
@ -81,7 +81,7 @@ namespace v2rayN.Handler
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
//graphics.FillRectangle(drawBrush, new Rectangle(0, 0, width, height)); //graphics.FillRectangle(drawBrush, new Rectangle(0, 0, width, height));
graphics.DrawImage(new Bitmap(item.customIcon), 0, 0, width, height); graphics.DrawImage(new Bitmap(item.CustomIcon), 0, 0, width, height);
graphics.FillEllipse(drawBrush, width / 2, width / 2, width / 2, width / 2); graphics.FillEllipse(drawBrush, width / 2, width / 2, width / 2, width / 2);
Icon createdIcon = Icon.FromHandle(bitmap.GetHicon()); Icon createdIcon = Icon.FromHandle(bitmap.GetHicon());

View File

@ -24,11 +24,11 @@ namespace v2rayN.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.address, v => v.txtAddress.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Address, v => v.txtAddress.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CoreType, v => v.cmbCoreType.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType, v => v.cmbCoreType.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.displayLog, v => v.togDisplayLog.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.DisplayLog, v => v.togDisplayLog.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.preSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PreSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.BrowseServerCmd, v => v.btnBrowse).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.BrowseServerCmd, v => v.btnBrowse).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);

View File

@ -20,7 +20,7 @@ namespace v2rayN.Views
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler); ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
if (profileItem.configType == EConfigType.VLESS) if (profileItem.ConfigType == EConfigType.VLESS)
{ {
Global.CoreTypes4VLESS.ForEach(it => Global.CoreTypes4VLESS.ForEach(it =>
{ {
@ -57,7 +57,7 @@ namespace v2rayN.Views
cmbAlpn.Items.Add(it); cmbAlpn.Items.Add(it);
}); });
switch (profileItem.configType) switch (profileItem.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
gridVMess.Visibility = Visibility.Visible; gridVMess.Visibility = Visibility.Visible;
@ -65,9 +65,9 @@ namespace v2rayN.Views
{ {
cmbSecurity.Items.Add(it); cmbSecurity.Items.Add(it);
}); });
if (profileItem.security.IsNullOrEmpty()) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.security = Global.DefaultSecurity; profileItem.Security = Global.DefaultSecurity;
} }
break; break;
@ -91,9 +91,9 @@ namespace v2rayN.Views
{ {
cmbFlow5.Items.Add(it); cmbFlow5.Items.Add(it);
}); });
if (profileItem.security.IsNullOrEmpty()) if (profileItem.Security.IsNullOrEmpty())
{ {
profileItem.security = Global.None; profileItem.Security = Global.None;
} }
break; break;
@ -145,80 +145,80 @@ namespace v2rayN.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.CoreType, v => v.cmbCoreType.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CoreType, v => v.cmbCoreType.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.address, v => v.txtAddress.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Address, v => v.txtAddress.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Port, v => v.txtPort.Text).DisposeWith(disposables);
switch (profileItem.configType) switch (profileItem.ConfigType)
{ {
case EConfigType.VMess: case EConfigType.VMess:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.alterId, v => v.txtAlterId.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.AlterId, v => v.txtAlterId.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.cmbSecurity.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.cmbSecurity.Text).DisposeWith(disposables);
break; break;
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId3.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId3.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.cmbSecurity3.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.cmbSecurity3.Text).DisposeWith(disposables);
break; break;
case EConfigType.SOCKS: case EConfigType.SOCKS:
case EConfigType.HTTP: case EConfigType.HTTP:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId4.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId4.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity4.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.txtSecurity4.Text).DisposeWith(disposables);
break; break;
case EConfigType.VLESS: case EConfigType.VLESS:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId5.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId5.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.flow, v => v.cmbFlow5.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Flow, v => v.cmbFlow5.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity5.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.txtSecurity5.Text).DisposeWith(disposables);
break; break;
case EConfigType.Trojan: case EConfigType.Trojan:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId6.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId6.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.flow, v => v.cmbFlow6.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Flow, v => v.cmbFlow6.Text).DisposeWith(disposables);
break; break;
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.path, v => v.txtPath7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables);
break; break;
case EConfigType.TUIC: case EConfigType.TUIC:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId8.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId8.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity8.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Security, v => v.txtSecurity8.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.headerType, v => v.cmbHeaderType8.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType8.Text).DisposeWith(disposables);
break; break;
case EConfigType.WireGuard: case EConfigType.WireGuard:
this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Id, v => v.txtId9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.publicKey, v => v.txtPublicKey9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PublicKey, v => v.txtPublicKey9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.path, v => v.txtPath9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.requestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost9.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.shortId, v => v.txtShortId9.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId9.Text).DisposeWith(disposables);
break; break;
} }
this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.headerType, v => v.cmbHeaderType.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.requestHost, v => v.txtRequestHost.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.RequestHost, v => v.txtRequestHost.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.path, v => v.txtPath.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.streamSecurity, v => v.cmbStreamSecurity.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.StreamSecurity, v => v.cmbStreamSecurity.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.sni, v => v.txtSNI.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Sni, v => v.txtSNI.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.allowInsecure, v => v.cmbAllowInsecure.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.AllowInsecure, v => v.cmbAllowInsecure.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.fingerprint, v => v.cmbFingerprint.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Fingerprint, v => v.cmbFingerprint.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.alpn, v => v.cmbAlpn.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Alpn, v => v.cmbAlpn.Text).DisposeWith(disposables);
//reality //reality
this.Bind(ViewModel, vm => vm.SelectedSource.sni, v => v.txtSNI2.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Sni, v => v.txtSNI2.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.fingerprint, v => v.cmbFingerprint2.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Fingerprint, v => v.cmbFingerprint2.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.publicKey, v => v.txtPublicKey.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PublicKey, v => v.txtPublicKey.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.shortId, v => v.txtShortId.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.ShortId, v => v.txtShortId.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.spiderX, v => v.txtSpiderX.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.SpiderX, v => v.txtSpiderX.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });
this.Title = $"{profileItem.configType}"; this.Title = $"{profileItem.ConfigType}";
WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? !WindowsUtils.IsLightTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark); WindowsUtils.SetDarkBorder(this, AppHandler.Instance.Config.UiItem.FollowSystemTheme ? !WindowsUtils.IsLightTheme() : AppHandler.Instance.Config.UiItem.ColorModeDark);
} }

View File

@ -161,7 +161,7 @@
Background="{DynamicResource MaterialDesign.Brush.Primary.Light}" Background="{DynamicResource MaterialDesign.Brush.Primary.Light}"
CornerRadius="4" CornerRadius="4"
DockPanel.Dock="Left" DockPanel.Dock="Left"
Visibility="{Binding Path=isActive, Converter={StaticResource BoolToVisConverter}}" /> Visibility="{Binding Path=IsActive, Converter={StaticResource BoolToVisConverter}}" />
<Grid Margin="{StaticResource Margin4}"> <Grid Margin="{StaticResource Margin4}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="2*" /> <RowDefinition Height="2*" />

View File

@ -30,7 +30,7 @@
Style="{StaticResource MaterialDesignChoiceChipPrimaryOutlineListBox}"> Style="{StaticResource MaterialDesignChoiceChipPrimaryOutlineListBox}">
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<TextBlock Text="{Binding remarks}" /> <TextBlock Text="{Binding Remarks}" />
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox> </ListBox>
@ -162,7 +162,7 @@
x:Name="cmbMoveToGroup" x:Name="cmbMoveToGroup"
Width="200" Width="200"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSubscription}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuSubscription}"
DisplayMemberPath="remarks" DisplayMemberPath="Remarks"
FontSize="{DynamicResource StdFontSize}" FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilledComboBox}" /> Style="{StaticResource MaterialDesignFilledComboBox}" />
</DockPanel> </DockPanel>
@ -224,7 +224,7 @@
<Style BasedOn="{StaticResource MaterialDesignDataGridCell}" TargetType="DataGridCell"> <Style BasedOn="{StaticResource MaterialDesignDataGridCell}" TargetType="DataGridCell">
<Style.Triggers> <Style.Triggers>
<DataTrigger Binding="{Binding isActive}" Value="True"> <DataTrigger Binding="{Binding IsActive}" Value="True">
<Setter Property="Background" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" /> <Setter Property="Background" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" />
<Setter Property="Foreground" Value="Black" /> <Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" /> <Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" />
@ -235,55 +235,56 @@
<DataGrid.Columns> <DataGrid.Columns>
<base:MyDGTextColumn <base:MyDGTextColumn
Width="80" Width="80"
Binding="{Binding configType}" Binding="{Binding ConfigType}"
ExName="configType" ExName="ConfigType"
Header="{x:Static resx:ResUI.LvServiceType}" /> Header="{x:Static resx:ResUI.LvServiceType}" />
<base:MyDGTextColumn <base:MyDGTextColumn
Width="150" Width="150"
Binding="{Binding remarks}" Binding="{Binding Remarks}"
ExName="remarks" ExName="Remarks"
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<base:MyDGTextColumn <base:MyDGTextColumn
Width="120" Width="120"
Binding="{Binding address}" Binding="{Binding Address}"
ExName="address" ExName="Address"
Header="{x:Static resx:ResUI.LvAddress}" /> Header="{x:Static resx:ResUI.LvAddress}" />
<base:MyDGTextColumn <base:MyDGTextColumn
Width="60" Width="60"
Binding="{Binding port}" Binding="{Binding Port}"
ExName="port" ExName="Port"
Header="{x:Static resx:ResUI.LvPort}" /> Header="{x:Static resx:ResUI.LvPort}" />
<base:MyDGTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding network}" Binding="{Binding Network}"
ExName="network" ExName="Network"
Header="{x:Static resx:ResUI.LvTransportProtocol}" /> Header="{x:Static resx:ResUI.LvTransportProtocol}" />
<base:MyDGTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding streamSecurity}" Binding="{Binding StreamSecurity}"
ExName="streamSecurity" ExName="StreamSecurity"
Header="{x:Static resx:ResUI.LvTLS}" /> Header="{x:Static resx:ResUI.LvTLS}" />
<base:MyDGTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding subRemarks}" Binding="{Binding SubRemarks}"
ExName="subRemarks" ExName="SubRemarks"
Header="{x:Static resx:ResUI.LvSubscription}" /> Header="{x:Static resx:ResUI.LvSubscription}" />
<base:MyDGTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding delayVal}" Binding="{Binding DelayVal}"
ExName="delayVal" ExName="DelayVal"
Header="{x:Static resx:ResUI.LvTestDelay}"> Header="{x:Static resx:ResUI.LvTestDelay}"
SortMemberPath="Delay">
<DataGridTextColumn.ElementStyle> <DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}"> <Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Right" /> <Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Foreground" Value="{Binding delay, Converter={StaticResource DelayColorConverter}}" /> <Setter Property="Foreground" Value="{Binding Delay, Converter={StaticResource DelayColorConverter}}" />
</Style> </Style>
</DataGridTextColumn.ElementStyle> </DataGridTextColumn.ElementStyle>
</base:MyDGTextColumn> </base:MyDGTextColumn>
<base:MyDGTextColumn <base:MyDGTextColumn
Width="100" Width="100"
Binding="{Binding speedVal}" Binding="{Binding SpeedVal}"
ExName="speedVal" ExName="SpeedVal"
Header="{x:Static resx:ResUI.LvTestSpeed}"> Header="{x:Static resx:ResUI.LvTestSpeed}">
<DataGridTextColumn.ElementStyle> <DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}"> <Style TargetType="{x:Type TextBlock}">
@ -295,26 +296,26 @@
<base:MyDGTextColumn <base:MyDGTextColumn
x:Name="colTodayUp" x:Name="colTodayUp"
Width="100" Width="100"
Binding="{Binding todayUp}" Binding="{Binding TodayUp}"
ExName="todayUp" ExName="TodayUp"
Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}" /> Header="{x:Static resx:ResUI.LvTodayUploadDataAmount}" />
<base:MyDGTextColumn <base:MyDGTextColumn
x:Name="colTodayDown" x:Name="colTodayDown"
Width="100" Width="100"
Binding="{Binding todayDown}" Binding="{Binding TodayDown}"
ExName="todayDown" ExName="TodayDown"
Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}" /> Header="{x:Static resx:ResUI.LvTodayDownloadDataAmount}" />
<base:MyDGTextColumn <base:MyDGTextColumn
x:Name="colTotalUp" x:Name="colTotalUp"
Width="100" Width="100"
Binding="{Binding totalUp}" Binding="{Binding TotalUp}"
ExName="totalUp" ExName="TotalUp"
Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}" /> Header="{x:Static resx:ResUI.LvTotalUploadDataAmount}" />
<base:MyDGTextColumn <base:MyDGTextColumn
x:Name="colTotalDown" x:Name="colTotalDown"
Width="100" Width="100"
Binding="{Binding totalDown}" Binding="{Binding TotalDown}"
ExName="totalDown" ExName="TotalDown"
Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}" /> Header="{x:Static resx:ResUI.LvTotalDownloadDataAmount}" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View File

@ -46,11 +46,11 @@ namespace v2rayN.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.outboundTag, v => v.cmbOutboundTag.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.outboundTag, v => v.cmbOutboundTag.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Process, v => v.txtProcess.Text).DisposeWith(disposables);

View File

@ -300,11 +300,11 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridCheckBoxColumn <DataGridCheckBoxColumn
Width="60" Width="60"
Binding="{Binding enabled}" Binding="{Binding Enabled}"
Header="" /> Header="" />
<DataGridTextColumn <DataGridTextColumn
Width="150" Width="150"
Binding="{Binding remarks}" Binding="{Binding Remarks}"
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
@ -316,11 +316,11 @@
Header="port" /> Header="port" />
<DataGridTextColumn <DataGridTextColumn
Width="100" Width="100"
Binding="{Binding protocols}" Binding="{Binding Protocols}"
Header="protocol" /> Header="protocol" />
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
Binding="{Binding inboundTags}" Binding="{Binding InboundTags}"
Header="inboundTag" /> Header="inboundTag" />
<DataGridTextColumn <DataGridTextColumn
Width="90" Width="90"
@ -328,11 +328,11 @@
Header="network" /> Header="network" />
<DataGridTextColumn <DataGridTextColumn
Width="200" Width="200"
Binding="{Binding domains}" Binding="{Binding Domains}"
Header="domain" /> Header="domain" />
<DataGridTextColumn <DataGridTextColumn
Width="200" Width="200"
Binding="{Binding ips}" Binding="{Binding Ips}"
Header="ip" /> Header="ip" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View File

@ -36,14 +36,14 @@ namespace v2rayN.Views
this.OneWayBind(ViewModel, vm => vm.RulesItems, v => v.lstRules.ItemsSource).DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.RulesItems, v => v.lstRules.ItemsSource).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRules.SelectedItem).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRules.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.domainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.DomainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.domainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.DomainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.url, v => v.txtUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.Url, v => v.txtUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.customIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.CustomIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.customRulesetPath4Singbox, v => v.txtCustomRulesetPath4Singbox.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.CustomRulesetPath4Singbox, v => v.txtCustomRulesetPath4Singbox.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedRouting.sort, v => v.txtSort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedRouting.Sort, v => v.txtSort.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.RuleAddCmd, v => v.menuRuleAdd).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.RuleAddCmd, v => v.menuRuleAdd).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportRulesFromFileCmd, v => v.menuImportRulesFromFile).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportRulesFromFileCmd, v => v.menuImportRulesFromFile).DisposeWith(disposables);

View File

@ -197,7 +197,7 @@
<DataGrid.Resources> <DataGrid.Resources>
<Style BasedOn="{StaticResource MaterialDesignDataGridCell}" TargetType="DataGridCell"> <Style BasedOn="{StaticResource MaterialDesignDataGridCell}" TargetType="DataGridCell">
<Style.Triggers> <Style.Triggers>
<DataTrigger Binding="{Binding isActive}" Value="True"> <DataTrigger Binding="{Binding IsActive}" Value="True">
<Setter Property="Background" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" /> <Setter Property="Background" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" />
<Setter Property="Foreground" Value="Black" /> <Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" /> <Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.Primary.Light}" />
@ -208,23 +208,23 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn <DataGridTextColumn
Width="250" Width="250"
Binding="{Binding remarks}" Binding="{Binding Remarks}"
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn <DataGridTextColumn
Width="60" Width="60"
Binding="{Binding ruleNum}" Binding="{Binding RuleNum}"
Header="{x:Static resx:ResUI.LvCount}" /> Header="{x:Static resx:ResUI.LvCount}" />
<DataGridTextColumn <DataGridTextColumn
Width="60" Width="60"
Binding="{Binding sort}" Binding="{Binding Sort}"
Header="{x:Static resx:ResUI.LvSort}" /> Header="{x:Static resx:ResUI.LvSort}" />
<DataGridTextColumn <DataGridTextColumn
Width="300" Width="300"
Binding="{Binding url}" Binding="{Binding Url}"
Header="{x:Static resx:ResUI.LvUrl}" /> Header="{x:Static resx:ResUI.LvUrl}" />
<DataGridTextColumn <DataGridTextColumn
Width="300" Width="300"
Binding="{Binding customIcon}" Binding="{Binding CustomIcon}"
Header="{x:Static resx:ResUI.LvCustomIcon}" /> Header="{x:Static resx:ResUI.LvCustomIcon}" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>

View File

@ -77,7 +77,7 @@
Width="160" Width="160"
Margin="{StaticResource MarginLeftRight8}" Margin="{StaticResource MarginLeftRight8}"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
DisplayMemberPath="remarks" DisplayMemberPath="Remarks"
FontSize="{DynamicResource StdFontSize}" FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFloatingHintComboBox}" /> Style="{StaticResource MaterialDesignFloatingHintComboBox}" />
</StackPanel> </StackPanel>
@ -155,7 +155,7 @@
x:Name="cmbRoutings" x:Name="cmbRoutings"
MaxWidth="300" MaxWidth="300"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}" materialDesign:HintAssist.Hint="{x:Static resx:ResUI.menuRouting}"
DisplayMemberPath="remarks" DisplayMemberPath="Remarks"
FontSize="{DynamicResource StdFontSize}" FontSize="{DynamicResource StdFontSize}"
Style="{StaticResource MaterialDesignFilledComboBox}" /> Style="{StaticResource MaterialDesignFilledComboBox}" />
</DockPanel> </DockPanel>

View File

@ -22,18 +22,18 @@ namespace v2rayN.Views
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Remarks, v => v.txtRemarks.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.url, v => v.txtUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Url, v => v.txtUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.moreUrl, v => v.txtMoreUrl.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.MoreUrl, v => v.txtMoreUrl.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnable.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Enabled, v => v.togEnable.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.autoUpdateInterval, v => v.txtAutoUpdateInterval.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.AutoUpdateInterval, v => v.txtAutoUpdateInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.userAgent, v => v.txtUserAgent.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.UserAgent, v => v.txtUserAgent.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.sort, v => v.txtSort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Sort, v => v.txtSort.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.filter, v => v.txtFilter.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Filter, v => v.txtFilter.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.convertTarget, v => v.cmbConvertTarget.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.ConvertTarget, v => v.cmbConvertTarget.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.prevProfile, v => v.txtPrevProfile.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PrevProfile, v => v.txtPrevProfile.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.nextProfile, v => v.txtNextProfile.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.NextProfile, v => v.txtNextProfile.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.preSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.PreSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);
}); });

View File

@ -99,27 +99,27 @@
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn <DataGridTextColumn
Width="120" Width="120"
Binding="{Binding remarks}" Binding="{Binding Remarks}"
Header="{x:Static resx:ResUI.LvRemarks}" /> Header="{x:Static resx:ResUI.LvRemarks}" />
<DataGridTextColumn <DataGridTextColumn
Width="150" Width="150"
Binding="{Binding url}" Binding="{Binding Url}"
Header="{x:Static resx:ResUI.LvUrl}" /> Header="{x:Static resx:ResUI.LvUrl}" />
<DataGridCheckBoxColumn <DataGridCheckBoxColumn
Width="100" Width="100"
Binding="{Binding enabled}" Binding="{Binding Enabled}"
Header="{x:Static resx:ResUI.LvEnabled}" /> Header="{x:Static resx:ResUI.LvEnabled}" />
<DataGridTextColumn <DataGridTextColumn
Width="150" Width="150"
Binding="{Binding autoUpdateInterval}" Binding="{Binding AutoUpdateInterval}"
Header="{x:Static resx:ResUI.LvAutoUpdateInterval}" /> Header="{x:Static resx:ResUI.LvAutoUpdateInterval}" />
<DataGridTextColumn <DataGridTextColumn
Width="150" Width="150"
Binding="{Binding userAgent}" Binding="{Binding UserAgent}"
Header="{x:Static resx:ResUI.LvUserAgent}" /> Header="{x:Static resx:ResUI.LvUserAgent}" />
<DataGridTextColumn <DataGridTextColumn
Width="80" Width="80"
Binding="{Binding sort}" Binding="{Binding Sort}"
Header="{x:Static resx:ResUI.LvSort}" /> Header="{x:Static resx:ResUI.LvSort}" />
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>