diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml
index c68dbc68..c65e311d 100644
--- a/.github/workflows/build-linux.yml
+++ b/.github/workflows/build-linux.yml
@@ -29,6 +29,22 @@ jobs:
release_tag: ${{ inputs.release_tag }}
secrets: inherit
+ build-aot:
+ uses: ./.github/workflows/build.yml
+ with:
+ target: linux
+ isAot: true
+
+ release-aot-zip:
+ if: inputs.release_tag != ''
+ needs: build-aot
+ uses: ./.github/workflows/package-zip.yml
+ with:
+ target: linux
+ release_tag: ${{ inputs.release_tag }}
+ isAot: true
+ secrets: inherit
+
deb:
name: build and release deb x64 & arm64
if: (github.event_name == 'workflow_dispatch' && inputs.release_tag != '') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
diff --git a/.github/workflows/build-osx.yml b/.github/workflows/build-osx.yml
index 47b6dbe0..21a43d88 100644
--- a/.github/workflows/build-osx.yml
+++ b/.github/workflows/build-osx.yml
@@ -28,7 +28,23 @@ jobs:
target: macos
release_tag: ${{ inputs.release_tag }}
secrets: inherit
-
+
+ build-aot:
+ uses: ./.github/workflows/build.yml
+ with:
+ target: macos
+ isAot: true
+
+ release-aot-zip:
+ if: inputs.release_tag != ''
+ needs: build-aot
+ uses: ./.github/workflows/package-zip.yml
+ with:
+ target: macos
+ release_tag: ${{ inputs.release_tag }}
+ isAot: true
+ secrets: inherit
+
dmg:
name: package and release macOS dmg
if: inputs.release_tag != ''
diff --git a/.github/workflows/build-windows-desktop.yml b/.github/workflows/build-windows-desktop.yml
index a473b96b..92a9159f 100644
--- a/.github/workflows/build-windows-desktop.yml
+++ b/.github/workflows/build-windows-desktop.yml
@@ -28,3 +28,19 @@ jobs:
target: windows-desktop
release_tag: ${{ inputs.release_tag }}
secrets: inherit
+
+ build-aot:
+ uses: ./.github/workflows/build.yml
+ with:
+ target: windows
+ isAot: true
+
+ release-aot-zip:
+ if: inputs.release_tag != ''
+ needs: build-aot
+ uses: ./.github/workflows/package-zip.yml
+ with:
+ target: windows-desktop
+ release_tag: ${{ inputs.release_tag }}
+ isAot: true
+ secrets: inherit
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 114718a0..38a8d70c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,6 +10,10 @@ on:
required: false
type: string
default: './v2rayN.Desktop/v2rayN.Desktop.csproj'
+ isAot:
+ required: false
+ type: boolean
+ default: false
jobs:
build:
@@ -27,7 +31,6 @@ jobs:
)
}}
env:
- Output: "${{ github.workspace }}/${{ matrix.arch }}"
RID: |-
${{
case(
@@ -41,6 +44,7 @@ jobs:
${{
case(
inputs.target == 'windows', '-p:EnableWindowsTargeting=true',
+ inputs.target == 'linux', (matrix.arch == 'arm64' && '-p:LinkerFlavor=lld -p:ObjCopyName=llvm-objcopy' || ''),
''
)
}}
@@ -71,25 +75,65 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
- dotnet-version: 10.0.1xx
-
- - name: Build v2rayN
+ dotnet-version: 10.0.x
+
+ - name: Install dependencies
shell: bash
- working-directory: ./v2rayN
- run: dotnet publish $Project -c Release -r $RID -p:SelfContained=true $ExtOpt -o $Output
+ if: inputs.target == 'linux' && inputs.isAot
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y clang zlib1g-dev build-essential
+
+ - name: Install dependencies cross-arch
+ shell: bash
+ if: inputs.target == 'linux' && inputs.isAot && matrix.arch == 'arm64'
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y lld llvm binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross
+
+ - name: Set AOT Environment Variable
+ shell: bash
+ run: |
+ if [ "${{ inputs.isAot }}" = "true" ]; then
+ echo "DOTNET_AOT_ARG=-p:IsAot=true" >> $GITHUB_ENV
+ else
+ echo "DOTNET_AOT_ARG=-p:IsAot=false" >> $GITHUB_ENV
+ fi
+
+ - name: Set OUTPUT Environment Variable
+ shell: bash
+ run: |
+ RAW_PATH="${{ github.workspace }}/${{ matrix.arch }}${{ inputs.isAot && '-aot' || '' }}"
+ echo "OUTPUT=${RAW_PATH//\\//}" >> "$GITHUB_ENV"
- name: Build AmazTool
shell: bash
working-directory: ./v2rayN
- run: dotnet publish ./AmazTool/AmazTool.csproj -c Release -r $RID -p:SelfContained=true -p:PublishTrimmed=true $ExtOpt -o $Output
+ run: dotnet publish ./AmazTool/AmazTool.csproj -c Release -r $RID -p:SelfContained=true -p:PublishTrimmed=true $ExtOpt ${{ env.DOTNET_AOT_ARG }} -o ${{ env.OUTPUT }}
+
+ - name: Build v2rayN WPF
+ shell: bash
+ if: inputs.project == './v2rayN/v2rayN.csproj'
+ working-directory: ./v2rayN
+ run: dotnet publish $Project -c Release -r $RID -p:SelfContained=true $ExtOpt -o ${{ env.OUTPUT }}
+
+ - name: Build v2rayN Avalonia
+ shell: bash
+ if: inputs.project == './v2rayN.Desktop/v2rayN.Desktop.csproj'
+ working-directory: ./v2rayN
+ run: dotnet publish $Project -c Release -r $RID -p:SelfContained=true $ExtOpt ${{ env.DOTNET_AOT_ARG }} -o ${{ env.OUTPUT }}
- name: Remove Debug Symbols
shell: bash
run: |
- find ${{ matrix.arch }} -type f -name '*.pdb' -delete
+ find ${{ env.OUTPUT }} -type f -name '*.pdb' -delete
+ find ${{ env.OUTPUT }} -type f -name '*.debug' -delete
+ find ${{ env.OUTPUT }} -type f -name '*.dbg' -delete
+ find ${{ env.OUTPUT }} -type f -name '*.sym' -delete
+ find ${{ env.OUTPUT }} -name '*.dSYM' -exec rm -rf {} +
- name: Upload build artifacts
uses: actions/upload-artifact@v7
with:
- name: ${{ matrix.arch }}
- path: ${{ matrix.arch }}
+ name: ${{ matrix.arch }}${{ inputs.isAot && '-aot' || '' }}
+ path: ${{ env.OUTPUT }}
diff --git a/.github/workflows/package-zip.yml b/.github/workflows/package-zip.yml
index 3b6e7116..599261c9 100644
--- a/.github/workflows/package-zip.yml
+++ b/.github/workflows/package-zip.yml
@@ -9,6 +9,10 @@ on:
target: # windows linux macos windows-desktop
required: true
type: string
+ isAot:
+ required: false
+ type: boolean
+ default: false
secrets:
GPG_PRIVATE_KEY:
required: true
@@ -43,27 +47,62 @@ jobs:
- name: Checkout
uses: actions/checkout@v7
+ - name: Set package variables
+ id: package-vars
+ shell: bash
+ env:
+ INPUT_TARGET: ${{ inputs.target }}
+ INPUT_IS_AOT: ${{ inputs.isAot }}
+ run: |
+ set -euo pipefail
+ package_dir="v2rayN-${Target}-${Arch}"
+ package_file="${package_dir}.zip"
+ build_artifact_name="${{ matrix.arch }}"
+ rename_suffix=""
+ if [[ "$INPUT_IS_AOT" == "true" ]]; then
+ build_artifact_name="${build_artifact_name}-aot"
+ rename_suffix="-aot"
+ fi
+ if [[ "$INPUT_TARGET" == "windows-desktop" ]]; then
+ rename_suffix="-desktop${rename_suffix}"
+ fi
+ final_package_file="${package_dir}${rename_suffix}.zip"
+
+ {
+ echo "build_artifact_name=${build_artifact_name}"
+ echo "package_dir=${package_dir}"
+ echo "package_file=${package_file}"
+ echo "final_package_file=${final_package_file}"
+ echo "rename_suffix=${rename_suffix}"
+ } >> "$GITHUB_OUTPUT"
+
- name: Restore build artifacts
uses: actions/download-artifact@v8
with:
- name: ${{ matrix.arch }}
- path: v2rayN-${{ env.Target }}-${{ env.Arch }}
-
+ name: ${{ steps.package-vars.outputs.build_artifact_name }}
+ path: ${{ steps.package-vars.outputs.package_dir }}
+
- name: Get v2rayN-core-bin
- run: wget -nv -O v2rayN-$Target-$Arch.zip "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/v2rayN-$Target-$Arch.zip"
-
+ run: |
+ wget -nv -O "${{ steps.package-vars.outputs.package_file }}" "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/v2rayN-$Target-$Arch.zip"
+
- name: Package zip archive
- run: 7z a -tZip v2rayN-$Target-$Arch.zip v2rayN-$Target-$Arch -mx1
+ shell: bash
+ run: |
+ 7z a -tZip "${{ steps.package-vars.outputs.package_file }}" "${{ steps.package-vars.outputs.package_dir }}" -mx1
+
+ - name: Rename package archive
+ if: steps.package-vars.outputs.rename_suffix != ''
+ shell: bash
+ run: |
+ mv "${{ steps.package-vars.outputs.package_file }}" \
+ "${{ steps.package-vars.outputs.package_dir }}${{ steps.package-vars.outputs.rename_suffix }}.zip"
- - name: Rename windows-desktop
- if: inputs.target == 'windows-desktop'
- run: mv "v2rayN-$Target-$Arch.zip" "v2rayN-$Target-$Arch-desktop.zip"
-
- name: Upload zip artifact
uses: actions/upload-artifact@v7
with:
- name: release-${{ inputs.target }}-${{ matrix.arch }}
- path: v2rayN*.zip
+ name: release-${{ inputs.target }}-${{ matrix.arch }}${{ inputs.isAot && '-aot' || '' }}
+ path: ${{ steps.package-vars.outputs.final_package_file }}
if-no-files-found: error
release:
@@ -75,7 +114,7 @@ jobs:
uses: ./.github/workflows/upload-sign.yml
with:
release_tag: ${{ inputs.release_tag }}
- artifact_name: release-${{ inputs.target }}-${{ matrix.arch }}
+ artifact_name: release-${{ inputs.target }}-${{ matrix.arch }}${{ inputs.isAot && '-aot' || '' }}
file_pattern: '*.zip'
secrets:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
diff --git a/v2rayN/AmazTool/AmazTool.csproj b/v2rayN/AmazTool/AmazTool.csproj
index 4657a889..9cdd5f89 100644
--- a/v2rayN/AmazTool/AmazTool.csproj
+++ b/v2rayN/AmazTool/AmazTool.csproj
@@ -5,16 +5,31 @@
-
- ResXFileCodeGenerator
- Resource.Designer.cs
-
-
True
True
Resource.resx
+
+ Designer
+ Resource.Designer.cs
+ ResXFileCodeGenerator
+
+
+ Designer
+ ResXFileCodeGenerator
+
+
+ Designer
+ ResXFileCodeGenerator
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/v2rayN/AmazTool/Resx/Resource.Designer.cs b/v2rayN/AmazTool/Resx/Resource.Designer.cs
index 2283298a..7cca6bdc 100644
--- a/v2rayN/AmazTool/Resx/Resource.Designer.cs
+++ b/v2rayN/AmazTool/Resx/Resource.Designer.cs
@@ -19,7 +19,7 @@ namespace AmazTool.Resx {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resource {
diff --git a/v2rayN/Directory.Build.props b/v2rayN/Directory.Build.props
index 19b4e76c..dfbd4fca 100644
--- a/v2rayN/Directory.Build.props
+++ b/v2rayN/Directory.Build.props
@@ -29,4 +29,14 @@
true
false
+
+
+ false
+
+
+
+ true
+ true
+ $(DefineConstants);V2RAYN_IS_AOT
+
diff --git a/v2rayN/Directory.Packages.props b/v2rayN/Directory.Packages.props
index 992e02f6..292b44f7 100644
--- a/v2rayN/Directory.Packages.props
+++ b/v2rayN/Directory.Packages.props
@@ -25,8 +25,7 @@
-
-
+
diff --git a/v2rayN/ServiceLib.Tests/ServiceLib.Tests.csproj b/v2rayN/ServiceLib.Tests/ServiceLib.Tests.csproj
index 2dd3c7a3..98c31aa6 100644
--- a/v2rayN/ServiceLib.Tests/ServiceLib.Tests.csproj
+++ b/v2rayN/ServiceLib.Tests/ServiceLib.Tests.csproj
@@ -4,6 +4,7 @@
Exe
false
enable
+ true
diff --git a/v2rayN/ServiceLib/Common/JsonUtils.cs b/v2rayN/ServiceLib/Common/JsonUtils.cs
index 951cdbd7..6aa22381 100644
--- a/v2rayN/ServiceLib/Common/JsonUtils.cs
+++ b/v2rayN/ServiceLib/Common/JsonUtils.cs
@@ -7,40 +7,45 @@ public class JsonUtils
private static readonly JsonSerializerOptions _defaultDeserializeOptions = new()
{
PropertyNameCaseInsensitive = true,
- ReadCommentHandling = JsonCommentHandling.Skip
+ ReadCommentHandling = JsonCommentHandling.Skip,
+ TypeInfoResolver = AppJsonContext.Default,
};
private static readonly JsonSerializerOptions _defaultSerializeOptions = new()
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ TypeInfoResolver = AppJsonContext.Default,
};
private static readonly JsonSerializerOptions _defaultSerializeNoIndentedOptions = new()
{
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ TypeInfoResolver = AppJsonContext.Default,
};
private static readonly JsonSerializerOptions _nullValueSerializeOptions = new()
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ TypeInfoResolver = AppJsonContext.Default,
};
private static readonly JsonSerializerOptions _nullValueSerializeNoIndentedOptions = new()
{
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
+ Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ TypeInfoResolver = AppJsonContext.Default,
};
private static readonly JsonDocumentOptions _defaultDocumentOptions = new()
{
- CommentHandling = JsonCommentHandling.Skip
+ CommentHandling = JsonCommentHandling.Skip,
};
///
@@ -109,7 +114,7 @@ public class JsonUtils
///
///
///
- public static string Serialize(object? obj, bool indented = true, bool nullValue = false)
+ public static string Serialize(T? obj, bool indented = true, bool nullValue = false)
{
var result = string.Empty;
try
@@ -140,7 +145,7 @@ public class JsonUtils
///
///
///
- public static string Serialize(object? obj, JsonSerializerOptions? options)
+ public static string SerializeCamelCase(T? obj)
{
var result = string.Empty;
try
@@ -149,7 +154,14 @@ public class JsonUtils
{
return result;
}
- result = JsonSerializer.Serialize(obj, options ?? _defaultSerializeOptions);
+ var options = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ TypeInfoResolver = AppJsonContext.Default,
+ };
+ result = JsonSerializer.Serialize(obj, options);
}
catch (Exception ex)
{
@@ -162,9 +174,108 @@ public class JsonUtils
/// SerializeToNode
///
///
+ ///
///
- public static JsonNode? SerializeToNode(object? obj, JsonSerializerOptions? options = null)
+ public static JsonNode? SerializeToNode(T? obj, bool nullValue = false)
{
+ var options = nullValue ? _nullValueSerializeOptions : _defaultSerializeOptions;
return JsonSerializer.SerializeToNode(obj, options);
}
+
+ public static JsonArray? SerializeToArray(IEnumerable? values)
+ {
+ if (values is null)
+ {
+ return null;
+ }
+ var array = new JsonArray();
+ foreach (var value in values)
+ {
+ var valueNode = JsonSerializer.SerializeToNode(value, _defaultSerializeOptions);
+ array.Add(valueNode);
+ }
+ return array;
+ }
}
+
+[JsonSerializable(typeof(Config))]
+[JsonSerializable(typeof(RulesItem))]
+[JsonSerializable(typeof(ProfileItem))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(ProfileItemModel))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(RoutingTemplate))]
+[JsonSerializable(typeof(DNSItem))]
+[JsonSerializable(typeof(SimpleDNSItem))]
+[JsonSerializable(typeof(IPAPIInfo))]
+[JsonSerializable(typeof(SsSIP008))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(SsServer))]
+[JsonSerializable(typeof(VmessQRCode))]
+[JsonSerializable(typeof(ClashProxies))]
+[JsonSerializable(typeof(ClashProviders))]
+[JsonSerializable(typeof(ClashConnections))]
+[JsonSerializable(typeof(ProtocolExtraItem))]
+[JsonSerializable(typeof(TransportExtraItem))]
+[JsonSerializable(typeof(TrafficItem))]
+[JsonSerializable(typeof(V2rayMetricsVars))]
+[JsonSerializable(typeof(V2rayMetricsVarsLink))]
+[JsonSerializable(typeof(GitHubRelease))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(ServerStatItem))]
+[JsonSerializable(typeof(WebDavItem))]
+[JsonSerializable(typeof(KeyEventItem))]
+[JsonSerializable(typeof(SubItem))]
+[JsonSerializable(typeof(SingboxConfig))]
+[JsonSerializable(typeof(Dns4Sbox))]
+[JsonSerializable(typeof(Inbound4Sbox))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(Endpoints4Sbox))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(Outbound4Sbox))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(Rule4Sbox))]
+[JsonSerializable(typeof(Ruleset4Sbox))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(V2rayConfig))]
+[JsonSerializable(typeof(Dns4Ray))]
+[JsonSerializable(typeof(DnsServer4Ray))]
+[JsonSerializable(typeof(Inbounds4Ray))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(Outbounds4Ray))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(RulesItem4Ray))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(Finalmask4Ray))]
+[JsonSerializable(typeof(string))]
+[JsonSerializable(typeof(int))]
+[JsonSerializable(typeof(long))]
+[JsonSerializable(typeof(double))]
+[JsonSerializable(typeof(decimal))]
+[JsonSerializable(typeof(bool))]
+[JsonSerializable(typeof(Guid))]
+[JsonSerializable(typeof(DateTime))]
+[JsonSerializable(typeof(DateTimeOffset))]
+[JsonSerializable(typeof(TimeSpan))]
+[JsonSerializable(typeof(int?))]
+[JsonSerializable(typeof(long?))]
+[JsonSerializable(typeof(double?))]
+[JsonSerializable(typeof(bool?))]
+[JsonSerializable(typeof(DateTime?))]
+[JsonSerializable(typeof(Guid?))]
+[JsonSerializable(typeof(string[]))]
+[JsonSerializable(typeof(int[]))]
+[JsonSerializable(typeof(byte[]))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(List))]
+[JsonSerializable(typeof(Dictionary))]
+[JsonSerializable(typeof(Dictionary))]
+[JsonSerializable(typeof(object))]
+[JsonSerializable(typeof(JsonElement))]
+[JsonSerializable(typeof(JsonDocument))]
+[JsonSerializable(typeof(JsonNode))]
+[JsonSerializable(typeof(JsonObject))]
+[JsonSerializable(typeof(JsonArray))]
+internal partial class AppJsonContext : JsonSerializerContext;
diff --git a/v2rayN/ServiceLib/Common/Utils.cs b/v2rayN/ServiceLib/Common/Utils.cs
index 393c4fe7..66b735d8 100644
--- a/v2rayN/ServiceLib/Common/Utils.cs
+++ b/v2rayN/ServiceLib/Common/Utils.cs
@@ -348,10 +348,9 @@ public class Utils
.ToList());
}
- public static List GetEnumNames() where TEnum : Enum
+ public static List GetEnumNames() where TEnum : struct, Enum
{
- return Enum.GetValues(typeof(TEnum))
- .Cast()
+ return Enum.GetValues()
.Select(e => e.ToString())
.ToList();
}
diff --git a/v2rayN/ServiceLib/Common/YamlUtils.cs b/v2rayN/ServiceLib/Common/YamlUtils.cs
index a95e1b0a..f1b94890 100644
--- a/v2rayN/ServiceLib/Common/YamlUtils.cs
+++ b/v2rayN/ServiceLib/Common/YamlUtils.cs
@@ -1,6 +1,5 @@
using YamlDotNet.Core;
-using YamlDotNet.Serialization;
-using YamlDotNet.Serialization.NamingConventions;
+using YamlDotNet.RepresentationModel;
namespace ServiceLib.Common;
@@ -13,45 +12,57 @@ public class YamlUtils
///
/// Deserialize
///
- ///
///
///
- public static T FromYaml(string str)
+ public static YamlMappingNode FromYaml(string str)
{
- var deserializer = new DeserializerBuilder()
- .WithNamingConvention(PascalCaseNamingConvention.Instance)
- .Build();
+ //var deserializer = new DeserializerBuilder()
+ // .WithNamingConvention(PascalCaseNamingConvention.Instance)
+ // .Build();
+ //try
+ //{
+ // var obj = deserializer.Deserialize(str);
+ // return obj;
+ //}
+ //catch (Exception ex)
+ //{
+ // Logging.SaveLog(_tag, ex);
+ // return deserializer.Deserialize("");
+ //}
try
{
- var obj = deserializer.Deserialize(str);
- return obj;
+ var yaml = new YamlStream();
+ using var reader = new StringReader(str);
+ yaml.Load(reader);
+ var rootNode = (YamlMappingNode)yaml.Documents[0].RootNode;
+ return rootNode;
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
- return deserializer.Deserialize("");
+ return new YamlMappingNode();
}
}
///
/// Serialize
///
- ///
+ ///
///
- public static string ToYaml(object? obj)
+ public static string ToYaml(YamlMappingNode? node)
{
var result = string.Empty;
- if (obj == null)
+ if (node == null)
{
return result;
}
- var serializer = new SerializerBuilder()
- .WithNamingConvention(HyphenatedNamingConvention.Instance)
- .Build();
-
try
{
- result = serializer.Serialize(obj);
+ var doc = new YamlDocument(node);
+ var stream = new YamlStream(doc);
+ using var writer = new StringWriter();
+ stream.Save(writer, assignAnchors: false);
+ result = writer.ToString();
}
catch (Exception ex)
{
@@ -64,9 +75,15 @@ public class YamlUtils
{
try
{
- var mergingParser = new MergingParser(new Parser(new StringReader(str)));
- var obj = new DeserializerBuilder().Build().Deserialize(mergingParser);
- return ToYaml(obj);
+ using var reader = new StringReader(str);
+ var parser = new Parser(reader);
+ var mergingParser = new MergingParser(parser);
+ var yamlStream = new YamlStream();
+ yamlStream.Load(mergingParser);
+ using var writer = new StringWriter();
+ yamlStream.Save(writer, assignAnchors: false);
+
+ return writer.ToString();
}
catch (Exception ex)
{
diff --git a/v2rayN/ServiceLib/Global.cs b/v2rayN/ServiceLib/Global.cs
index eaedc701..6159013d 100644
--- a/v2rayN/ServiceLib/Global.cs
+++ b/v2rayN/ServiceLib/Global.cs
@@ -42,6 +42,7 @@ public class Global
public const string SingboxFakeIPFilterFileName = NamespaceSample + "singbox_fakeip_filter";
public const string ChromeRootCertFileName = NamespaceSample + "chrome_roots_pem";
public const string MozillaRootCertFileName = NamespaceSample + "mozilla_roots_pem";
+ public const string TaskXmlTemplateFileName = NamespaceSample + "TaskXmlTemplate";
public const string ChromeRootProvider = "chrome";
public const string MozillaRootProvider = "mozilla";
diff --git a/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs b/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs
index acd9a515..c1259456 100644
--- a/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs
+++ b/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs
@@ -87,6 +87,7 @@ public static class AutoStartupHandler
[SupportedOSPlatform("windows")]
public static void AutoStartTaskService(string taskName, string fileName, string description)
{
+#if false
if (taskName.IsNullOrEmpty())
{
return;
@@ -117,6 +118,78 @@ public static class AutoStartupHandler
task.Actions.Add(new Microsoft.Win32.TaskScheduler.ExecAction(fileName.AppendQuotes(), null, Path.GetDirectoryName(fileName)));
taskService.RootFolder.RegisterTaskDefinition(taskName, task);
+#endif
+ if (string.IsNullOrEmpty(taskName))
+ {
+ return;
+ }
+
+ RunSchtasks($"/Delete /TN \"{taskName}\" /F");
+
+ if (string.IsNullOrEmpty(fileName))
+ {
+ return;
+ }
+
+ var workingDir = Path.GetDirectoryName(fileName) ?? string.Empty;
+
+ var taskXml = EmbedUtils.GetEmbedText(Global.TaskXmlTemplateFileName);
+
+ taskXml = taskXml
+ .Replace("{{DESCRIPTION}}", System.Security.SecurityElement.Escape(description ?? ""))
+ .Replace("{{EXEC_PATH}}", System.Security.SecurityElement.Escape(fileName ?? ""))
+ .Replace("{{ARGUMENTS}}", string.Empty)
+ .Replace("{{WORKING_DIRECTORY}}", System.Security.SecurityElement.Escape(workingDir ?? ""));
+
+ var taskXmlFileName = Utils.GetTempPath($"{Utils.GetGuid(false)}.xml");
+
+ File.WriteAllText(taskXmlFileName, taskXml);
+
+ RunSchtasks(
+ "/Create",
+ "/TN", taskName,
+ "/XML", taskXmlFileName,
+ "/F"
+ );
+ }
+
+ private static bool RunSchtasks(params string[] arguments)
+ {
+ var psi = new ProcessStartInfo
+ {
+ FileName = "schtasks.exe",
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ };
+
+ foreach (var argument in arguments)
+ {
+ psi.ArgumentList.Add(argument);
+ }
+
+ using var process = Process.Start(psi);
+
+ if (process == null)
+ {
+ return false;
+ }
+
+ process.WaitForExit();
+
+ var output = process.StandardOutput.ReadToEnd();
+ var error = process.StandardError.ReadToEnd();
+ if (!string.IsNullOrEmpty(output))
+ {
+ Logging.SaveLog($"RunSchtasks output: {output}");
+ }
+ if (!string.IsNullOrEmpty(error))
+ {
+ Logging.SaveLog($"RunSchtasks error: {error}");
+ }
+
+ return process.ExitCode == 0;
}
private static string GetAutoRunNameWindows()
diff --git a/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs
index 58be1d37..898becd2 100644
--- a/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs
+++ b/v2rayN/ServiceLib/Handler/Fmt/BaseFmt.cs
@@ -80,12 +80,7 @@ public class BaseFmt
{
var node = JsonUtils.ParseJson(item.Finalmask);
var finalmask = node != null
- ? JsonUtils.Serialize(node, new JsonSerializerOptions
- {
- WriteIndented = false,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- })
+ ? JsonUtils.Serialize(node, indented: false, nullValue: true)
: item.Finalmask;
dicQuery.Add("fm", Utils.UrlEncode(finalmask));
}
@@ -154,12 +149,7 @@ public class BaseFmt
{
var node = JsonUtils.ParseJson(transport.XhttpExtra);
var extra = node != null
- ? JsonUtils.Serialize(node, new JsonSerializerOptions
- {
- WriteIndented = false,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- })
+ ? JsonUtils.Serialize(node, indented: false, nullValue: true)
: transport.XhttpExtra;
dicQuery.Add("extra", UrlEncodeSafe(extra));
}
@@ -215,12 +205,7 @@ public class BaseFmt
{
var node = JsonUtils.ParseJson(finalmaskDecoded);
item.Finalmask = node != null
- ? JsonUtils.Serialize(node, new JsonSerializerOptions
- {
- WriteIndented = true,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- })
+ ? JsonUtils.Serialize(node, indented: true, nullValue: true)
: finalmaskDecoded;
}
else
@@ -278,12 +263,7 @@ public class BaseFmt
var node = JsonUtils.ParseJson(xhttpExtra);
if (node != null)
{
- xhttpExtra = JsonUtils.Serialize(node, new JsonSerializerOptions
- {
- WriteIndented = true,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- });
+ xhttpExtra = JsonUtils.Serialize(node, indented: true, nullValue: true);
}
}
diff --git a/v2rayN/ServiceLib/Handler/Fmt/InnerFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/InnerFmt.cs
index c39ab032..752bddf4 100644
--- a/v2rayN/ServiceLib/Handler/Fmt/InnerFmt.cs
+++ b/v2rayN/ServiceLib/Handler/Fmt/InnerFmt.cs
@@ -179,12 +179,7 @@ public class InnerFmt : BaseFmt
if (jsonObj.TryGetPropertyValue("CustomOutboundObj", out var customOutboundNode)
&& customOutboundNode is JsonObject customOutboundObj)
{
- var customOutboundContent = JsonUtils.Serialize(customOutboundObj, new JsonSerializerOptions
- {
- WriteIndented = true,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- });
+ var customOutboundContent = JsonUtils.Serialize(customOutboundObj, indented: true, nullValue: true);
customOutboundFilePath = WriteAllText(customOutboundContent);
jsonObj.Remove("CustomOutboundObj");
}
diff --git a/v2rayN/ServiceLib/Handler/Fmt/WireguardFmt.cs b/v2rayN/ServiceLib/Handler/Fmt/WireguardFmt.cs
index dfd0408b..126ea3ba 100644
--- a/v2rayN/ServiceLib/Handler/Fmt/WireguardFmt.cs
+++ b/v2rayN/ServiceLib/Handler/Fmt/WireguardFmt.cs
@@ -29,12 +29,7 @@ public class WireguardFmt : BaseFmt
{
var node = JsonUtils.ParseJson(finalmaskDecoded);
item.Finalmask = node != null
- ? JsonUtils.Serialize(node, new JsonSerializerOptions
- {
- WriteIndented = true,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- })
+ ? JsonUtils.Serialize(node, indented: true, nullValue: true)
: finalmaskDecoded;
}
else
@@ -98,12 +93,7 @@ public class WireguardFmt : BaseFmt
{
var node = JsonUtils.ParseJson(item.Finalmask);
var finalmask = node != null
- ? JsonUtils.Serialize(node, new JsonSerializerOptions
- {
- WriteIndented = false,
- DefaultIgnoreCondition = JsonIgnoreCondition.Never,
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- })
+ ? JsonUtils.Serialize(node, indented: false, nullValue: true)
: item.Finalmask;
dicQuery.Add("fm", Utils.UrlEncode(finalmask));
}
diff --git a/v2rayN/ServiceLib/Handler/SysProxy/ProxySettingWindows.cs b/v2rayN/ServiceLib/Handler/SysProxy/ProxySettingWindows.cs
index 614437d7..d3738644 100644
--- a/v2rayN/ServiceLib/Handler/SysProxy/ProxySettingWindows.cs
+++ b/v2rayN/ServiceLib/Handler/SysProxy/ProxySettingWindows.cs
@@ -133,7 +133,7 @@ public static class ProxySettingWindows
list.dwOptionCount = options.Length;
list.dwOptionError = 0;
- var optSize = Marshal.SizeOf(typeof(InternetConnectionOption));
+ var optSize = Marshal.SizeOf();
// make a pointer out of all that ...
var optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length); // !! remember to deallocate memory 4
// copy the array over into that spot in memory ...
@@ -207,17 +207,17 @@ public static class ProxySettingWindows
var entries = 0;
// attempt to query with 1 entry buffer
var rasEntryNames = new RASENTRYNAME[1];
- var bufferSize = Marshal.SizeOf(typeof(RASENTRYNAME));
- rasEntryNames[0].dwSize = Marshal.SizeOf(typeof(RASENTRYNAME));
+ var bufferSize = Marshal.SizeOf();
+ rasEntryNames[0].dwSize = Marshal.SizeOf();
var result = NativeMethods.RasEnumEntries(null, null, rasEntryNames, ref bufferSize, ref entries);
// increase buffer if the buffer is not large enough
if (result == (uint)ErrorCode.ERROR_BUFFER_TOO_SMALL)
{
- rasEntryNames = new RASENTRYNAME[bufferSize / Marshal.SizeOf(typeof(RASENTRYNAME))];
+ rasEntryNames = new RASENTRYNAME[bufferSize / Marshal.SizeOf()];
for (var i = 0; i < rasEntryNames.Length; i++)
{
- rasEntryNames[i].dwSize = Marshal.SizeOf(typeof(RASENTRYNAME));
+ rasEntryNames[i].dwSize = Marshal.SizeOf();
}
result = NativeMethods.RasEnumEntries(null, null, rasEntryNames, ref bufferSize, ref entries);
@@ -258,7 +258,7 @@ public static class ProxySettingWindows
static InternetConnectionOption()
{
- Size = Marshal.SizeOf(typeof(InternetConnectionOption));
+ Size = Marshal.SizeOf();
}
// Nested Types
diff --git a/v2rayN/ServiceLib/Models/Configs/Config.cs b/v2rayN/ServiceLib/Models/Configs/Config.cs
index 834a13a9..61ef2e91 100644
--- a/v2rayN/ServiceLib/Models/Configs/Config.cs
+++ b/v2rayN/ServiceLib/Models/Configs/Config.cs
@@ -1,6 +1,5 @@
namespace ServiceLib.Models.Configs;
-[Serializable]
public class Config
{
#region property
diff --git a/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs b/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs
index 4219b66e..54c91fc4 100644
--- a/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs
+++ b/v2rayN/ServiceLib/Models/Configs/ConfigItems.cs
@@ -1,6 +1,5 @@
namespace ServiceLib.Models.Configs;
-[Serializable]
public class CoreBasicItem
{
public bool LogEnabled { get; set; }
@@ -22,7 +21,6 @@ public class CoreBasicItem
public bool EnableCacheFile4Sbox { get; set; } = true;
}
-[Serializable]
public class InItem
{
public int LocalPort { get; set; }
@@ -38,7 +36,6 @@ public class InItem
public bool SecondLocalPortEnabled { get; set; }
}
-[Serializable]
public class KcpItem
{
public int Mtu { get; set; }
@@ -54,7 +51,6 @@ public class KcpItem
public int MaxSendingWindow { get; set; }
}
-[Serializable]
public class GrpcItem
{
public int? IdleTimeout { get; set; }
@@ -63,7 +59,6 @@ public class GrpcItem
public int? InitialWindowsSize { get; set; }
}
-[Serializable]
public class GUIItem
{
public bool AutoRun { get; set; }
@@ -77,14 +72,12 @@ public class GUIItem
public string? RootCertProvider { get; set; }
}
-[Serializable]
public class MsgUIItem
{
public string? MainMsgFilter { get; set; }
public bool? AutoRefresh { get; set; }
}
-[Serializable]
public class UIItem
{
public bool EnableAutoAdjustMainLvColWidth { get; set; }
@@ -106,7 +99,6 @@ public class UIItem
public bool HideColumnIpInfo { get; set; }
}
-[Serializable]
public class ConstItem
{
public string? SubConvertUrl { get; set; }
@@ -115,7 +107,6 @@ public class ConstItem
public string? RouteRulesTemplateSourceUrl { get; set; }
}
-[Serializable]
public class KeyEventItem
{
public EGlobalHotkey EGlobalHotkey { get; set; }
@@ -129,7 +120,6 @@ public class KeyEventItem
public int? KeyCode { get; set; }
}
-[Serializable]
public class CoreTypeItem
{
public EConfigType ConfigType { get; set; }
@@ -137,7 +127,6 @@ public class CoreTypeItem
public ECoreType CoreType { get; set; }
}
-[Serializable]
public class TunModeItem
{
public bool EnableTun { get; set; }
@@ -153,7 +142,6 @@ public class TunModeItem
public string IPv6Address { get; set; }
}
-[Serializable]
public class SpeedTestItem
{
public int SpeedTestTimeout { get; set; }
@@ -166,7 +154,6 @@ public class SpeedTestItem
public int? SpeedTestDelayInterval { get; set; }
}
-[Serializable]
public class RoutingBasicItem
{
public string DomainStrategy { get; set; }
@@ -174,7 +161,6 @@ public class RoutingBasicItem
public string RoutingIndexId { get; set; }
}
-[Serializable]
public class ColumnItem
{
public string Name { get; set; }
@@ -182,7 +168,6 @@ public class ColumnItem
public int Index { get; set; }
}
-[Serializable]
public class Mux4RayItem
{
public int? Concurrency { get; set; }
@@ -190,7 +175,6 @@ public class Mux4RayItem
public string? XudpProxyUDP443 { get; set; }
}
-[Serializable]
public class Mux4SboxItem
{
public string Protocol { get; set; }
@@ -198,7 +182,6 @@ public class Mux4SboxItem
public bool? Padding { get; set; }
}
-[Serializable]
public class HysteriaItem
{
public int UpMbps { get; set; }
@@ -206,7 +189,6 @@ public class HysteriaItem
public int HopInterval { get; set; } = Global.Hysteria2DefaultHopInt;
}
-[Serializable]
public class ClashUIItem
{
public bool EnableIPv6 { get; set; }
@@ -219,7 +201,6 @@ public class ClashUIItem
public List ConnectionsColumnItem { get; set; }
}
-[Serializable]
public class SystemProxyItem
{
public ESysProxyType SysProxyType { get; set; }
@@ -230,7 +211,6 @@ public class SystemProxyItem
public string? CustomSystemProxyScriptPath { get; set; }
}
-[Serializable]
public class WebDavItem
{
public string? Url { get; set; }
@@ -239,7 +219,6 @@ public class WebDavItem
public string? DirName { get; set; }
}
-[Serializable]
public class CheckUpdateItem
{
public bool UpdateViaProxy { get; set; } = true;
@@ -247,7 +226,6 @@ public class CheckUpdateItem
public List? CheckPreReleaseCoreTypes { get; set; }
}
-[Serializable]
public class Fragment4RayItem
{
public string? Packets { get; set; }
@@ -262,7 +240,6 @@ public class Fragment4RayItem
// migration end
}
-[Serializable]
public class WindowSizeItem
{
public string TypeName { get; set; }
@@ -270,7 +247,6 @@ public class WindowSizeItem
public int Height { get; set; }
}
-[Serializable]
public class SimpleDNSItem
{
public bool? UseSystemHosts { get; set; }
@@ -293,7 +269,6 @@ public class SimpleDNSItem
public bool? EnableHappyEyeballs { get; set; }
}
-[Serializable]
public class HappyEyeballs4RayItem
{
public int? TryDelayMs { get; set; }
diff --git a/v2rayN/ServiceLib/Models/CoreConfigs/CoreInfo.cs b/v2rayN/ServiceLib/Models/CoreConfigs/CoreInfo.cs
index df5f3667..8bc886ce 100644
--- a/v2rayN/ServiceLib/Models/CoreConfigs/CoreInfo.cs
+++ b/v2rayN/ServiceLib/Models/CoreConfigs/CoreInfo.cs
@@ -1,6 +1,5 @@
namespace ServiceLib.Models.CoreConfigs;
-[Serializable]
public class CoreInfo
{
public ECoreType CoreType { get; set; }
diff --git a/v2rayN/ServiceLib/Models/CoreConfigs/SingboxConfig.cs b/v2rayN/ServiceLib/Models/CoreConfigs/SingboxConfig.cs
index e77b4640..6e549d1a 100644
--- a/v2rayN/ServiceLib/Models/CoreConfigs/SingboxConfig.cs
+++ b/v2rayN/ServiceLib/Models/CoreConfigs/SingboxConfig.cs
@@ -44,7 +44,6 @@ public class Route4Sbox
public string? final { get; set; }
}
-[Serializable]
public class Rule4Sbox
{
public string? outbound { get; set; }
@@ -103,7 +102,6 @@ public class Rule4Sbox
public bool? speculative { get; set; }
}
-[Serializable]
public class Inbound4Sbox
{
public string type { get; set; }
@@ -232,7 +230,7 @@ public class Reality4Sbox
public class Transport4Sbox
{
public string? type { get; set; }
- public object? host { get; set; }
+ public JsonNode? host { get; set; }
public string? path { get; set; }
public Headers4Sbox? headers { get; set; }
diff --git a/v2rayN/ServiceLib/Models/CoreConfigs/V2rayConfig.cs b/v2rayN/ServiceLib/Models/CoreConfigs/V2rayConfig.cs
index 5978e79f..a56a3fe0 100644
--- a/v2rayN/ServiceLib/Models/CoreConfigs/V2rayConfig.cs
+++ b/v2rayN/ServiceLib/Models/CoreConfigs/V2rayConfig.cs
@@ -3,7 +3,7 @@ namespace ServiceLib.Models.CoreConfigs;
public class V2rayConfig
{
public Log4Ray log { get; set; }
- public object dns { get; set; }
+ public JsonObject? dns { get; set; }
public FakeDns4Ray? fakedns { get; set; }
public List inbounds { get; set; }
public List outbounds { get; set; }
@@ -130,7 +130,7 @@ public class Outboundsettings4Ray
public string? secretKey { get; set; }
- public object? address { get; set; }
+ public JsonNode? address { get; set; }
public int? port { get; set; }
@@ -142,7 +142,7 @@ public class Outboundsettings4Ray
public string? email { get; set; }
- public object? headers { get; set; }
+ public JsonNode? headers { get; set; }
public List? peers { get; set; }
@@ -199,8 +199,8 @@ public class Response4Ray
public class Dns4Ray
{
- public Dictionary? hosts { get; set; }
- public List
@@ -45,6 +44,7 @@
+
diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs
index a8103e99..96013109 100644
--- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs
+++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigClashService.cs
@@ -61,10 +61,10 @@ public class CoreConfigClashService(Config config, bool isTunEnabled)
//YAML anchors
if (txtFile.Contains("<<:") && txtFile.Contains('*') && txtFile.Contains('&'))
{
- txtFile = YamlUtils.PreprocessYaml(txtFile);
+ txtFile = YamlUtils.PreprocessYaml(txtFile) ?? "";
}
- var fileContent = YamlUtils.FromYaml>(txtFile);
+ var fileContent = YamlUtils.FromYaml(txtFile);
if (fileContent == null)
{
ret.Msg = ResUI.FailedConversionConfiguration;
@@ -72,29 +72,38 @@ public class CoreConfigClashService(Config config, bool isTunEnabled)
}
//mixed-port
- fileContent["mixed-port"] = AppManager.Instance.GetLocalPort(EInboundProtocol.socks);
+ //fileContent["mixed-port"] = AppManager.Instance.GetLocalPort(EInboundProtocol.socks);
+ fileContent.Children[new YamlScalarNode("mixed-port")] = new YamlScalarNode(AppManager.Instance.GetLocalPort(EInboundProtocol.socks).ToString());
//log-level
- fileContent["log-level"] = GetLogLevel(config.CoreBasicItem.Loglevel);
+ //fileContent["log-level"] = GetLogLevel(config.CoreBasicItem.Loglevel);
+ fileContent.Children[new YamlScalarNode("log-level")] = new YamlScalarNode(GetLogLevel(config.CoreBasicItem.Loglevel));
//external-controller
- fileContent["external-controller"] = $"{Global.Loopback}:{AppManager.Instance.StatePort2}";
- fileContent.Remove("secret");
+ //fileContent["external-controller"] = $"{Global.Loopback}:{AppManager.Instance.StatePort2}";
+ fileContent.Children[new YamlScalarNode("external-controller")] = new YamlScalarNode($"{Global.Loopback}:{AppManager.Instance.StatePort2}");
+ //fileContent.Remove("secret");
+ fileContent.Children.Remove(new YamlScalarNode("secret"));
//allow-lan
if (config.Inbound.First().AllowLANConn)
{
- fileContent["allow-lan"] = "true";
- fileContent["bind-address"] = "*";
+ //fileContent["allow-lan"] = "true";
+ fileContent.Children[new YamlScalarNode("allow-lan")] = new YamlScalarNode("true");
+ //fileContent["bind-address"] = "*";
+ fileContent.Children[new YamlScalarNode("bind-address")] = new YamlScalarNode("*");
}
else
{
- fileContent["allow-lan"] = "false";
+ //fileContent["allow-lan"] = "false";
+ fileContent.Children[new YamlScalarNode("allow-lan")] = new YamlScalarNode("false");
}
//ipv6
- fileContent["ipv6"] = config.ClashUIItem.EnableIPv6;
+ //fileContent["ipv6"] = config.ClashUIItem.EnableIPv6;
+ fileContent.Children[new YamlScalarNode("ipv6")] = new YamlScalarNode(config.ClashUIItem.EnableIPv6.ToString().ToLowerInvariant());
//mode
- fileContent.TryAdd("mode", nameof(ERuleMode.Rule));
+ //fileContent.TryAdd("mode", nameof(ERuleMode.Rule));
+ fileContent.Children.TryAdd(new YamlScalarNode("mode"), new YamlScalarNode(nameof(ERuleMode.Rule)));
//enable tun mode
if (isTunEnabled)
@@ -102,10 +111,11 @@ public class CoreConfigClashService(Config config, bool isTunEnabled)
var tun = EmbedUtils.GetEmbedText(Global.ClashTunYaml);
if (tun.IsNotEmpty())
{
- var tunContent = YamlUtils.FromYaml>(tun);
+ var tunContent = YamlUtils.FromYaml(tun);
if (tunContent != null)
{
- fileContent["tun"] = tunContent["tun"];
+ //fileContent["tun"] = tunContent["tun"];
+ fileContent.Children[new YamlScalarNode("tun")] = tunContent.Children[new YamlScalarNode("tun")];
}
}
}
@@ -120,27 +130,27 @@ public class CoreConfigClashService(Config config, bool isTunEnabled)
Logging.SaveLog($"{_tag}-Mixin", ex);
}
- // Mihomo parses plain values such as 815458e4 as floats, so quote REALITY short IDs.
- var originalRealityShortIds = new List<(Dictionary
-
+
+
+
+