* Adjust XHTTP style

* Add xray tun custom support
This commit is contained in:
DHR60 2026-04-18 11:18:17 +00:00 committed by GitHub
parent 021e64e20b
commit eeecef4db9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 211 additions and 70 deletions

View file

@ -4681,7 +4681,16 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 XHTTP Extra raw JSON, format: { XHTTP Object } 的本地化字符串。
/// 查找类似 XHTTP Extra 的本地化字符串。
/// </summary>
public static string TransportExtra {
get {
return ResourceManager.GetString("TransportExtra", resourceCulture);
}
}
/// <summary>
/// 查找类似 Raw JSON, format: { XHTTP Object } 的本地化字符串。
/// </summary>
public static string TransportExtraTip {
get {

View file

@ -1321,7 +1321,7 @@
<value>حالت xhttp</value>
</data>
<data name="TransportExtraTip" xml:space="preserve">
<value>جیسون خام XHTTP Extra, فرمت: { XHTTPObject }</value>
<value>Raw JSON, format: { XHTTP Object }</value>
</data>
<data name="TbSettingsHide2TrayWhenClose" xml:space="preserve">
<value>هنگام بستن پنجره در سینی پنهان شوید</value>
@ -1704,4 +1704,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbHost" xml:space="preserve">
<value>Host</value>
</data>
<data name="TransportExtra" xml:space="preserve">
<value>XHTTP Extra</value>
</data>
</root>

View file

@ -1327,7 +1327,7 @@
<value>Mode XHTTP</value>
</data>
<data name="TransportExtraTip" xml:space="preserve">
<value>JSON brut XHTTP Extra, format : { XHTTPObject }</value>
<value>Raw JSON, format: { XHTTP Object }</value>
</data>
<data name="TbSettingsHide2TrayWhenClose" xml:space="preserve">
<value>Masquer dans la barre détat à la fermeture de la fenêtre</value>
@ -1707,4 +1707,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbHost" xml:space="preserve">
<value>Host</value>
</data>
<data name="TransportExtra" xml:space="preserve">
<value>XHTTP Extra</value>
</data>
</root>

View file

@ -1321,7 +1321,7 @@
<value>xhttp mód</value>
</data>
<data name="TransportExtraTip" xml:space="preserve">
<value>XHTTP Extra nyers JSON, formátum: { XHTTP Objektum }</value>
<value>Raw JSON, format: { XHTTP Object }</value>
</data>
<data name="TbSettingsHide2TrayWhenClose" xml:space="preserve">
<value>Ablak bezárásakor a tálcára rejtés</value>
@ -1704,4 +1704,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbHost" xml:space="preserve">
<value>Host</value>
</data>
<data name="TransportExtra" xml:space="preserve">
<value>XHTTP Extra</value>
</data>
</root>

View file

@ -1330,7 +1330,7 @@
<value>xhttp mode</value>
</data>
<data name="TransportExtraTip" xml:space="preserve">
<value>XHTTP Extra raw JSON, format: { XHTTP Object }</value>
<value>Raw JSON, format: { XHTTP Object }</value>
</data>
<data name="TbSettingsHide2TrayWhenClose" xml:space="preserve">
<value>Hide to tray when closing the window</value>
@ -1710,4 +1710,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
<data name="TbHost" xml:space="preserve">
<value>Host</value>
</data>
<data name="TransportExtra" xml:space="preserve">
<value>XHTTP Extra</value>
</data>
</root>

View file

@ -1321,7 +1321,7 @@
<value>XHTTP-режим</value>
</data>
<data name="TransportExtraTip" xml:space="preserve">
<value>Дополнительный сырой JSON для XHTTP, формат: { XHTTP Object }</value>
<value>Raw JSON, format: { XHTTP Object }</value>
</data>
<data name="TbSettingsHide2TrayWhenClose" xml:space="preserve">
<value>Сворачивать в трей при закрытии окна</value>
@ -1704,4 +1704,7 @@
<data name="TbHost" xml:space="preserve">
<value>Host</value>
</data>
<data name="TransportExtra" xml:space="preserve">
<value>XHTTP Extra</value>
</data>
</root>

View file

@ -1327,7 +1327,7 @@
<value>XHTTP 模式</value>
</data>
<data name="TransportExtraTip" xml:space="preserve">
<value>XHTTP Extra 原始 JSON格式 { XHTTPObject }</value>
<value>原始 JSON格式 { XHTTPObject }</value>
</data>
<data name="TbSettingsHide2TrayWhenClose" xml:space="preserve">
<value>关闭窗口时隐藏至托盘</value>
@ -1707,4 +1707,7 @@
<data name="TbHost" xml:space="preserve">
<value>Host</value>
</data>
<data name="TransportExtra" xml:space="preserve">
<value>XHTTP Extra</value>
</data>
</root>

View file

@ -1318,7 +1318,7 @@
<value>xhttp 模式</value>
</data>
<data name="TransportExtraTip" xml:space="preserve">
<value>XHTTP Extra 原始 JSON格式 { XHTTPObject }</value>
<value>原始 JSON格式 { XHTTPObject }</value>
</data>
<data name="TbSettingsHide2TrayWhenClose" xml:space="preserve">
<value>關閉視窗時隱藏至托盤</value>
@ -1701,4 +1701,7 @@
<data name="TbHost" xml:space="preserve">
<value>Host</value>
</data>
<data name="TransportExtra" xml:space="preserve">
<value>XHTTP Extra</value>
</data>
</root>

View file

@ -5,12 +5,18 @@ public partial class CoreConfigV2rayService
private string ApplyFullConfigTemplate()
{
var fullConfigTemplate = context.FullConfigTemplate;
if (fullConfigTemplate == null || !fullConfigTemplate.Enabled || fullConfigTemplate.Config.IsNullOrEmpty())
if (fullConfigTemplate is not { Enabled: true })
{
return JsonUtils.Serialize(_coreConfig);
}
var fullConfigTemplateNode = JsonNode.Parse(fullConfigTemplate.Config);
var fullConfigTemplateItem = context.IsTunEnabled ? fullConfigTemplate.TunConfig : fullConfigTemplate.Config;
if (fullConfigTemplateItem.IsNullOrEmpty())
{
return JsonUtils.Serialize(_coreConfig);
}
var fullConfigTemplateNode = JsonNode.Parse(fullConfigTemplateItem);
if (fullConfigTemplateNode == null)
{
return JsonUtils.Serialize(_coreConfig);

View file

@ -370,11 +370,11 @@ public partial class CoreConfigV2rayService
try
{
var item = context.RawDnsItem;
var normalDNS = item?.NormalDNS;
var customDNS = context.IsTunEnabled ? item?.TunDNS : item?.NormalDNS;
var domainStrategy4Freedom = item?.DomainStrategy4Freedom;
if (normalDNS.IsNullOrEmpty())
if (customDNS.IsNullOrEmpty())
{
normalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
customDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
}
//Outbound Freedom domainStrategy
@ -389,11 +389,11 @@ public partial class CoreConfigV2rayService
}
}
var obj = JsonUtils.ParseJson(normalDNS);
var obj = JsonUtils.ParseJson(customDNS);
if (obj is null)
{
List<string> servers = [];
var arrDNS = normalDNS.Split(',');
var arrDNS = customDNS.Split(',');
foreach (var str in arrDNS)
{
servers.Add(str);

View file

@ -20,6 +20,7 @@ public class DNSSettingViewModel : MyReactiveObject
[Reactive] public string DomainStrategy4FreedomCompatible { get; set; }
[Reactive] public string DomainDNSAddressCompatible { get; set; }
[Reactive] public string NormalDNSCompatible { get; set; }
[Reactive] public string TunDNSCompatible { get; set; }
[Reactive] public string DomainStrategy4Freedom2Compatible { get; set; }
[Reactive] public string DomainDNSAddress2Compatible { get; set; }
@ -43,6 +44,7 @@ public class DNSSettingViewModel : MyReactiveObject
ImportDefConfig4V2rayCompatibleCmd = ReactiveCommand.CreateFromTask(async () =>
{
NormalDNSCompatible = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
TunDNSCompatible = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
await Task.CompletedTask;
});
@ -84,6 +86,7 @@ public class DNSSettingViewModel : MyReactiveObject
DomainStrategy4FreedomCompatible = item1?.DomainStrategy4Freedom ?? string.Empty;
DomainDNSAddressCompatible = item1?.DomainDNSAddress ?? string.Empty;
NormalDNSCompatible = item1?.NormalDNS ?? string.Empty;
TunDNSCompatible = item1?.TunDNS ?? string.Empty;
var item2 = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
SBCustomDNSEnableCompatible = item2.Enabled;
@ -124,6 +127,21 @@ public class DNSSettingViewModel : MyReactiveObject
}
}
}
if (TunDNSCompatible.IsNotEmpty())
{
var obj = JsonUtils.ParseJson(TunDNSCompatible);
if (obj != null && obj["servers"] != null)
{
}
else
{
if (TunDNSCompatible.Contains('{') || TunDNSCompatible.Contains('}'))
{
NoticeManager.Instance.Enqueue(ResUI.FillCorrectDNSText);
return;
}
}
}
if (NormalDNS2Compatible.IsNotEmpty())
{
var obj2 = JsonUtils.Deserialize<Dns4Sbox>(NormalDNS2Compatible);
@ -149,6 +167,7 @@ public class DNSSettingViewModel : MyReactiveObject
item1.DomainDNSAddress = DomainDNSAddressCompatible;
item1.UseSystemHosts = UseSystemHostsCompatible;
item1.NormalDNS = NormalDNSCompatible;
item1.TunDNS = TunDNSCompatible;
await ConfigHandler.SaveDNSItems(_config, item1);
var item2 = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);

View file

@ -13,6 +13,9 @@ public class FullConfigTemplateViewModel : MyReactiveObject
[Reactive]
public string FullConfigTemplate4Ray { get; set; }
[Reactive]
public string FullTunConfigTemplate4Ray { get; set; }
[Reactive]
public string FullConfigTemplate4Singbox { get; set; }
@ -50,10 +53,15 @@ public class FullConfigTemplateViewModel : MyReactiveObject
private async Task Init()
{
var item = await AppManager.Instance.GetFullConfigTemplateItem(ECoreType.Xray);
EnableFullConfigTemplate4Ray = item?.Enabled ?? false;
FullConfigTemplate4Ray = item?.Config ?? string.Empty;
AddProxyOnly4Ray = item?.AddProxyOnly ?? false;
ProxyDetour4Ray = item?.ProxyDetour ?? string.Empty;
if (item == null)
{
return;
}
EnableFullConfigTemplate4Ray = item.Enabled;
FullConfigTemplate4Ray = item.Config ?? string.Empty;
FullTunConfigTemplate4Ray = item.TunConfig ?? string.Empty;
AddProxyOnly4Ray = item.AddProxyOnly ?? false;
ProxyDetour4Ray = item.ProxyDetour ?? string.Empty;
var item2 = await AppManager.Instance.GetFullConfigTemplateItem(ECoreType.sing_box);
EnableFullConfigTemplate4Singbox = item2?.Enabled ?? false;
@ -82,10 +90,13 @@ public class FullConfigTemplateViewModel : MyReactiveObject
private async Task<bool> SaveXrayConfigAsync()
{
var item = await AppManager.Instance.GetFullConfigTemplateItem(ECoreType.Xray);
if (item == null)
{
return false;
}
item.Enabled = EnableFullConfigTemplate4Ray;
item.Config = null;
item.Config = FullConfigTemplate4Ray;
item.TunConfig = FullTunConfigTemplate4Ray;
item.AddProxyOnly = AddProxyOnly4Ray;
item.ProxyDetour = ProxyDetour4Ray;
@ -97,10 +108,11 @@ public class FullConfigTemplateViewModel : MyReactiveObject
private async Task<bool> SaveSingboxConfigAsync()
{
var item = await AppManager.Instance.GetFullConfigTemplateItem(ECoreType.sing_box);
if (item == null)
{
return false;
}
item.Enabled = EnableFullConfigTemplate4Singbox;
item.Config = null;
item.TunConfig = null;
item.Config = FullConfigTemplate4Singbox;
item.TunConfig = FullTunConfigTemplate4Singbox;

View file

@ -814,17 +814,17 @@
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Top"
Text="{x:Static resx:ResUI.TransportExtraTip}"
Text="{x:Static resx:ResUI.TransportExtra}"
TextWrapping="Wrap" />
<views:JsonEditor
x:Name="txtExtraXhttp"
<Expander
Grid.Row="3"
Grid.Column="1"
Width="400"
MinHeight="100"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Stretch"
VerticalAlignment="Center" />
IsExpanded="True">
<Expander.Header>
<TextBlock FontWeight="Normal" Text="{x:Static resx:ResUI.TransportExtraTip}" />
</Expander.Header>
<views:JsonEditor x:Name="txtExtraXhttp" HorizontalAlignment="Stretch" />
</Expander>
</Grid>
<Grid

View file

@ -395,13 +395,26 @@
</StackPanel>
</WrapPanel>
<Grid Margin="{StaticResource Margin4}" ColumnDefinitions="*,10,*">
<HeaderedContentControl
Margin="{StaticResource Margin4}"
Grid.Column="0"
BorderBrush="Gray"
BorderThickness="1"
Header="HTTP/SOCKS">
<local:JsonEditor Name="txtnormalDNSCompatible" VerticalAlignment="Stretch" />
</HeaderedContentControl>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
<HeaderedContentControl
Grid.Column="2"
BorderBrush="Gray"
BorderThickness="1"
Header="{x:Static resx:ResUI.TbSettingsTunMode}">
<local:JsonEditor Name="txttunDNSCompatible" VerticalAlignment="Stretch" />
</HeaderedContentControl>
</Grid>
</DockPanel>
</TabItem>

View file

@ -52,6 +52,7 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
this.Bind(ViewModel, vm => vm.DomainStrategy4FreedomCompatible, v => v.cmbdomainStrategy4FreedomCompatible.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddressCompatible, v => v.cmbdomainDNSAddressCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNSCompatible, v => v.txtnormalDNSCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunDNSCompatible, v => v.txttunDNSCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2Compatible, v => v.cmbdomainStrategy4OutCompatible.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddress2Compatible, v => v.cmbdomainDNSAddress2Compatible.Text).DisposeWith(disposables);

View file

@ -90,13 +90,26 @@
</StackPanel>
</WrapPanel>
<Grid Margin="{StaticResource Margin4}" ColumnDefinitions="*,10,*">
<HeaderedContentControl
Margin="{StaticResource Margin4}"
Grid.Column="0"
BorderBrush="Gray"
BorderThickness="1"
Header="xray config template json">
<views:JsonEditor x:Name="rayFullConfigTemplate" VerticalAlignment="Stretch" />
</HeaderedContentControl>
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
<HeaderedContentControl
Grid.Column="2"
BorderBrush="Gray"
BorderThickness="1"
Header="xray tun config template json">
<views:JsonEditor x:Name="rayFullTunConfigTemplate" VerticalAlignment="Stretch" />
</HeaderedContentControl>
</Grid>
</DockPanel>
</TabItem>
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbSBFullConfigTemplate}">

View file

@ -12,13 +12,14 @@ public partial class FullConfigTemplateWindow : WindowBase<FullConfigTemplateVie
_config = AppManager.Instance.Config;
Loaded += Window_Loaded;
btnCancel.Click += (s, e) => Close();
btnCancel.Click += (_, _) => Close();
ViewModel = new FullConfigTemplateViewModel(UpdateViewHandler);
this.WhenActivated(disposables =>
{
this.Bind(ViewModel, vm => vm.EnableFullConfigTemplate4Ray, v => v.rayFullConfigTemplateEnable.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FullConfigTemplate4Ray, v => v.rayFullConfigTemplate.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FullTunConfigTemplate4Ray, v => v.rayFullTunConfigTemplate.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.AddProxyOnly4Ray, v => v.togAddProxyProtocolOutboundOnly4Ray.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.ProxyDetour4Ray, v => v.txtProxyDetour4Ray.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableFullConfigTemplate4Singbox, v => v.sbFullConfigTemplateEnable.IsChecked).DisposeWith(disposables);

View file

@ -1071,7 +1071,7 @@
Margin="{StaticResource Margin4}"
VerticalAlignment="Top"
Style="{StaticResource ToolbarTextBlock}"
Text="{x:Static resx:ResUI.TransportExtraTip}"
Text="{x:Static resx:ResUI.TransportExtra}"
TextWrapping="Wrap" />
<TextBox
x:Name="txtExtraXhttp"
@ -1080,8 +1080,10 @@
Width="400"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TransportExtraTip}"
AcceptsReturn="True"
MinLines="6"
MaxLines="12"
MinLines="3"
Style="{StaticResource MyOutlinedTextBox}"
TextWrapping="Wrap" />
</Grid>

View file

@ -453,9 +453,16 @@
</StackPanel>
</WrapPanel>
<Grid Margin="{StaticResource Margin8}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox
x:Name="txtnormalDNSCompatible"
Margin="{StaticResource Margin8}"
Grid.Column="0"
VerticalAlignment="Stretch"
materialDesign:HintAssist.Hint="HTTP/SOCKS"
AcceptsReturn="True"
@ -463,6 +470,20 @@
Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
<TextBox
x:Name="txttunDNSCompatible"
Grid.Column="2"
VerticalAlignment="Stretch"
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbSettingsTunMode}"
AcceptsReturn="True"
BorderThickness="1"
Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
</Grid>
</DockPanel>
</TabItem>

View file

@ -50,6 +50,7 @@ public partial class DNSSettingWindow
this.Bind(ViewModel, vm => vm.DomainStrategy4FreedomCompatible, v => v.cmbdomainStrategy4FreedomCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddressCompatible, v => v.cmbdomainDNSAddressCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.NormalDNSCompatible, v => v.txtnormalDNSCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.TunDNSCompatible, v => v.txttunDNSCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainStrategy4Freedom2Compatible, v => v.cmbdomainStrategy4OutCompatible.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DomainDNSAddress2Compatible, v => v.cmbdomainDNSAddress2Compatible.Text).DisposeWith(disposables);

View file

@ -107,9 +107,16 @@
</StackPanel>
</WrapPanel>
<Grid Margin="{StaticResource Margin8}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox
x:Name="rayFullConfigTemplate"
Margin="{StaticResource Margin8}"
Grid.Column="0"
VerticalAlignment="Stretch"
materialDesign:HintAssist.Hint="xray config template json"
AcceptsReturn="True"
@ -117,6 +124,20 @@
Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
<TextBox
x:Name="rayFullTunConfigTemplate"
Grid.Column="2"
VerticalAlignment="Stretch"
materialDesign:HintAssist.Hint="xray tun config template json"
AcceptsReturn="True"
BorderThickness="1"
Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
</Grid>
</DockPanel>
</TabItem>
<TabItem HorizontalAlignment="Left" Header="{x:Static resx:ResUI.TbSBFullConfigTemplate}">

View file

@ -17,6 +17,7 @@ public partial class FullConfigTemplateWindow
{
this.Bind(ViewModel, vm => vm.EnableFullConfigTemplate4Ray, v => v.rayFullConfigTemplateEnable.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FullConfigTemplate4Ray, v => v.rayFullConfigTemplate.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.FullTunConfigTemplate4Ray, v => v.rayFullTunConfigTemplate.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.AddProxyOnly4Ray, v => v.togAddProxyProtocolOutboundOnly4Ray.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.ProxyDetour4Ray, v => v.txtProxyDetour4Ray.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableFullConfigTemplate4Singbox, v => v.sbFullConfigTemplateEnable.IsChecked).DisposeWith(disposables);