mirror of
https://github.com/2dust/v2rayN.git
synced 2026-02-28 21:23:04 +00:00
Compare commits
18 commits
8fb4cb088b
...
f36358dca8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f36358dca8 | ||
|
|
6b1d827dd1 | ||
|
|
1b79d2f560 | ||
|
|
fa8c3f337c | ||
|
|
314fb7c73d | ||
|
|
37734d2de9 | ||
|
|
3b826e3e36 | ||
|
|
323bf70474 | ||
|
|
274fc8084d | ||
|
|
2c454aee95 | ||
|
|
0eae23ace0 | ||
|
|
189ab47fa9 | ||
|
|
7bfd2f504d | ||
|
|
82443a64cd | ||
|
|
ee7d3c60b6 | ||
|
|
2d450357d1 | ||
|
|
1c2d086a71 | ||
|
|
a6b12aa718 |
18 changed files with 133 additions and 177 deletions
|
|
@ -332,20 +332,22 @@ public class Utils
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, List<string>> ParseHostsToDictionary(string? hostsContent)
|
public static Dictionary<string, List<string>> ParseHostsToDictionary(string hostsContent)
|
||||||
{
|
{
|
||||||
if (hostsContent.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
return new();
|
|
||||||
}
|
|
||||||
var userHostsMap = hostsContent
|
var userHostsMap = hostsContent
|
||||||
.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries)
|
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
.Select(line => line.Trim())
|
.Select(line => line.Trim())
|
||||||
// skip full-line comments
|
// skip full-line comments
|
||||||
.Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith('#'))
|
.Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith("#"))
|
||||||
|
// strip inline comments (truncate at '#')
|
||||||
|
.Select(line =>
|
||||||
|
{
|
||||||
|
var index = line.IndexOf('#');
|
||||||
|
return index >= 0 ? line.Substring(0, index).Trim() : line;
|
||||||
|
})
|
||||||
// ensure line still contains valid parts
|
// ensure line still contains valid parts
|
||||||
.Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains(' '))
|
.Where(line => !string.IsNullOrWhiteSpace(line) && line.Contains(' '))
|
||||||
.Select(line => line.Split([' ', '\t'], StringSplitOptions.RemoveEmptyEntries))
|
.Select(line => line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
.Where(parts => parts.Length >= 2)
|
.Where(parts => parts.Length >= 2)
|
||||||
.GroupBy(parts => parts[0])
|
.GroupBy(parts => parts[0])
|
||||||
.ToDictionary(
|
.ToDictionary(
|
||||||
|
|
|
||||||
|
|
@ -722,7 +722,7 @@ public static class ConfigHandler
|
||||||
SalamanderPass = profileItem.GetProtocolExtra().SalamanderPass?.TrimEx(),
|
SalamanderPass = profileItem.GetProtocolExtra().SalamanderPass?.TrimEx(),
|
||||||
UpMbps = profileItem.GetProtocolExtra().UpMbps is null or < 0 ? config.HysteriaItem.UpMbps : profileItem.GetProtocolExtra().UpMbps,
|
UpMbps = profileItem.GetProtocolExtra().UpMbps is null or < 0 ? config.HysteriaItem.UpMbps : profileItem.GetProtocolExtra().UpMbps,
|
||||||
DownMbps = profileItem.GetProtocolExtra().DownMbps is null or < 0 ? config.HysteriaItem.DownMbps : profileItem.GetProtocolExtra().DownMbps,
|
DownMbps = profileItem.GetProtocolExtra().DownMbps is null or < 0 ? config.HysteriaItem.DownMbps : profileItem.GetProtocolExtra().DownMbps,
|
||||||
HopInterval = profileItem.GetProtocolExtra().HopInterval?.TrimEx(),
|
HopInterval = profileItem.GetProtocolExtra().HopInterval is null or <= 5 ? Global.Hysteria2DefaultHopInt : profileItem.GetProtocolExtra().HopInterval,
|
||||||
});
|
});
|
||||||
|
|
||||||
await AddServerCommon(config, profileItem, toFile);
|
await AddServerCommon(config, profileItem, toFile);
|
||||||
|
|
@ -745,8 +745,11 @@ public static class ConfigHandler
|
||||||
profileItem.CoreType = ECoreType.sing_box;
|
profileItem.CoreType = ECoreType.sing_box;
|
||||||
|
|
||||||
profileItem.Address = profileItem.Address.TrimEx();
|
profileItem.Address = profileItem.Address.TrimEx();
|
||||||
profileItem.Username = profileItem.Username.TrimEx();
|
|
||||||
profileItem.Password = profileItem.Password.TrimEx();
|
profileItem.Password = profileItem.Password.TrimEx();
|
||||||
|
profileItem.SetProtocolExtra(profileItem.GetProtocolExtra() with
|
||||||
|
{
|
||||||
|
Username = profileItem.GetProtocolExtra().Username?.TrimEx()
|
||||||
|
});
|
||||||
profileItem.Network = string.Empty;
|
profileItem.Network = string.Empty;
|
||||||
|
|
||||||
if (!Global.TuicCongestionControls.Contains(profileItem.HeaderType))
|
if (!Global.TuicCongestionControls.Contains(profileItem.HeaderType))
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ public class SocksFmt : BaseFmt
|
||||||
remark = "#" + Utils.UrlEncode(item.Remarks);
|
remark = "#" + Utils.UrlEncode(item.Remarks);
|
||||||
}
|
}
|
||||||
//new
|
//new
|
||||||
var pw = Utils.Base64Encode($"{item.Username}:{item.Password}", true);
|
var pw = Utils.Base64Encode($"{item.GetProtocolExtra().Username}:{item.Password}", true);
|
||||||
return ToUri(EConfigType.SOCKS, item.Address, item.Port, pw, null, remark);
|
return ToUri(EConfigType.SOCKS, item.Address, item.Port, pw, null, remark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ public class SocksFmt : BaseFmt
|
||||||
}
|
}
|
||||||
item.Address = arr1[1][..indexPort];
|
item.Address = arr1[1][..indexPort];
|
||||||
item.Port = arr1[1][(indexPort + 1)..].ToInt();
|
item.Port = arr1[1][(indexPort + 1)..].ToInt();
|
||||||
item.Username = arr21.First();
|
item.SetProtocolExtra(item.GetProtocolExtra() with { Username = arr21.First() });
|
||||||
item.Password = arr21[1];
|
item.Password = arr21[1];
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +103,7 @@ public class SocksFmt : BaseFmt
|
||||||
var userInfoParts = userInfo.Split([':'], 2);
|
var userInfoParts = userInfo.Split([':'], 2);
|
||||||
if (userInfoParts.Length == 2)
|
if (userInfoParts.Length == 2)
|
||||||
{
|
{
|
||||||
item.Username = userInfoParts.First();
|
item.SetProtocolExtra(item.GetProtocolExtra() with { Username = userInfoParts.First() });
|
||||||
item.Password = userInfoParts[1];
|
item.Password = userInfoParts[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ public class TuicFmt : BaseFmt
|
||||||
var userInfoParts = rawUserInfo.Split(new[] { ':' }, 2);
|
var userInfoParts = rawUserInfo.Split(new[] { ':' }, 2);
|
||||||
if (userInfoParts.Length == 2)
|
if (userInfoParts.Length == 2)
|
||||||
{
|
{
|
||||||
item.Username = userInfoParts.First();
|
item.Password = userInfoParts.First();
|
||||||
item.Password = userInfoParts.Last();
|
item.SetProtocolExtra(item.GetProtocolExtra() with { Username = userInfoParts.Last() });
|
||||||
}
|
}
|
||||||
|
|
||||||
var query = Utils.ParseQueryString(url.Query);
|
var query = Utils.ParseQueryString(url.Query);
|
||||||
|
|
@ -53,6 +53,6 @@ public class TuicFmt : BaseFmt
|
||||||
|
|
||||||
dicQuery.Add("congestion_control", item.HeaderType);
|
dicQuery.Add("congestion_control", item.HeaderType);
|
||||||
|
|
||||||
return ToUri(EConfigType.TUIC, item.Address, item.Port, $"{item.Username ?? ""}:{item.Password}", dicQuery, remark);
|
return ToUri(EConfigType.TUIC, item.Address, item.Port, $"{item.GetProtocolExtra().Username ?? ""}:{item.Password}", dicQuery, remark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
using ServiceLib.Common;
|
||||||
|
|
||||||
namespace ServiceLib.Manager;
|
namespace ServiceLib.Manager;
|
||||||
|
|
||||||
public sealed class AppManager
|
public sealed class AppManager
|
||||||
|
|
@ -96,10 +98,7 @@ public sealed class AppManager
|
||||||
_ = StatePort;
|
_ = StatePort;
|
||||||
_ = StatePort2;
|
_ = StatePort2;
|
||||||
|
|
||||||
Task.Run(async () =>
|
_ = MigrateProfileExtra();
|
||||||
{
|
|
||||||
await MigrateProfileExtra();
|
|
||||||
}).Wait();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -280,33 +279,29 @@ public sealed class AppManager
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var batchSuccessCount = 0;
|
|
||||||
foreach (var item in batch)
|
foreach (var item in batch)
|
||||||
{
|
{
|
||||||
try
|
var extra = item.GetProtocolExtra();
|
||||||
{
|
|
||||||
var extra = item.GetProtocolExtra();
|
|
||||||
|
|
||||||
if (item.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
if (item.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
|
||||||
|
{
|
||||||
|
extra = extra with { GroupType = nameof(item.ConfigType) };
|
||||||
|
groupItems.TryGetValue(item.IndexId, out var groupItem);
|
||||||
|
if (groupItem != null && !groupItem.NotHasChild())
|
||||||
{
|
{
|
||||||
extra = extra with { GroupType = nameof(item.ConfigType) };
|
extra = extra with
|
||||||
groupItems.TryGetValue(item.IndexId, out var groupItem);
|
|
||||||
if (groupItem != null && !groupItem.NotHasChild())
|
|
||||||
{
|
{
|
||||||
extra = extra with
|
ChildItems = groupItem.ChildItems,
|
||||||
{
|
SubChildItems = groupItem.SubChildItems,
|
||||||
ChildItems = groupItem.ChildItems,
|
Filter = groupItem.Filter,
|
||||||
SubChildItems = groupItem.SubChildItems,
|
MultipleLoad = groupItem.MultipleLoad,
|
||||||
Filter = groupItem.Filter,
|
};
|
||||||
MultipleLoad = groupItem.MultipleLoad,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (item.ConfigType)
|
switch (item.ConfigType)
|
||||||
{
|
{
|
||||||
case EConfigType.Shadowsocks:
|
case EConfigType.Shadowsocks:
|
||||||
extra = extra with { SsMethod = item.Security.NullIfEmpty() };
|
extra = extra with {SsMethod = item.Security.NullIfEmpty() };
|
||||||
break;
|
break;
|
||||||
case EConfigType.VMess:
|
case EConfigType.VMess:
|
||||||
extra = extra with
|
extra = extra with
|
||||||
|
|
@ -319,7 +314,6 @@ public sealed class AppManager
|
||||||
extra = extra with
|
extra = extra with
|
||||||
{
|
{
|
||||||
Flow = item.Flow.NullIfEmpty(),
|
Flow = item.Flow.NullIfEmpty(),
|
||||||
VlessEncryption = item.Security,
|
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case EConfigType.Hysteria2:
|
case EConfigType.Hysteria2:
|
||||||
|
|
@ -329,18 +323,17 @@ public sealed class AppManager
|
||||||
Ports = item.Ports.NullIfEmpty(),
|
Ports = item.Ports.NullIfEmpty(),
|
||||||
UpMbps = _config.HysteriaItem.UpMbps,
|
UpMbps = _config.HysteriaItem.UpMbps,
|
||||||
DownMbps = _config.HysteriaItem.DownMbps,
|
DownMbps = _config.HysteriaItem.DownMbps,
|
||||||
HopInterval = _config.HysteriaItem.HopInterval.ToString(),
|
HopInterval = _config.HysteriaItem.HopInterval
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
item.Username = item.Id;
|
extra = extra with
|
||||||
|
{
|
||||||
|
Username = item.Id,
|
||||||
|
};
|
||||||
item.Id = item.Security;
|
item.Id = item.Security;
|
||||||
item.Password = item.Security;
|
item.Password = item.Security;
|
||||||
break;
|
break;
|
||||||
case EConfigType.HTTP:
|
|
||||||
case EConfigType.SOCKS:
|
|
||||||
item.Username = item.Security;
|
|
||||||
break;
|
|
||||||
case EConfigType.WireGuard:
|
case EConfigType.WireGuard:
|
||||||
extra = extra with
|
extra = extra with
|
||||||
{
|
{
|
||||||
|
|
@ -351,24 +344,17 @@ public sealed class AppManager
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.SetProtocolExtra(extra);
|
|
||||||
|
|
||||||
item.Password = item.Id;
|
|
||||||
|
|
||||||
item.ConfigVersion = 3;
|
|
||||||
await SQLiteHelper.Instance.UpdateAsync(item);
|
|
||||||
batchSuccessCount++;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog($"MigrateProfileExtra Error: {ex}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.SetProtocolExtra(extra);
|
||||||
|
|
||||||
|
item.Password = item.Id;
|
||||||
|
|
||||||
|
item.ConfigVersion = 3;
|
||||||
|
await SQLiteHelper.Instance.UpdateAsync(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only increment offset by the number of failed items that remain in the result set
|
offset += pageSize;
|
||||||
// Successfully updated items are automatically excluded from future queries due to ConfigVersion = 3
|
|
||||||
offset += batch.Count - batchSuccessCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ public class ProfileItem : ReactiveObject
|
||||||
Address = string.Empty;
|
Address = string.Empty;
|
||||||
Port = 0;
|
Port = 0;
|
||||||
Password = string.Empty;
|
Password = string.Empty;
|
||||||
Username = string.Empty;
|
|
||||||
Network = string.Empty;
|
Network = string.Empty;
|
||||||
Remarks = string.Empty;
|
Remarks = string.Empty;
|
||||||
HeaderType = string.Empty;
|
HeaderType = string.Empty;
|
||||||
|
|
@ -152,7 +151,6 @@ public class ProfileItem : ReactiveObject
|
||||||
public string Address { get; set; }
|
public string Address { get; set; }
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public string Username { get; set; }
|
|
||||||
public string Network { get; set; }
|
public string Network { get; set; }
|
||||||
public string Remarks { get; set; }
|
public string Remarks { get; set; }
|
||||||
public string HeaderType { get; set; }
|
public string HeaderType { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ public record ProtocolExtraItem
|
||||||
//public string? PluginArgs { get; init; }
|
//public string? PluginArgs { get; init; }
|
||||||
public string? SsMethod { get; init; }
|
public string? SsMethod { get; init; }
|
||||||
|
|
||||||
|
// socks and http
|
||||||
|
public string? Username { get; init; }
|
||||||
|
|
||||||
// wireguard
|
// wireguard
|
||||||
public string? WgPublicKey { get; init; }
|
public string? WgPublicKey { get; init; }
|
||||||
public string? WgPresharedKey { get; init; }
|
public string? WgPresharedKey { get; init; }
|
||||||
|
|
@ -27,7 +30,7 @@ public record ProtocolExtraItem
|
||||||
public int? UpMbps { get; init; }
|
public int? UpMbps { get; init; }
|
||||||
public int? DownMbps { get; init; }
|
public int? DownMbps { get; init; }
|
||||||
public string? Ports { get; init; }
|
public string? Ports { get; init; }
|
||||||
public string? HopInterval { get; init; }
|
public int? HopInterval { get; init; }
|
||||||
|
|
||||||
// group profile
|
// group profile
|
||||||
public string? GroupType { get; init; }
|
public string? GroupType { get; init; }
|
||||||
|
|
|
||||||
|
|
@ -473,7 +473,7 @@ public class HysteriaSettings4Ray
|
||||||
public class HysteriaUdpHop4Ray
|
public class HysteriaUdpHop4Ray
|
||||||
{
|
{
|
||||||
public string? ports { get; set; }
|
public string? ports { get; set; }
|
||||||
public string? interval { get; set; }
|
public int? interval { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FinalMask4Ray
|
public class FinalMask4Ray
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,14 @@ public partial class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var kvp in Utils.ParseHostsToDictionary(simpleDNSItem.Hosts))
|
if (!simpleDNSItem.Hosts.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
hostsDns.predefined[kvp.Key] = kvp.Value.Where(s => Utils.IsIpAddress(s)).ToList();
|
var userHostsMap = Utils.ParseHostsToDictionary(simpleDNSItem.Hosts);
|
||||||
|
|
||||||
|
foreach (var kvp in userHostsMap)
|
||||||
|
{
|
||||||
|
hostsDns.predefined[kvp.Key] = kvp.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var host in hostsDns.predefined)
|
foreach (var host in hostsDns.predefined)
|
||||||
|
|
@ -110,7 +115,7 @@ public partial class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
|
|
||||||
singboxConfig.dns ??= new Dns4Sbox();
|
singboxConfig.dns ??= new Dns4Sbox();
|
||||||
singboxConfig.dns.servers ??= [];
|
singboxConfig.dns.servers ??= new List<Server4Sbox>();
|
||||||
singboxConfig.dns.servers.Add(remoteDns);
|
singboxConfig.dns.servers.Add(remoteDns);
|
||||||
singboxConfig.dns.servers.Add(directDns);
|
singboxConfig.dns.servers.Add(directDns);
|
||||||
singboxConfig.dns.servers.Add(hostsDns);
|
singboxConfig.dns.servers.Add(hostsDns);
|
||||||
|
|
@ -186,56 +191,13 @@ public partial class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var kvp in Utils.ParseHostsToDictionary(simpleDNSItem.Hosts))
|
|
||||||
{
|
|
||||||
var predefined = kvp.Value.First();
|
|
||||||
if (predefined.IsNullOrEmpty() || Utils.IsIpAddress(predefined))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (predefined.StartsWith('#') && int.TryParse(predefined.AsSpan(1), out var rcode))
|
|
||||||
{
|
|
||||||
// xray syntactic sugar for predefined
|
|
||||||
// etc. #0 -> NOERROR
|
|
||||||
singboxConfig.dns.rules.Add(new()
|
|
||||||
{
|
|
||||||
query_type = [1, 28],
|
|
||||||
domain = [kvp.Key],
|
|
||||||
action = "predefined",
|
|
||||||
rcode = rcode switch
|
|
||||||
{
|
|
||||||
0 => "NOERROR",
|
|
||||||
1 => "FORMERR",
|
|
||||||
2 => "SERVFAIL",
|
|
||||||
3 => "NXDOMAIN",
|
|
||||||
4 => "NOTIMP",
|
|
||||||
5 => "REFUSED",
|
|
||||||
_ => "NOERROR",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// CNAME record
|
|
||||||
Rule4Sbox rule = new()
|
|
||||||
{
|
|
||||||
query_type = [1, 28],
|
|
||||||
action = "predefined",
|
|
||||||
rcode = "NOERROR",
|
|
||||||
answer = [$"*. IN CNAME {predefined}."],
|
|
||||||
};
|
|
||||||
if (ParseV2Domain(kvp.Key, rule))
|
|
||||||
{
|
|
||||||
singboxConfig.dns.rules.Add(rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (ech, _) = ParseEchParam(node?.EchConfigList);
|
var (ech, _) = ParseEchParam(node?.EchConfigList);
|
||||||
if (ech is not null)
|
if (ech is not null)
|
||||||
{
|
{
|
||||||
var echDomain = ech.query_server_name ?? node?.Sni;
|
var echDomain = ech.query_server_name ?? node?.Sni;
|
||||||
singboxConfig.dns.rules.Add(new()
|
singboxConfig.dns.rules.Add(new()
|
||||||
{
|
{
|
||||||
query_type = [64, 65],
|
query_type = new List<int> { 64, 65 },
|
||||||
server = Global.SingboxEchDNSTag,
|
server = Global.SingboxEchDNSTag,
|
||||||
domain = echDomain is not null ? new List<string> { echDomain } : null,
|
domain = echDomain is not null ? new List<string> { echDomain } : null,
|
||||||
});
|
});
|
||||||
|
|
@ -247,7 +209,7 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
singboxConfig.dns.rules.Add(new()
|
singboxConfig.dns.rules.Add(new()
|
||||||
{
|
{
|
||||||
query_type = [64, 65],
|
query_type = new List<int> { 64, 65 },
|
||||||
server = Global.SingboxEchDNSTag,
|
server = Global.SingboxEchDNSTag,
|
||||||
domain = queryServerNames,
|
domain = queryServerNames,
|
||||||
});
|
});
|
||||||
|
|
@ -258,9 +220,9 @@ public partial class CoreConfigSingboxService
|
||||||
{
|
{
|
||||||
singboxConfig.dns.rules.Add(new()
|
singboxConfig.dns.rules.Add(new()
|
||||||
{
|
{
|
||||||
query_type = [64, 65],
|
query_type = new List<int> { 64, 65 },
|
||||||
action = "predefined",
|
action = "predefined",
|
||||||
rcode = "NOERROR"
|
rcode = "NOTIMP"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,14 +236,13 @@ public partial class CoreConfigSingboxService
|
||||||
type = "logical",
|
type = "logical",
|
||||||
mode = "and",
|
mode = "and",
|
||||||
rewrite_ttl = 1,
|
rewrite_ttl = 1,
|
||||||
rules =
|
rules = new List<Rule4Sbox>
|
||||||
[
|
{
|
||||||
new()
|
new() {
|
||||||
{
|
query_type = new List<int> { 1, 28 }, // A and AAAA
|
||||||
query_type = [1, 28], // A and AAAA
|
|
||||||
},
|
},
|
||||||
fakeipFilterRule
|
fakeipFilterRule,
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
singboxConfig.dns.rules.Add(rule4Fake);
|
singboxConfig.dns.rules.Add(rule4Fake);
|
||||||
|
|
@ -301,7 +262,7 @@ public partial class CoreConfigSingboxService
|
||||||
if (!string.IsNullOrEmpty(simpleDNSItem?.DirectExpectedIPs))
|
if (!string.IsNullOrEmpty(simpleDNSItem?.DirectExpectedIPs))
|
||||||
{
|
{
|
||||||
var ipItems = simpleDNSItem.DirectExpectedIPs
|
var ipItems = simpleDNSItem.DirectExpectedIPs
|
||||||
.Split([',', ';'], StringSplitOptions.RemoveEmptyEntries)
|
.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
.Select(s => s.Trim())
|
.Select(s => s.Trim())
|
||||||
.Where(s => !string.IsNullOrEmpty(s))
|
.Where(s => !string.IsNullOrEmpty(s))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
|
||||||
|
|
@ -90,20 +90,20 @@ public partial class CoreConfigSingboxService
|
||||||
case EConfigType.SOCKS:
|
case EConfigType.SOCKS:
|
||||||
{
|
{
|
||||||
outbound.version = "5";
|
outbound.version = "5";
|
||||||
if (node.Username.IsNotEmpty()
|
if (protocolExtra.Username.IsNotEmpty()
|
||||||
&& node.Password.IsNotEmpty())
|
&& node.Password.IsNotEmpty())
|
||||||
{
|
{
|
||||||
outbound.username = node.Username;
|
outbound.username = protocolExtra.Username;
|
||||||
outbound.password = node.Password;
|
outbound.password = node.Password;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EConfigType.HTTP:
|
case EConfigType.HTTP:
|
||||||
{
|
{
|
||||||
if (node.Username.IsNotEmpty()
|
if (protocolExtra.Username.IsNotEmpty()
|
||||||
&& node.Password.IsNotEmpty())
|
&& node.Password.IsNotEmpty())
|
||||||
{
|
{
|
||||||
outbound.username = node.Username;
|
outbound.username = protocolExtra.Username;
|
||||||
outbound.password = node.Password;
|
outbound.password = node.Password;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -114,13 +114,13 @@ public partial class CoreConfigSingboxService
|
||||||
|
|
||||||
outbound.packet_encoding = "xudp";
|
outbound.packet_encoding = "xudp";
|
||||||
|
|
||||||
if (!protocolExtra.Flow.IsNullOrEmpty())
|
if (protocolExtra.Flow.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
outbound.flow = protocolExtra.Flow;
|
await GenOutboundMux(node, outbound);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await GenOutboundMux(node, outbound);
|
outbound.flow = protocolExtra.Flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
await GenOutboundTransport(node, outbound);
|
await GenOutboundTransport(node, outbound);
|
||||||
|
|
@ -149,10 +149,10 @@ public partial class CoreConfigSingboxService
|
||||||
|
|
||||||
outbound.up_mbps = protocolExtra?.UpMbps is { } su and >= 0
|
outbound.up_mbps = protocolExtra?.UpMbps is { } su and >= 0
|
||||||
? su
|
? su
|
||||||
: _config.HysteriaItem.UpMbps;
|
: 0;
|
||||||
outbound.down_mbps = protocolExtra?.DownMbps is { } sd and >= 0
|
outbound.down_mbps = protocolExtra?.DownMbps is { } sd and >= 0
|
||||||
? sd
|
? sd
|
||||||
: _config.HysteriaItem.DownMbps;
|
: 0;
|
||||||
var ports = protocolExtra?.Ports?.IsNullOrEmpty() == false ? protocolExtra.Ports : null;
|
var ports = protocolExtra?.Ports?.IsNullOrEmpty() == false ? protocolExtra.Ports : null;
|
||||||
if ((!ports.IsNullOrEmpty()) && (ports.Contains(':') || ports.Contains('-') || ports.Contains(',')))
|
if ((!ports.IsNullOrEmpty()) && (ports.Contains(':') || ports.Contains('-') || ports.Contains(',')))
|
||||||
{
|
{
|
||||||
|
|
@ -166,31 +166,16 @@ public partial class CoreConfigSingboxService
|
||||||
return port.Contains(':') ? port : $"{port}:{port}";
|
return port.Contains(':') ? port : $"{port}:{port}";
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
outbound.hop_interval = _config.HysteriaItem.HopInterval >= 5
|
outbound.hop_interval = protocolExtra?.HopInterval is { } hi and >= 5
|
||||||
? $"{_config.HysteriaItem.HopInterval}s"
|
? $"{hi}s"
|
||||||
: $"{Global.Hysteria2DefaultHopInt}s";
|
: _config.HysteriaItem.HopInterval >= 5 ? $"{_config.HysteriaItem.HopInterval}s" : $"{Global.Hysteria2DefaultHopInt}s";
|
||||||
if (int.TryParse(protocolExtra.HopInterval, out var hiResult))
|
|
||||||
{
|
|
||||||
outbound.hop_interval = hiResult >= 5 ? $"{hiResult}s" : outbound.hop_interval;
|
|
||||||
}
|
|
||||||
else if (protocolExtra.HopInterval?.Contains('-') ?? false)
|
|
||||||
{
|
|
||||||
// may be a range like 5-10
|
|
||||||
var parts = protocolExtra.HopInterval.Split('-');
|
|
||||||
if (parts.Length == 2 && int.TryParse(parts[0], out var hiL) &&
|
|
||||||
int.TryParse(parts[0], out var hiH))
|
|
||||||
{
|
|
||||||
var hi = (hiL + hiH) / 2;
|
|
||||||
outbound.hop_interval = hi >= 5 ? $"{hi}s" : outbound.hop_interval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
{
|
{
|
||||||
outbound.uuid = node.Username;
|
outbound.uuid = protocolExtra.Username;
|
||||||
outbound.password = node.Password;
|
outbound.password = node.Password;
|
||||||
outbound.congestion_control = node.HeaderType;
|
outbound.congestion_control = node.HeaderType;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,14 @@ public partial class CoreConfigSingboxService
|
||||||
var dnsItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
|
var dnsItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
|
||||||
if (dnsItem == null || !dnsItem.Enabled)
|
if (dnsItem == null || !dnsItem.Enabled)
|
||||||
{
|
{
|
||||||
var userHostsMap = Utils.ParseHostsToDictionary(simpleDnsItem.Hosts);
|
if (!simpleDnsItem.Hosts.IsNullOrEmpty())
|
||||||
hostsDomains.AddRange(userHostsMap.Select(kvp => kvp.Key));
|
{
|
||||||
|
var userHostsMap = Utils.ParseHostsToDictionary(simpleDnsItem.Hosts);
|
||||||
|
foreach (var kvp in userHostsMap)
|
||||||
|
{
|
||||||
|
hostsDomains.Add(kvp.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (simpleDnsItem.UseSystemHosts == true)
|
if (simpleDnsItem.UseSystemHosts == true)
|
||||||
{
|
{
|
||||||
var systemHostsMap = Utils.GetSystemHosts();
|
var systemHostsMap = Utils.GetSystemHosts();
|
||||||
|
|
|
||||||
|
|
@ -333,9 +333,14 @@ public partial class CoreConfigV2rayService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var kvp in Utils.ParseHostsToDictionary(simpleDNSItem.Hosts))
|
if (!simpleDNSItem.Hosts.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
dnsItem.hosts[kvp.Key] = kvp.Value;
|
var userHostsMap = Utils.ParseHostsToDictionary(simpleDNSItem.Hosts);
|
||||||
|
|
||||||
|
foreach (var kvp in userHostsMap)
|
||||||
|
{
|
||||||
|
dnsItem.hosts[kvp.Key] = kvp.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return await Task.FromResult(0);
|
return await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,12 +97,12 @@ public partial class CoreConfigV2rayService
|
||||||
serversItem.method = null;
|
serversItem.method = null;
|
||||||
serversItem.password = null;
|
serversItem.password = null;
|
||||||
|
|
||||||
if (node.Username.IsNotEmpty()
|
if (protocolExtra.Username.IsNotEmpty()
|
||||||
&& node.Password.IsNotEmpty())
|
&& node.Password.IsNotEmpty())
|
||||||
{
|
{
|
||||||
SocksUsersItem4Ray socksUsersItem = new()
|
SocksUsersItem4Ray socksUsersItem = new()
|
||||||
{
|
{
|
||||||
user = node.Username ?? "",
|
user = protocolExtra.Username ?? "",
|
||||||
pass = node.Password,
|
pass = node.Password,
|
||||||
level = 1
|
level = 1
|
||||||
};
|
};
|
||||||
|
|
@ -144,12 +144,13 @@ public partial class CoreConfigV2rayService
|
||||||
usersItem.email = Global.UserEMail;
|
usersItem.email = Global.UserEMail;
|
||||||
usersItem.encryption = protocolExtra.VlessEncryption;
|
usersItem.encryption = protocolExtra.VlessEncryption;
|
||||||
|
|
||||||
if (!protocolExtra.Flow.IsNullOrEmpty())
|
if (protocolExtra.Flow.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
usersItem.flow = protocolExtra.Flow;
|
await GenOutboundMux(node, outbound, muxEnabled, muxEnabled);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
usersItem.flow = protocolExtra.Flow;
|
||||||
await GenOutboundMux(node, outbound, false, muxEnabled);
|
await GenOutboundMux(node, outbound, false, muxEnabled);
|
||||||
}
|
}
|
||||||
outbound.settings.servers = null;
|
outbound.settings.servers = null;
|
||||||
|
|
@ -514,15 +515,13 @@ public partial class CoreConfigV2rayService
|
||||||
var ports = protocolExtra?.Ports;
|
var ports = protocolExtra?.Ports;
|
||||||
int? upMbps = protocolExtra?.UpMbps is { } su and >= 0
|
int? upMbps = protocolExtra?.UpMbps is { } su and >= 0
|
||||||
? su
|
? su
|
||||||
: _config.HysteriaItem.UpMbps;
|
: 0;
|
||||||
int? downMbps = protocolExtra?.DownMbps is { } sd and >= 0
|
int? downMbps = protocolExtra?.DownMbps is { } sd and >= 0
|
||||||
? sd
|
? sd
|
||||||
: _config.HysteriaItem.UpMbps;
|
: 0;
|
||||||
var hopInterval = !protocolExtra.HopInterval.IsNullOrEmpty()
|
var hopInterval = protocolExtra?.HopInterval is { } hi and >= 5
|
||||||
? protocolExtra.HopInterval
|
? hi
|
||||||
: (_config.HysteriaItem.HopInterval >= 5
|
: _config.HysteriaItem.HopInterval >= 5 ? _config.HysteriaItem.HopInterval : Global.Hysteria2DefaultHopInt;
|
||||||
? _config.HysteriaItem.HopInterval
|
|
||||||
: Global.Hysteria2DefaultHopInt).ToString();
|
|
||||||
HysteriaUdpHop4Ray? udpHop = null;
|
HysteriaUdpHop4Ray? udpHop = null;
|
||||||
if (!ports.IsNullOrEmpty() &&
|
if (!ports.IsNullOrEmpty() &&
|
||||||
(ports.Contains(':') || ports.Contains('-') || ports.Contains(',')))
|
(ports.Contains(':') || ports.Contains('-') || ports.Contains(',')))
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
public int DownMbps { get; set; }
|
public int DownMbps { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string HopInterval { get; set; }
|
public int HopInterval { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string Flow { get; set; }
|
public string Flow { get; set; }
|
||||||
|
|
@ -47,6 +47,9 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string SsMethod { get; set; }
|
public string SsMethod { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public string Username { get; set; }
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string WgPublicKey { get; set; }
|
public string WgPublicKey { get; set; }
|
||||||
//[Reactive]
|
//[Reactive]
|
||||||
|
|
@ -110,12 +113,13 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
AlterId = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0;
|
AlterId = int.TryParse(protocolExtra?.AlterId, out var result) ? result : 0;
|
||||||
Flow = protocolExtra?.Flow ?? string.Empty;
|
Flow = protocolExtra?.Flow ?? string.Empty;
|
||||||
SalamanderPass = protocolExtra?.SalamanderPass ?? string.Empty;
|
SalamanderPass = protocolExtra?.SalamanderPass ?? string.Empty;
|
||||||
UpMbps = protocolExtra?.UpMbps ?? _config.HysteriaItem.UpMbps;
|
UpMbps = protocolExtra?.UpMbps ?? 0;
|
||||||
DownMbps = protocolExtra?.DownMbps ?? _config.HysteriaItem.DownMbps;
|
DownMbps = protocolExtra?.DownMbps ?? 0;
|
||||||
HopInterval = protocolExtra?.HopInterval.IsNullOrEmpty() ?? true ? Global.Hysteria2DefaultHopInt.ToString() : protocolExtra.HopInterval;
|
HopInterval = protocolExtra?.HopInterval ?? Global.Hysteria2DefaultHopInt;
|
||||||
VmessSecurity = protocolExtra?.VmessSecurity?.IsNullOrEmpty() == false ? protocolExtra.VmessSecurity : Global.DefaultSecurity;
|
VmessSecurity = protocolExtra?.VmessSecurity?.IsNullOrEmpty() == false ? protocolExtra.VmessSecurity : Global.DefaultSecurity;
|
||||||
VlessEncryption = protocolExtra?.VlessEncryption.IsNullOrEmpty() == false ? protocolExtra.VlessEncryption : Global.None;
|
VlessEncryption = protocolExtra?.VlessEncryption.IsNullOrEmpty() == false ? protocolExtra.VlessEncryption : Global.None;
|
||||||
SsMethod = protocolExtra?.SsMethod ?? string.Empty;
|
SsMethod = protocolExtra?.SsMethod ?? string.Empty;
|
||||||
|
Username = protocolExtra?.Username ?? string.Empty;
|
||||||
WgPublicKey = protocolExtra?.WgPublicKey ?? string.Empty;
|
WgPublicKey = protocolExtra?.WgPublicKey ?? string.Empty;
|
||||||
WgInterfaceAddress = protocolExtra?.WgInterfaceAddress ?? string.Empty;
|
WgInterfaceAddress = protocolExtra?.WgInterfaceAddress ?? string.Empty;
|
||||||
WgReserved = protocolExtra?.WgReserved ?? string.Empty;
|
WgReserved = protocolExtra?.WgReserved ?? string.Empty;
|
||||||
|
|
@ -172,12 +176,13 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
AlterId = AlterId > 0 ? AlterId.ToString() : null,
|
AlterId = AlterId > 0 ? AlterId.ToString() : null,
|
||||||
Flow = Flow.NullIfEmpty(),
|
Flow = Flow.NullIfEmpty(),
|
||||||
SalamanderPass = SalamanderPass.NullIfEmpty(),
|
SalamanderPass = SalamanderPass.NullIfEmpty(),
|
||||||
UpMbps = UpMbps >= 0 ? UpMbps : null,
|
UpMbps = UpMbps > 0 ? UpMbps : null,
|
||||||
DownMbps = DownMbps >= 0 ? DownMbps : null,
|
DownMbps = DownMbps > 0 ? DownMbps : null,
|
||||||
HopInterval = HopInterval.NullIfEmpty(),
|
HopInterval = HopInterval >= 5 ? HopInterval : null,
|
||||||
VmessSecurity = VmessSecurity.NullIfEmpty(),
|
VmessSecurity = VmessSecurity.NullIfEmpty(),
|
||||||
VlessEncryption = VlessEncryption.NullIfEmpty(),
|
VlessEncryption = VlessEncryption.NullIfEmpty(),
|
||||||
SsMethod = SsMethod.NullIfEmpty(),
|
SsMethod = SsMethod.NullIfEmpty(),
|
||||||
|
Username = Username.NullIfEmpty(),
|
||||||
WgPublicKey = WgPublicKey.NullIfEmpty(),
|
WgPublicKey = WgPublicKey.NullIfEmpty(),
|
||||||
WgInterfaceAddress = WgInterfaceAddress.NullIfEmpty(),
|
WgInterfaceAddress = WgInterfaceAddress.NullIfEmpty(),
|
||||||
WgReserved = WgReserved.NullIfEmpty(),
|
WgReserved = WgReserved.NullIfEmpty(),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Avalonia.Controls;
|
||||||
using v2rayN.Desktop.Base;
|
using v2rayN.Desktop.Base;
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views;
|
namespace v2rayN.Desktop.Views;
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
case EConfigType.SOCKS:
|
case EConfigType.SOCKS:
|
||||||
case EConfigType.HTTP:
|
case EConfigType.HTTP:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId4.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId4.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtSecurity4.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.Username, v => v.txtSecurity4.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.VLESS:
|
case EConfigType.VLESS:
|
||||||
|
|
@ -152,7 +152,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, 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;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace v2rayN.Views;
|
namespace v2rayN.Views;
|
||||||
|
|
||||||
public partial class AddGroupServerWindow
|
public partial class AddGroupServerWindow
|
||||||
|
|
@ -156,11 +158,11 @@ public partial class AddGroupServerWindow
|
||||||
lstChild.SelectAll();
|
lstChild.SelectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void TabControl_SelectionChanged(object? sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
private async void TabControl_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (e.Source is not System.Windows.Controls.TabControl tc)
|
if (e.Source is not TabControl tc)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ public partial class AddServerWindow
|
||||||
case EConfigType.SOCKS:
|
case EConfigType.SOCKS:
|
||||||
case EConfigType.HTTP:
|
case EConfigType.HTTP:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId4.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId4.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtSecurity4.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.Username, v => v.txtSecurity4.Text).DisposeWith(disposables);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.VLESS:
|
case EConfigType.VLESS:
|
||||||
|
|
@ -147,7 +147,7 @@ public partial class AddServerWindow
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EConfigType.TUIC:
|
case EConfigType.TUIC:
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.Password, 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;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue