Fix raw http ui

Fill xhttp default mode

Fix share uri

Remove RawHost

Fix singbox tcp http path

Fix vmess share uri
This commit is contained in:
DHR60 2026-03-29 16:48:40 +08:00
parent 8599f70b03
commit 945ffb7fd4
15 changed files with 229 additions and 156 deletions

View file

@ -45,6 +45,8 @@ public class Global
public const string DefaultNetwork = "raw"; public const string DefaultNetwork = "raw";
public const string RawHeaderHttp = "http"; public const string RawHeaderHttp = "http";
public const string None = "none"; public const string None = "none";
public const string RawNetworkAlias = "tcp";
public const string DefaultXhttpMode = "auto";
public const string ProxyTag = "proxy"; public const string ProxyTag = "proxy";
public const string DirectTag = "direct"; public const string DirectTag = "direct";
public const string BlockTag = "block"; public const string BlockTag = "block";

View file

@ -1140,7 +1140,6 @@ public static class ConfigHandler
&& AreEqual(oProtocolExtra.VmessSecurity, nProtocolExtra.VmessSecurity) && AreEqual(oProtocolExtra.VmessSecurity, nProtocolExtra.VmessSecurity)
&& AreEqual(o.Network, n.Network) && AreEqual(o.Network, n.Network)
&& AreEqual(oTransport.RawHeaderType, nTransport.RawHeaderType) && AreEqual(oTransport.RawHeaderType, nTransport.RawHeaderType)
&& AreEqual(oTransport.RawHost, nTransport.RawHost)
&& AreEqual(oTransport.Host, nTransport.Host) && AreEqual(oTransport.Host, nTransport.Host)
&& AreEqual(oTransport.Path, nTransport.Path) && AreEqual(oTransport.Path, nTransport.Path)
&& AreEqual(oTransport.XhttpMode, nTransport.XhttpMode) && AreEqual(oTransport.XhttpMode, nTransport.XhttpMode)

View file

