Hy2 SalamanderPass

This commit is contained in:
DHR60 2026-02-05 13:15:04 +08:00
parent 37734d2de9
commit 314fb7c73d
9 changed files with 54 additions and 39 deletions

View file

@ -707,7 +707,6 @@ public static class ConfigHandler
profileItem.Address = profileItem.Address.TrimEx(); profileItem.Address = profileItem.Address.TrimEx();
profileItem.Password = profileItem.Password.TrimEx(); profileItem.Password = profileItem.Password.TrimEx();
profileItem.Path = profileItem.Path.TrimEx();
profileItem.Network = string.Empty; profileItem.Network = string.Empty;
if (profileItem.StreamSecurity.IsNullOrEmpty()) if (profileItem.StreamSecurity.IsNullOrEmpty())
@ -720,6 +719,7 @@ public static class ConfigHandler
} }
profileItem.SetProtocolExtra(profileItem.GetProtocolExtra() with profileItem.SetProtocolExtra(profileItem.GetProtocolExtra() with
{ {
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 is null or <= 5 ? Global.Hysteria2DefaultHopInt : profileItem.GetProtocolExtra().HopInterval, HopInterval = profileItem.GetProtocolExtra().HopInterval is null or <= 5 ? Global.Hysteria2DefaultHopInt : profileItem.GetProtocolExtra().HopInterval,
@ -1119,6 +1119,7 @@ public static class ConfigHandler
&& AreEqual(o.Path, n.Path) && AreEqual(o.Path, n.Path)
&& (o.ConfigType == EConfigType.Trojan || o.StreamSecurity == n.StreamSecurity) && (o.ConfigType == EConfigType.Trojan || o.StreamSecurity == n.StreamSecurity)
&& AreEqual(oProtocolExtra.Flow, nProtocolExtra.Flow) && AreEqual(oProtocolExtra.Flow, nProtocolExtra.Flow)
&& AreEqual(oProtocolExtra.SalamanderPass, nProtocolExtra.SalamanderPass)
&& AreEqual(o.Sni, n.Sni) && AreEqual(o.Sni, n.Sni)
&& AreEqual(o.Alpn, n.Alpn) && AreEqual(o.Alpn, n.Alpn)
&& AreEqual(o.Fingerprint, n.Fingerprint) && AreEqual(o.Fingerprint, n.Fingerprint)

View file

@ -23,16 +23,15 @@ public class Hysteria2Fmt : BaseFmt
var query = Utils.ParseQueryString(url.Query); var query = Utils.ParseQueryString(url.Query);
ResolveUriQuery(query, ref item); ResolveUriQuery(query, ref item);
item.Path = GetQueryDecoded(query, "obfs-password");
if (item.CertSha.IsNullOrEmpty()) if (item.CertSha.IsNullOrEmpty())
{ {
item.CertSha = GetQueryDecoded(query, "pinSHA256"); item.CertSha = GetQueryDecoded(query, "pinSHA256");
} }
ProtocolExtraItem extraItem = new() item.SetProtocolExtra(item.GetProtocolExtra() with
{ {
Ports = GetQueryDecoded(query, "mport") Ports = GetQueryDecoded(query, "mport"),
}; SalamanderPass = GetQueryDecoded(query, "obfs-password"),
item.SetProtocolExtra(extraItem); });
return item; return item;
} }
@ -53,15 +52,16 @@ public class Hysteria2Fmt : BaseFmt
} }
var dicQuery = new Dictionary<string, string>(); var dicQuery = new Dictionary<string, string>();
ToUriQueryLite(item, ref dicQuery); ToUriQueryLite(item, ref dicQuery);
var protocolExtraItem = item.GetProtocolExtra();
if (item.Path.IsNotEmpty()) if (!protocolExtraItem.SalamanderPass.IsNullOrEmpty())
{ {
dicQuery.Add("obfs", "salamander"); dicQuery.Add("obfs", "salamander");
dicQuery.Add("obfs-password", Utils.UrlEncode(item.Path)); dicQuery.Add("obfs-password", Utils.UrlEncode(protocolExtraItem.SalamanderPass));
} }
if (item.GetProtocolExtra()?.Ports?.IsNotEmpty() ?? false) if (!protocolExtraItem.Ports.IsNullOrEmpty())
{ {
dicQuery.Add("mport", Utils.UrlEncode(item.GetProtocolExtra().Ports.Replace(':', '-'))); dicQuery.Add("mport", Utils.UrlEncode(protocolExtraItem.Ports.Replace(':', '-')));
} }
if (!item.CertSha.IsNullOrEmpty()) if (!item.CertSha.IsNullOrEmpty())
{ {

View file

@ -1,3 +1,5 @@
using ServiceLib.Common;
namespace ServiceLib.Manager; namespace ServiceLib.Manager;
public sealed class AppManager public sealed class AppManager
@ -279,12 +281,7 @@ public sealed class AppManager
foreach (var item in batch) foreach (var item in batch)
{ {
ProtocolExtraItem extra = new() var extra = item.GetProtocolExtra();
{
AlterId = item.AlterId.ToString(),
Flow = item.Flow.IsNotEmpty() ? item.Flow : null,
Ports = item.Ports.IsNotEmpty() ? item.Ports : null,
};
if (item.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain) if (item.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
{ {
@ -304,14 +301,26 @@ public sealed class AppManager
switch (item.ConfigType) switch (item.ConfigType)
{ {
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
extra = extra with {SsMethod = item.Security.IsNotEmpty() ? item.Security : null}; extra = extra with {SsMethod = item.Security.NullIfEmpty() };
break; break;
case EConfigType.VMess: case EConfigType.VMess:
extra = extra with {VmessSecurity = item.Security.IsNotEmpty() ? item.Security : null}; extra = extra with
{
AlterId = item.AlterId.ToString(),
VmessSecurity = item.Security.NullIfEmpty(),
};
break;
case EConfigType.VLESS:
extra = extra with
{
Flow = item.Flow.NullIfEmpty(),
};
break; break;
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
extra = extra with extra = extra with
{ {
SalamanderPass = item.Path.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 HopInterval = _config.HysteriaItem.HopInterval
@ -320,9 +329,9 @@ public sealed class AppManager
case EConfigType.WireGuard: case EConfigType.WireGuard:
extra = extra with extra = extra with
{ {
WgPublicKey = item.PublicKey.IsNotEmpty() ? item.PublicKey : null, WgPublicKey = item.PublicKey.NullIfEmpty(),
WgInterfaceAddress = item.RequestHost.IsNotEmpty() ? item.RequestHost : null, WgInterfaceAddress = item.RequestHost.NullIfEmpty(),
WgReserved = item.Path.IsNotEmpty() ? item.Path : null, WgReserved = item.Path.NullIfEmpty(),
WgMtu = int.TryParse(item.ShortId, out var mtu) ? mtu : 1280 WgMtu = int.TryParse(item.ShortId, out var mtu) ? mtu : 1280
}; };
break; break;

View file

@ -26,6 +26,7 @@ public record ProtocolExtraItem
public int? WgMtu { get; init; } public int? WgMtu { get; init; }
// hysteria2 // hysteria2
public string? SalamanderPass { get; init; }
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; }

View file

@ -138,12 +138,12 @@ public partial class CoreConfigSingboxService
{ {
outbound.password = node.Password; outbound.password = node.Password;
if (node.Path.IsNotEmpty()) if (!protocolExtra.SalamanderPass.IsNullOrEmpty())
{ {
outbound.obfs = new() outbound.obfs = new()
{ {
type = "salamander", type = "salamander",
password = node.Path.TrimEx(), password = protocolExtra.SalamanderPass.TrimEx(),
}; };
} }

View file

@ -532,7 +532,7 @@ public partial class CoreConfigV2rayService
interval = hopInterval, interval = hopInterval,
}; };
} }
HysteriaSettings4Ray hysteriaSettings = new() streamSettings.hysteriaSettings = new()
{ {
version = 2, version = 2,
auth = node.Password, auth = node.Password,
@ -540,8 +540,7 @@ public partial class CoreConfigV2rayService
down = downMbps > 0 ? $"{downMbps}mbps" : null, down = downMbps > 0 ? $"{downMbps}mbps" : null,
udphop = udpHop, udphop = udpHop,
}; };
streamSettings.hysteriaSettings = hysteriaSettings; if (!protocolExtra.SalamanderPass.IsNullOrEmpty())
if (node.Path.IsNotEmpty())
{ {
streamSettings.finalmask ??= new(); streamSettings.finalmask ??= new();
streamSettings.finalmask.udp = streamSettings.finalmask.udp =
@ -549,7 +548,7 @@ public partial class CoreConfigV2rayService
new Mask4Ray new Mask4Ray
{ {
type = "salamander", type = "salamander",
settings = new MaskSettings4Ray { password = node.Path.TrimEx(), } settings = new MaskSettings4Ray { password = protocolExtra.SalamanderPass.TrimEx(), }
} }
]; ];
} }

View file

@ -17,6 +17,9 @@ public class AddServerViewModel : MyReactiveObject
[Reactive] [Reactive]
public string CertSha { get; set; } public string CertSha { get; set; }
[Reactive]
public string SalamanderPass { get; set; }
[Reactive] [Reactive]
public int AlterId { get; set; } public int AlterId { get; set; }
@ -109,6 +112,7 @@ public class AddServerViewModel : MyReactiveObject
Ports = protocolExtra?.Ports ?? string.Empty; Ports = protocolExtra?.Ports ?? string.Empty;
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;
UpMbps = protocolExtra?.UpMbps ?? 0; UpMbps = protocolExtra?.UpMbps ?? 0;
DownMbps = protocolExtra?.DownMbps ?? 0; DownMbps = protocolExtra?.DownMbps ?? 0;
HopInterval = protocolExtra?.HopInterval ?? Global.Hysteria2DefaultHopInt; HopInterval = protocolExtra?.HopInterval ?? Global.Hysteria2DefaultHopInt;
@ -168,19 +172,20 @@ public class AddServerViewModel : MyReactiveObject
SelectedSource.CertSha = CertSha.IsNullOrEmpty() ? string.Empty : CertSha; SelectedSource.CertSha = CertSha.IsNullOrEmpty() ? string.Empty : CertSha;
SelectedSource.SetProtocolExtra(SelectedSource.GetProtocolExtra() with SelectedSource.SetProtocolExtra(SelectedSource.GetProtocolExtra() with
{ {
Ports = Ports.IsNullOrEmpty() ? null : Ports, Ports = Ports.NullIfEmpty(),
AlterId = AlterId > 0 ? AlterId.ToString() : string.Empty, AlterId = AlterId > 0 ? AlterId.ToString() : null,
Flow = Flow.IsNullOrEmpty() ? null : Flow, Flow = Flow.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 >= 5 ? HopInterval : null, HopInterval = HopInterval >= 5 ? HopInterval : null,
VmessSecurity = VmessSecurity.IsNullOrEmpty() ? null : VmessSecurity, VmessSecurity = VmessSecurity.NullIfEmpty(),
VlessEncryption = VlessEncryption.IsNullOrEmpty() ? null : VlessEncryption, VlessEncryption = VlessEncryption.NullIfEmpty(),
SsMethod = SsMethod.IsNullOrEmpty() ? null : SsMethod, SsMethod = SsMethod.NullIfEmpty(),
Username = Username.IsNullOrEmpty() ? null : Username, Username = Username.NullIfEmpty(),
WgPublicKey = WgPublicKey.IsNullOrEmpty() ? null : WgPublicKey, WgPublicKey = WgPublicKey.NullIfEmpty(),
WgInterfaceAddress = WgInterfaceAddress.IsNullOrEmpty() ? null : WgInterfaceAddress, WgInterfaceAddress = WgInterfaceAddress.NullIfEmpty(),
WgReserved = WgReserved.IsNullOrEmpty() ? null : WgReserved, WgReserved = WgReserved.NullIfEmpty(),
WgMtu = WgMtu >= 576 ? WgMtu : null, WgMtu = WgMtu >= 576 ? WgMtu : null,
}); });

View file

@ -144,7 +144,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SalamanderPass, v => v.txtPath7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Ports, v => v.txtPorts7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Ports, v => v.txtPorts7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.HopInterval, v => v.txtHopInt7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.HopInterval, v => v.txtHopInt7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.UpMbps, v => v.txtUpMbps7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.UpMbps, v => v.txtUpMbps7.Text).DisposeWith(disposables);

View file

@ -139,7 +139,7 @@ public partial class AddServerWindow
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.SelectedSource.Path, v => v.txtPath7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.SalamanderPass, v => v.txtPath7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Ports, v => v.txtPorts7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Ports, v => v.txtPorts7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.HopInterval, v => v.txtHopInt7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.HopInterval, v => v.txtHopInt7.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.UpMbps, v => v.txtUpMbps7.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.UpMbps, v => v.txtUpMbps7.Text).DisposeWith(disposables);