@ -5,6 +5,7 @@ namespace ServiceLib.Handler.Fmt;
public class BaseFmt public class BaseFmt
{ {
private static readonly string[] _allowInsecureArray = new[] { "insecure", "allowInsecure", "allow_insecure" }; private static readonly string[] _allowInsecureArray = new[] { "insecure", "allowInsecure", "allow_insecure" };
private static string UrlEncodeSafe(string? value) => Utils.UrlEncode(value ?? string.Empty);
protected static string GetIpv6(string address) protected static string GetIpv6(string address)
{ {
@ -95,15 +96,20 @@ public class BaseFmt
network = nameof(ETransport.raw); network = nameof(ETransport.raw);
} }
dicQuery.Add("type", network); //dicQuery.Add("type", network);
dicQuery.Add("type", network == nameof(ETransport.raw) ? Global.RawNetworkAlias : network);
switch (network) switch (network)
{ {
case nameof(ETransport.raw): case nameof(ETransport.raw):
dicQuery.Add("headerType", transport.RawHeaderType.IsNotEmpty() ? transport.RawHeaderType : Global.None); dicQuery.Add("headerType", transport.RawHeaderType.IsNotEmpty() ? transport.RawHeaderType : Global.None);
if (transport.RawHost.IsNotEmpty()) if (transport.Host.IsNotEmpty())
{ {
dicQuery.Add("host", Utils.UrlEncode(transport.RawHost)); dicQuery.Add("host", UrlEncodeSafe(transport.Host));
}
if (transport.Path.IsNotEmpty())
{
dicQuery.Add("path", UrlEncodeSafe(transport.Path));
} }
break; break;
@ -111,44 +117,34 @@ public class BaseFmt
dicQuery.Add("headerType", transport.KcpHeaderType.IsNotEmpty() ? transport.KcpHeaderType : Global.None); dicQuery.Add("headerType", transport.KcpHeaderType.IsNotEmpty() ? transport.KcpHeaderType : Global.None);
if (transport.KcpSeed.IsNotEmpty()) if (transport.KcpSeed.IsNotEmpty())
{ {
dicQuery.Add("seed", Utils.UrlEncode(transport.KcpSeed)); dicQuery.Add("seed", UrlEncodeSafe(transport.KcpSeed));
} }
break; break;
case nameof(ETransport.ws): case nameof(ETransport.ws):
if (transport.Host.IsNotEmpty())
{
dicQuery.Add("host", Utils.UrlEncode(transport.Host));
}
if (transport.Path.IsNotEmpty())
{
dicQuery.Add("path", Utils.UrlEncode(transport.Path));
}
break;
case nameof(ETransport.httpupgrade): case nameof(ETransport.httpupgrade):
if (transport.Host.IsNotEmpty()) if (transport.Host.IsNotEmpty())
{ {
dicQuery.Add("host", Utils.UrlEncode(transport.Host)); dicQuery.Add("host", UrlEncodeSafe(transport.Host));
} }
if (transport.Path.IsNotEmpty()) if (transport.Path.IsNotEmpty())
{ {
dicQuery.Add("path", Utils.UrlEncode(transport.Path)); dicQuery.Add("path", UrlEncodeSafe(transport.Path));
} }
break; break;
case nameof(ETransport.xhttp): case nameof(ETransport.xhttp):
if (transport.Host.IsNotEmpty()) if (transport.Host.IsNotEmpty())
{ {
dicQuery.Add("host", Utils.UrlEncode(transport.Host)); dicQuery.Add("host", UrlEncodeSafe(transport.Host));
} }
if (transport.Path.IsNotEmpty()) if (transport.Path.IsNotEmpty())
{ {
dicQuery.Add("path", Utils.UrlEncode(transport.Path)); dicQuery.Add("path", UrlEncodeSafe(transport.Path));
} }
if (transport.XhttpMode.IsNotEmpty() && Global.XhttpMode.Contains(transport.XhttpMode)) if (transport.XhttpMode.IsNotEmpty() && Global.XhttpMode.Contains(transport.XhttpMode))
{ {
dicQuery.Add("mode", Utils.UrlEncode(transport.XhttpMode)); dicQuery.Add("mode", UrlEncodeSafe(transport.XhttpMode));
} }
if (transport.XhttpExtra.IsNotEmpty()) if (transport.XhttpExtra.IsNotEmpty())
{ {
@ -161,18 +157,18 @@ public class BaseFmt
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
}) })
: transport.XhttpExtra; : transport.XhttpExtra;
dicQuery.Add("extra", Utils.UrlEncode(extra)); dicQuery.Add("extra", UrlEncodeSafe(extra));
} }
break; break;
case nameof(ETransport.grpc): case nameof(ETransport.grpc):
if (transport.GrpcServiceName.IsNotEmpty()) if (transport.GrpcServiceName.IsNotEmpty())
{ {
dicQuery.Add("authority", Utils.UrlEncode(transport.GrpcAuthority)); dicQuery.Add("authority", UrlEncodeSafe(transport.GrpcAuthority));
dicQuery.Add("serviceName", Utils.UrlEncode(transport.GrpcServiceName)); dicQuery.Add("serviceName", UrlEncodeSafe(transport.GrpcServiceName));
if (transport.GrpcMode is Global.GrpcGunMode or Global.GrpcMultiMode) if (transport.GrpcMode is Global.GrpcGunMode or Global.GrpcMultiMode)
{ {
dicQuery.Add("mode", Utils.UrlEncode(transport.GrpcMode)); dicQuery.Add("mode", UrlEncodeSafe(transport.GrpcMode));
} }
} }
break; break;
@ -260,6 +256,10 @@ public class BaseFmt
} }
var net = GetQueryValue(query, "type", nameof(ETransport.raw)); var net = GetQueryValue(query, "type", nameof(ETransport.raw));
if (net == Global.RawNetworkAlias)
{
net = nameof(ETransport.raw);
}
if (!Global.Networks.Contains(net)) if (!Global.Networks.Contains(net))
{ {
net = nameof(ETransport.raw); net = nameof(ETransport.raw);
@ -272,7 +272,8 @@ public class BaseFmt
transport = transport with transport = transport with
{ {
RawHeaderType = GetQueryValue(query, "headerType", Global.None), RawHeaderType = GetQueryValue(query, "headerType", Global.None),
RawHost = GetQueryDecoded(query, "host"), Host = GetQueryDecoded(query, "host"),
Path = GetQueryDecoded(query, "path"),
}; };
break; break;
@ -286,13 +287,6 @@ public class BaseFmt
break; break;
case nameof(ETransport.ws): case nameof(ETransport.ws):
transport = transport with
{
Host = GetQueryDecoded(query, "host"),
Path = GetQueryDecoded(query, "path", "/"),
};
break;
case nameof(ETransport.httpupgrade): case nameof(ETransport.httpupgrade):
transport = transport with transport = transport with
{ {

View file

@ -51,7 +51,7 @@ public class ShadowsocksFmt : BaseFmt
if (item.Network == nameof(ETransport.raw) && transport.RawHeaderType == Global.RawHeaderHttp) if (item.Network == nameof(ETransport.raw) && transport.RawHeaderType == Global.RawHeaderHttp)
{ {
plugin = "obfs-local"; plugin = "obfs-local";
pluginArgs = $"obfs=http;obfs-host={transport.RawHost};"; pluginArgs = $"obfs=http;obfs-host={transport.Host};";
} }
else else
{ {
@ -213,7 +213,7 @@ public class ShadowsocksFmt : BaseFmt
item.SetTransportExtra(item.GetTransportExtra() with item.SetTransportExtra(item.GetTransportExtra() with
{ {
RawHeaderType = Global.RawHeaderHttp, RawHeaderType = Global.RawHeaderHttp,
RawHost = obfsHost, Host = obfsHost,
}); });
} }
} }

View file

@ -34,7 +34,7 @@ public class VmessFmt : BaseFmt
id = item.Password, id = item.Password,
aid = int.TryParse(item.GetProtocolExtra()?.AlterId, out var result) ? result : 0, aid = int.TryParse(item.GetProtocolExtra()?.AlterId, out var result) ? result : 0,
scy = item.GetProtocolExtra().VmessSecurity ?? "", scy = item.GetProtocolExtra().VmessSecurity ?? "",
net = item.Network, net = item.GetNetwork() == nameof(ETransport.raw) ? Global.RawNetworkAlias : item.Network,
type = item.GetNetwork() switch type = item.GetNetwork() switch
{ {
nameof(ETransport.raw) => item.GetTransportExtra().RawHeaderType, nameof(ETransport.raw) => item.GetTransportExtra().RawHeaderType,
@ -45,7 +45,7 @@ public class VmessFmt : BaseFmt
}, },
host = item.GetNetwork() switch host = item.GetNetwork() switch
{ {
nameof(ETransport.raw) => item.GetTransportExtra().RawHost, nameof(ETransport.raw) => item.GetTransportExtra().Host,
nameof(ETransport.ws) => item.GetTransportExtra().Host, nameof(ETransport.ws) => item.GetTransportExtra().Host,
nameof(ETransport.httpupgrade) => item.GetTransportExtra().Host, nameof(ETransport.httpupgrade) => item.GetTransportExtra().Host,
nameof(ETransport.xhttp) => item.GetTransportExtra().Host, nameof(ETransport.xhttp) => item.GetTransportExtra().Host,
@ -54,6 +54,7 @@ public class VmessFmt : BaseFmt
}, },
path = item.GetNetwork() switch path = item.GetNetwork() switch
{ {
nameof(ETransport.raw) => item.GetTransportExtra().Path,
nameof(ETransport.kcp) => item.GetTransportExtra().KcpSeed, nameof(ETransport.kcp) => item.GetTransportExtra().KcpSeed,
nameof(ETransport.ws) => item.GetTransportExtra().Path, nameof(ETransport.ws) => item.GetTransportExtra().Path,
nameof(ETransport.httpupgrade) => item.GetTransportExtra().Path, nameof(ETransport.httpupgrade) => item.GetTransportExtra().Path,
@ -111,7 +112,7 @@ public class VmessFmt : BaseFmt
}); });
if (vmessQRCode.net.IsNotEmpty()) if (vmessQRCode.net.IsNotEmpty())
{ {
item.Network = vmessQRCode.net; item.Network = vmessQRCode.net == Global.RawNetworkAlias ? nameof(ETransport.raw) : vmessQRCode.net;
} }
if (vmessQRCode.type.IsNotEmpty()) if (vmessQRCode.type.IsNotEmpty())
{ {
@ -126,7 +127,7 @@ public class VmessFmt : BaseFmt
} }
transport = item.GetNetwork() switch transport = item.GetNetwork() switch
{ {
nameof(ETransport.raw) => transport with { RawHost = Utils.ToString(vmessQRCode.host) }, nameof(ETransport.raw) => transport with { Host = Utils.ToString(vmessQRCode.host), Path = Utils.ToString(vmessQRCode.path) },
nameof(ETransport.kcp) => transport with { KcpSeed = Utils.ToString(vmessQRCode.path) }, nameof(ETransport.kcp) => transport with { KcpSeed = Utils.ToString(vmessQRCode.path) },
nameof(ETransport.ws) => transport with { Host = Utils.ToString(vmessQRCode.host), Path = Utils.ToString(vmessQRCode.path) }, nameof(ETransport.ws) => transport with { Host = Utils.ToString(vmessQRCode.host), Path = Utils.ToString(vmessQRCode.path) },
nameof(ETransport.httpupgrade) => transport with { Host = Utils.ToString(vmessQRCode.host), Path = Utils.ToString(vmessQRCode.path) }, nameof(ETransport.httpupgrade) => transport with { Host = Utils.ToString(vmessQRCode.host), Path = Utils.ToString(vmessQRCode.path) },
@ -164,7 +165,7 @@ public class VmessFmt : BaseFmt
item.SetProtocolExtra(new ProtocolExtraItem item.SetProtocolExtra(new ProtocolExtraItem
{ {
VmessSecurity = "auto", VmessSecurity = Global.DefaultSecurity,
}); });
var query = Utils.ParseQueryString(url.Query); var query = Utils.ParseQueryString(url.Query);

View file

@ -362,7 +362,7 @@ public sealed class AppManager
{ {
try try
{ {
if (item.Network == "tcp") if (item.Network == Global.RawNetworkAlias)
{ {
item.Network = nameof(ETransport.raw); item.Network = nameof(ETransport.raw);
} }
@ -376,7 +376,8 @@ public sealed class AppManager
transport = transport with transport = transport with
{ {
RawHeaderType = item.HeaderType.NullIfEmpty(), RawHeaderType = item.HeaderType.NullIfEmpty(),
RawHost = item.RequestHost.NullIfEmpty(), Host = item.RequestHost.NullIfEmpty(),
Path = item.Path.NullIfEmpty(),
}; };
break; break;
@ -421,7 +422,7 @@ public sealed class AppManager
transport = transport with transport = transport with
{ {
RawHeaderType = item.HeaderType.NullIfEmpty(), RawHeaderType = item.HeaderType.NullIfEmpty(),
RawHost = item.RequestHost.NullIfEmpty(), Host = item.RequestHost.NullIfEmpty(),
}; };
break; break;
} }

View file

@ -169,7 +169,7 @@ public class ProfileItem
public string Network { get; set; } public string Network { get; set; }
[Obsolete("Use TransportExtra.RawHeaderType/XhttpMode/GrpcMode/KcpHeaderType instead.")] [Obsolete("Use TransportExtra.RawHeaderType/XhttpMode/GrpcMode/KcpHeaderType instead.")]
public string HeaderType { get; set; } public string HeaderType { get; set; }
[Obsolete("Use TransportExtra.RawHost/Host/GrpcAuthority instead.")] [Obsolete("Use TransportExtra.Host/GrpcAuthority instead.")]
public string RequestHost { get; set; } public string RequestHost { get; set; }
[Obsolete("Use TransportExtra.Path/GrpcServiceName/KcpSeed instead.")] [Obsolete("Use TransportExtra.Path/GrpcServiceName/KcpSeed instead.")]
public string Path { get; set; } public string Path { get; set; }

View file

@ -3,7 +3,6 @@ namespace ServiceLib.Models;
public record TransportExtra public record TransportExtra
{ {
public string? RawHeaderType { get; init; } public string? RawHeaderType { get; init; }
public string? RawHost { get; init; }
public string? Host { get; init; } public string? Host { get; init; }
public string? Path { get; init; } public string? Path { get; init; }

View file

@ -119,7 +119,7 @@ public partial class CoreConfigSingboxService
if (network == nameof(ETransport.raw) && transportExtra.RawHeaderType == Global.RawHeaderHttp) if (network == nameof(ETransport.raw) && transportExtra.RawHeaderType == Global.RawHeaderHttp)
{ {
outbound.plugin = "obfs-local"; outbound.plugin = "obfs-local";
outbound.plugin_opts = $"obfs=http;obfs-host={transportExtra.RawHost};"; outbound.plugin_opts = $"obfs=http;obfs-host={transportExtra.Host};";
} }
else else
{ {
@ -383,7 +383,7 @@ public partial class CoreConfigSingboxService
{ {
var host = _node.GetNetwork() switch var host = _node.GetNetwork() switch
{ {
nameof(ETransport.raw) => _node.GetTransportExtra().RawHost, nameof(ETransport.raw) => _node.GetTransportExtra().Host,
nameof(ETransport.ws) => _node.GetTransportExtra().Host, nameof(ETransport.ws) => _node.GetTransportExtra().Host,
nameof(ETransport.httpupgrade) => _node.GetTransportExtra().Host, nameof(ETransport.httpupgrade) => _node.GetTransportExtra().Host,
nameof(ETransport.xhttp) => _node.GetTransportExtra().Host, nameof(ETransport.xhttp) => _node.GetTransportExtra().Host,
@ -453,7 +453,8 @@ public partial class CoreConfigSingboxService
if (transportExtra.RawHeaderType == Global.RawHeaderHttp) if (transportExtra.RawHeaderType == Global.RawHeaderHttp)
{ {
transport.type = nameof(ETransport.http); transport.type = nameof(ETransport.http);
transport.host = transportExtra.RawHost.IsNullOrEmpty() ? null : Utils.String2List(transportExtra.RawHost); transport.host = transportExtra.Host.IsNullOrEmpty() ? null : Utils.String2List(transportExtra.Host);
transport.path = transportExtra.Path.NullIfEmpty();
} }
break; break;

View file

@ -357,7 +357,8 @@ public partial class CoreConfigV2rayService
switch (network) switch (network)
{ {
case nameof(ETransport.raw): case nameof(ETransport.raw):
host = transport.RawHost?.TrimEx() ?? string.Empty; host = transport.Host?.TrimEx() ?? string.Empty;
path = transport.Path?.TrimEx() ?? string.Empty;
headerType = transport.RawHeaderType?.TrimEx() ?? string.Empty; headerType = transport.RawHeaderType?.TrimEx() ?? string.Empty;
break; break;

View file

@ -76,9 +76,6 @@ public class AddServerViewModel : MyReactiveObject
[Reactive] [Reactive]
public string RawHeaderType { get; set; } public string RawHeaderType { get; set; }
[Reactive]
public string RawHost { get; set; }
[Reactive] [Reactive]
public string Host { get; set; } public string Host { get; set; }
@ -141,7 +138,7 @@ public class AddServerViewModel : MyReactiveObject
{ {
get => SelectedSource.GetNetwork() switch get => SelectedSource.GetNetwork() switch
{ {
nameof(ETransport.raw) => RawHost, nameof(ETransport.raw) => Host,
nameof(ETransport.ws) => Host, nameof(ETransport.ws) => Host,
nameof(ETransport.httpupgrade) => Host, nameof(ETransport.httpupgrade) => Host,
nameof(ETransport.xhttp) => Host, nameof(ETransport.xhttp) => Host,
@ -153,7 +150,7 @@ public class AddServerViewModel : MyReactiveObject
switch (SelectedSource.GetNetwork()) switch (SelectedSource.GetNetwork())
{ {
case nameof(ETransport.raw): case nameof(ETransport.raw):
RawHost = value; Host = value;
break; break;
case nameof(ETransport.ws): case nameof(ETransport.ws):
Host = value; Host = value;
@ -298,10 +295,9 @@ public class AddServerViewModel : MyReactiveObject
NaiveQuic = protocolExtra?.NaiveQuic ?? false; NaiveQuic = protocolExtra?.NaiveQuic ?? false;
RawHeaderType = transport.RawHeaderType ?? Global.None; RawHeaderType = transport.RawHeaderType ?? Global.None;
RawHost = transport.RawHost ?? string.Empty;
Host = transport.Host ?? string.Empty; Host = transport.Host ?? string.Empty;
Path = transport.Path ?? string.Empty; Path = transport.Path ?? string.Empty;
XhttpMode = transport.XhttpMode ?? string.Empty; XhttpMode = transport.XhttpMode ?? Global.DefaultXhttpMode;
XhttpExtra = transport.XhttpExtra ?? string.Empty; XhttpExtra = transport.XhttpExtra ?? string.Empty;
GrpcAuthority = transport.GrpcAuthority ?? string.Empty; GrpcAuthority = transport.GrpcAuthority ?? string.Empty;
GrpcServiceName = transport.GrpcServiceName ?? string.Empty; GrpcServiceName = transport.GrpcServiceName ?? string.Empty;
@ -363,7 +359,6 @@ public class AddServerViewModel : MyReactiveObject
var transport = new TransportExtra var transport = new TransportExtra
{ {
RawHeaderType = RawHeaderType.NullIfEmpty(), RawHeaderType = RawHeaderType.NullIfEmpty(),
RawHost = RawHost.NullIfEmpty(),
Host = Host.NullIfEmpty(), Host = Host.NullIfEmpty(),
Path = Path.NullIfEmpty(), Path = Path.NullIfEmpty(),
XhttpMode = XhttpMode.NullIfEmpty(), XhttpMode = XhttpMode.NullIfEmpty(),
@ -497,7 +492,7 @@ public class AddServerViewModel : MyReactiveObject
{ {
return SelectedSource.GetNetwork() switch return SelectedSource.GetNetwork() switch
{ {
nameof(ETransport.raw) => RawHost, nameof(ETransport.raw) => Host,
nameof(ETransport.ws) => Host, nameof(ETransport.ws) => Host,
nameof(ETransport.httpupgrade) => Host, nameof(ETransport.httpupgrade) => Host,
nameof(ETransport.xhttp) => Host, nameof(ETransport.xhttp) => Host,

View file

@ -718,33 +718,54 @@
<Grid Grid.Row="2"> <Grid Grid.Row="2">
<Grid <Grid
x:Name="gridTransportRaw" x:Name="gridTransportRaw"
ColumnDefinitions="300,Auto"
IsVisible="False" IsVisible="False"
RowDefinitions="Auto,Auto"> RowDefinitions="Auto,Auto">
<TextBlock <Grid Grid.Row="0" ColumnDefinitions="300,Auto">
Grid.Row="0" <TextBlock
Grid.Column="0" Grid.Row="0"
Margin="{StaticResource Margin4}" Grid.Column="0"
VerticalAlignment="Center" Margin="{StaticResource Margin4}"
Text="{x:Static resx:ResUI.TbHeaderType}" /> VerticalAlignment="Center"
<ComboBox Text="{x:Static resx:ResUI.TbHeaderType}" />
x:Name="cmbHeaderTypeRaw" <ComboBox
Grid.Row="0" x:Name="cmbHeaderTypeRaw"
Grid.Column="1" Grid.Row="0"
Width="200" Grid.Column="1"
Margin="{StaticResource Margin4}" /> Width="200"
<TextBlock Margin="{StaticResource Margin4}" />
</Grid>
<Grid
x:Name="gridTransportRawHttp"
Grid.Row="1" Grid.Row="1"
Grid.Column="0" ColumnDefinitions="300,Auto"
Margin="{StaticResource Margin4}" IsVisible="False"
VerticalAlignment="Center" RowDefinitions="Auto,Auto">
Text="{x:Static resx:ResUI.TbRequestHost}" /> <TextBlock
<TextBox Grid.Row="0"
x:Name="txtRequestHostRaw" Grid.Column="0"
Grid.Row="1" Margin="{StaticResource Margin4}"
Grid.Column="1" VerticalAlignment="Center"
Width="400" Text="{x:Static resx:ResUI.TbRequestHost}" />
Margin="{StaticResource Margin4}" /> <TextBox
x:Name="txtRequestHostRaw"
Grid.Row="0"
Grid.Column="1"
Width="400"
Margin="{StaticResource Margin4}" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbPath}" />
<TextBox
x:Name="txtPathRaw"
Grid.Row="1"
Grid.Column="1"
Width="400"
Margin="{StaticResource Margin4}" />
</Grid>
</Grid> </Grid>
<Grid <Grid

View file

@ -16,6 +16,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
Loaded += Window_Loaded; Loaded += Window_Loaded;
btnCancel.Click += (s, e) => Close(); btnCancel.Click += (s, e) => Close();
cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged; cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;
cmbHeaderTypeRaw.SelectionChanged += CmbHeaderTypeRaw_SelectionChanged;
cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged; cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;
btnGUID.Click += btnGUID_Click; btnGUID.Click += btnGUID_Click;
btnGUID5.Click += btnGUID_Click; btnGUID5.Click += btnGUID_Click;
@ -24,6 +25,16 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
cmbCoreType.ItemsSource = Global.CoreTypes.AppendEmpty(); cmbCoreType.ItemsSource = Global.CoreTypes.AppendEmpty();
cmbNetwork.ItemsSource = Global.Networks; cmbNetwork.ItemsSource = Global.Networks;
cmbHeaderTypeRaw.ItemsSource = new List<string> { Global.None, Global.RawHeaderHttp };
var kcpHeaderTypes = new List<string> { Global.None };
kcpHeaderTypes.AddRange(Global.KcpHeaderTypes);
cmbHeaderTypeKcp.ItemsSource = kcpHeaderTypes;
cmbHeaderTypeXhttp.ItemsSource = Global.XhttpMode;
cmbHeaderTypeGrpc.ItemsSource = new List<string> { Global.GrpcGunMode, Global.GrpcMultiMode };
cmbFingerprint.ItemsSource = Global.Fingerprints; cmbFingerprint.ItemsSource = Global.Fingerprints;
cmbFingerprint2.ItemsSource = Global.Fingerprints; cmbFingerprint2.ItemsSource = Global.Fingerprints;
cmbAllowInsecure.ItemsSource = Global.AllowInsecure; cmbAllowInsecure.ItemsSource = Global.AllowInsecure;
@ -202,7 +213,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
} }
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.RawHeaderType, v => v.cmbHeaderTypeRaw.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.RawHeaderType, v => v.cmbHeaderTypeRaw.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RawHost, v => v.txtRequestHostRaw.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Host, v => v.txtRequestHostRaw.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Path, v => v.txtPathRaw.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.KcpHeaderType, v => v.cmbHeaderTypeKcp.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.KcpHeaderType, v => v.cmbHeaderTypeKcp.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.KcpSeed, v => v.txtKcpSeed.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.KcpSeed, v => v.txtKcpSeed.Text).DisposeWith(disposables);
@ -269,8 +281,12 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
private void CmbNetwork_SelectionChanged(object? sender, SelectionChangedEventArgs e) private void CmbNetwork_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{ {
SetHeaderType(); SetTransportGridVisibility();
SetTips(); }
private void CmbHeaderTypeRaw_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{
SetRawHttpFieldsVisibility();
} }
private void CmbStreamSecurity_SelectionChanged(object? sender, SelectionChangedEventArgs e) private void CmbStreamSecurity_SelectionChanged(object? sender, SelectionChangedEventArgs e)
@ -299,25 +315,6 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
txtId5.Text = Utils.GetGuid(); txtId5.Text = Utils.GetGuid();
} }
private void SetHeaderType()
{
cmbHeaderTypeRaw.ItemsSource = new List<string> { Global.None, Global.RawHeaderHttp };
var kcpHeaderTypes = new List<string> { Global.None };
kcpHeaderTypes.AddRange(Global.KcpHeaderTypes);
cmbHeaderTypeKcp.ItemsSource = kcpHeaderTypes;
cmbHeaderTypeXhttp.ItemsSource = Global.XhttpMode;
cmbHeaderTypeGrpc.ItemsSource = new List<string> { Global.GrpcGunMode, Global.GrpcMultiMode };
SetTransportGridVisibility();
}
private void SetTips()
{
SetTransportGridVisibility();
}
private void SetTransportGridVisibility() private void SetTransportGridVisibility()
{ {
var network = cmbNetwork.SelectedItem?.ToString(); var network = cmbNetwork.SelectedItem?.ToString();
@ -357,5 +354,21 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
gridTransportRaw.IsVisible = true; gridTransportRaw.IsVisible = true;
break; break;
} }
SetRawHttpFieldsVisibility();
}
private void SetRawHttpFieldsVisibility()
{
var network = cmbNetwork.SelectedItem?.ToString();
if (network.IsNullOrEmpty())
{
network = Global.DefaultNetwork;
}
var rawHeaderType = cmbHeaderTypeRaw.SelectedItem?.ToString();
var showRawHttpFields = network == nameof(ETransport.raw)
&& rawHeaderType == Global.RawHeaderHttp;
gridTransportRawHttp.IsVisible = showRawHttpFields;
} }
} }

View file

@ -943,42 +943,73 @@
<Grid Grid.Row="2"> <Grid Grid.Row="2">
<Grid x:Name="gridTransportRaw" Visibility="Collapsed"> <Grid x:Name="gridTransportRaw" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock
Grid.Row="0" <Grid Grid.Row="0">
Grid.Column="0" <Grid.ColumnDefinitions>
Margin="{StaticResource Margin4}" <ColumnDefinition Width="300" />
VerticalAlignment="Center" <ColumnDefinition Width="Auto" />
Style="{StaticResource ToolbarTextBlock}" </Grid.ColumnDefinitions>
Text="{x:Static resx:ResUI.TbHeaderType}" /> <TextBlock
<ComboBox Grid.Row="0"
x:Name="cmbHeaderTypeRaw" Grid.Column="0"
Grid.Row="0" Margin="{StaticResource Margin4}"
Grid.Column="1" VerticalAlignment="Center"
Width="200" Style="{StaticResource ToolbarTextBlock}"
Margin="{StaticResource Margin4}" Text="{x:Static resx:ResUI.TbHeaderType}" />
Style="{StaticResource DefComboBox}" /> <ComboBox
<TextBlock x:Name="cmbHeaderTypeRaw"
Grid.Row="0"
Grid.Column="1"
Width="200"
Margin="{StaticResource Margin4}"
Style="{StaticResource DefComboBox}" />
</Grid>
<Grid
x:Name="gridTransportRawHttp"
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Visibility="Collapsed">
Margin="{StaticResource Margin4}" <Grid.ColumnDefinitions>
VerticalAlignment="Center" <ColumnDefinition Width="300" />
Style="{StaticResource ToolbarTextBlock}" <ColumnDefinition Width="Auto" />
Text="{x:Static resx:ResUI.TbRequestHost}" /> </Grid.ColumnDefinitions>
<TextBox <Grid.RowDefinitions>
x:Name="txtRequestHostRaw" <RowDefinition Height="Auto" />
Grid.Row="1" <RowDefinition Height="Auto" />
Grid.Column="1" </Grid.RowDefinitions>
Width="400" <TextBlock
Margin="{StaticResource Margin4}" Grid.Row="0"
Style="{StaticResource DefTextBox}" /> Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbRequestHost}" />
<TextBox
x:Name="txtRequestHostRaw"
Grid.Row="0"
Grid.Column="1"
Width="400"
Margin="{StaticResource Margin4}"
Style="{StaticResource DefTextBox}" />
<TextBlock
Grid.Row="1"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TbPath}" />
<TextBox
x:Name="txtPathRaw"
Grid.Row="1"
Grid.Column="1"
Width="400"
Margin="{StaticResource Margin4}"
Style="{StaticResource DefTextBox}" />
</Grid>
</Grid> </Grid>
<Grid x:Name="gridTransportXhttp" Visibility="Collapsed"> <Grid x:Name="gridTransportXhttp" Visibility="Collapsed">

View file

@ -11,6 +11,7 @@ public partial class AddServerWindow
Owner = Application.Current.MainWindow; Owner = Application.Current.MainWindow;
Loaded += Window_Loaded; Loaded += Window_Loaded;
cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged; cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;
cmbHeaderTypeRaw.SelectionChanged += CmbHeaderTypeRaw_SelectionChanged;
cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged; cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;
btnGUID.Click += btnGUID_Click; btnGUID.Click += btnGUID_Click;
btnGUID5.Click += btnGUID_Click; btnGUID5.Click += btnGUID_Click;
@ -23,6 +24,16 @@ public partial class AddServerWindow
{ {
ViewModel.SelectedSource.Network = Global.DefaultNetwork; ViewModel.SelectedSource.Network = Global.DefaultNetwork;
} }
cmbHeaderTypeRaw.ItemsSource = new List<string> { Global.None, Global.RawHeaderHttp };
var kcpHeaderTypes = new List<string> { Global.None };
kcpHeaderTypes.AddRange(Global.KcpHeaderTypes);
cmbHeaderTypeKcp.ItemsSource = kcpHeaderTypes;
cmbHeaderTypeXhttp.ItemsSource = Global.XhttpMode;
cmbHeaderTypeGrpc.ItemsSource = new List<string> { Global.GrpcGunMode, Global.GrpcMultiMode };
cmbFingerprint.ItemsSource = Global.Fingerprints; cmbFingerprint.ItemsSource = Global.Fingerprints;
cmbFingerprint2.ItemsSource = Global.Fingerprints; cmbFingerprint2.ItemsSource = Global.Fingerprints;
cmbAllowInsecure.ItemsSource = Global.AllowInsecure; cmbAllowInsecure.ItemsSource = Global.AllowInsecure;
@ -200,7 +211,8 @@ public partial class AddServerWindow
} }
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.RawHeaderType, v => v.cmbHeaderTypeRaw.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.RawHeaderType, v => v.cmbHeaderTypeRaw.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.RawHost, v => v.txtRequestHostRaw.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Host, v => v.txtRequestHostRaw.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Path, v => v.txtPathRaw.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.KcpHeaderType, v => v.cmbHeaderTypeKcp.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.KcpHeaderType, v => v.cmbHeaderTypeKcp.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.KcpSeed, v => v.txtKcpSeed.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.KcpSeed, v => v.txtKcpSeed.Text).DisposeWith(disposables);
@ -269,8 +281,12 @@ public partial class AddServerWindow
private void CmbNetwork_SelectionChanged(object sender, SelectionChangedEventArgs e) private void CmbNetwork_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
SetHeaderType(); SetTransportGridVisibility();
SetTips(); }
private void CmbHeaderTypeRaw_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetRawHttpFieldsVisibility();
} }
private void CmbStreamSecurity_SelectionChanged(object sender, SelectionChangedEventArgs e) private void CmbStreamSecurity_SelectionChanged(object sender, SelectionChangedEventArgs e)
@ -299,25 +315,6 @@ public partial class AddServerWindow
txtId5.Text = Utils.GetGuid(); txtId5.Text = Utils.GetGuid();
} }
private void SetHeaderType()
{
cmbHeaderTypeRaw.ItemsSource = new List<string> { Global.None, Global.RawHeaderHttp };
var kcpHeaderTypes = new List<string> { Global.None };
kcpHeaderTypes.AddRange(Global.KcpHeaderTypes);
cmbHeaderTypeKcp.ItemsSource = kcpHeaderTypes;
cmbHeaderTypeXhttp.ItemsSource = Global.XhttpMode;
cmbHeaderTypeGrpc.ItemsSource = new List<string> { Global.GrpcGunMode, Global.GrpcMultiMode };
SetTransportGridVisibility();
}
private void SetTips()
{
SetTransportGridVisibility();
}
private void SetTransportGridVisibility() private void SetTransportGridVisibility()
{ {
var network = cmbNetwork.SelectedItem?.ToString(); var network = cmbNetwork.SelectedItem?.ToString();
@ -357,5 +354,23 @@ public partial class AddServerWindow
gridTransportRaw.Visibility = Visibility.Visible; gridTransportRaw.Visibility = Visibility.Visible;
break; break;
} }
SetRawHttpFieldsVisibility();
}
private void SetRawHttpFieldsVisibility()
{
var network = cmbNetwork.SelectedItem?.ToString();
if (network.IsNullOrEmpty())
{
network = Global.DefaultNetwork;
}
var rawHeaderType = cmbHeaderTypeRaw.SelectedItem?.ToString();
var showRawHttpFields = network == nameof(ETransport.raw)
&& rawHeaderType == Global.RawHeaderHttp;
gridTransportRawHttp.Visibility = showRawHttpFields
? Visibility.Visible
: Visibility.Collapsed;
} }
} }