Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49a3c84fc5 | ||
|
|
5e0c28438b | ||
|
|
a6dc801bc4 | ||
|
|
22009d1b71 | ||
|
|
50f39dc40e |
@@ -10,8 +10,18 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Assets\en-US.json" />
|
<Compile Update="Resx\Resource.Designer.cs">
|
||||||
<EmbeddedResource Include="Assets\zh-CN.json" />
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resource.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="Resx\Resource.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"Restart_v2rayN": "Start v2rayN, please wait...",
|
|
||||||
"Guidelines": "Please run it from the main application.",
|
|
||||||
"Upgrade_File_Not_Found": "Upgrade failed, file not found.",
|
|
||||||
"In_Progress": "In progress, please wait...",
|
|
||||||
"Try_Terminate_Process": "Try to terminate the v2rayN process.",
|
|
||||||
"Failed_Terminate_Process": "Failed to terminate the v2rayN.Close it manually,or the upgrade may fail.",
|
|
||||||
"Start_Unzipping": "Start extracting the update package.",
|
|
||||||
"Success_Unzipping": "Successfully extracted the update package!",
|
|
||||||
"Failed_Unzipping": "Failed to extract the update package!",
|
|
||||||
"Failed_Upgrade": "Upgrade failed!",
|
|
||||||
"Success_Upgrade": "Upgrade success!",
|
|
||||||
"Information": "Information"
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"Restart_v2rayN": "正在重启,请等待...",
|
|
||||||
"Guidelines": "请从主应用运行!",
|
|
||||||
"Upgrade_File_Not_Found": "升级失败,文件不存在!",
|
|
||||||
"In_Progress": "正在进行中,请等待...",
|
|
||||||
"Try_Terminate_Process": "尝试结束 v2rayN 进程...",
|
|
||||||
"Failed_Terminate_Process": "请手动关闭正在运行的v2rayN,否则可能升级失败。",
|
|
||||||
"Start_Unzipping": "开始解压缩更新包...",
|
|
||||||
"Success_Unzipping": "解压缩更新包成功!",
|
|
||||||
"Failed_Unzipping": "解压缩更新包失败!",
|
|
||||||
"Failed_Upgrade": "升级失败!",
|
|
||||||
"Success_Upgrade": "升级成功!",
|
|
||||||
"Information": "提示"
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
using System.Globalization;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace AmazTool
|
|
||||||
{
|
|
||||||
public class LocalizationHelper
|
|
||||||
{
|
|
||||||
private static Dictionary<string, string> _languageResources = [];
|
|
||||||
|
|
||||||
static LocalizationHelper()
|
|
||||||
{
|
|
||||||
// 加载语言资源
|
|
||||||
LoadLanguageResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LoadLanguageResources()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var currentLanguage = CultureInfo.CurrentCulture.Name;
|
|
||||||
if (currentLanguage != "zh-CN" && currentLanguage != "en-US")
|
|
||||||
{
|
|
||||||
currentLanguage = "en-US";
|
|
||||||
}
|
|
||||||
|
|
||||||
var resourceName = $"AmazTool.Assets.{currentLanguage}.json";
|
|
||||||
var assembly = Assembly.GetExecutingAssembly();
|
|
||||||
|
|
||||||
using var stream = assembly.GetManifestResourceStream(resourceName);
|
|
||||||
if (stream == null) return;
|
|
||||||
|
|
||||||
using StreamReader reader = new(stream);
|
|
||||||
var json = reader.ReadToEnd();
|
|
||||||
if (!string.IsNullOrEmpty(json))
|
|
||||||
{
|
|
||||||
_languageResources = JsonSerializer.Deserialize<Dictionary<string, string>>(json) ?? new Dictionary<string, string>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Failed to read language resource file: {ex.Message}");
|
|
||||||
}
|
|
||||||
catch (JsonException ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Failed to parse JSON data: {ex.Message}");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Unexpected error occurred: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetLocalizedValue(string key)
|
|
||||||
{
|
|
||||||
return _languageResources.TryGetValue(key, out var translation) ? translation : key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
{
|
{
|
||||||
if (args.Length == 0)
|
if (args.Length == 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine(LocalizationHelper.GetLocalizedValue("Guidelines"));
|
Console.WriteLine(Resx.Resource.Guidelines);
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
171
v2rayN/AmazTool/Resx/Resource.Designer.cs
generated
Normal file
171
v2rayN/AmazTool/Resx/Resource.Designer.cs
generated
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// 此代码由工具生成。
|
||||||
|
// 运行时版本:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||||
|
// 重新生成代码,这些更改将会丢失。
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace AmazTool.Resx {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||||
|
/// </summary>
|
||||||
|
// 此类是由 StronglyTypedResourceBuilder
|
||||||
|
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||||
|
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||||
|
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resource {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AmazTool.Resx.Resource", typeof(Resource).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||||
|
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Failed to terminate the v2rayN.Close it manually,or the upgrade may fail. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string FailedTerminateProcess {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FailedTerminateProcess", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Failed to extract the update package. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string FailedUnzipping {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FailedUnzipping", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Upgrade failed. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string FailedUpgrade {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("FailedUpgrade", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Please run it from the main application. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string Guidelines {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Guidelines", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Information 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string Information {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Information", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 In progress, please wait... 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string InProgress {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("InProgress", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Start v2rayN, please wait... 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string Restartv2rayN {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Restartv2rayN", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Start extracting the update package... 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string StartUnzipping {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("StartUnzipping", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Successfully extracted the update package. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string SuccessUnzipping {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SuccessUnzipping", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Upgrade success. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string SuccessUpgrade {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SuccessUpgrade", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Try to terminate the v2rayN process... 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string TryTerminateProcess {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TryTerminateProcess", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Upgrade failed, file not found. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
internal static string UpgradeFileNotFound {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("UpgradeFileNotFound", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
156
v2rayN/AmazTool/Resx/Resource.resx
Normal file
156
v2rayN/AmazTool/Resx/Resource.resx
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="Restartv2rayN" xml:space="preserve">
|
||||||
|
<value>Start v2rayN, please wait...</value>
|
||||||
|
</data>
|
||||||
|
<data name="Guidelines" xml:space="preserve">
|
||||||
|
<value>Please run it from the main application.</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpgradeFileNotFound" xml:space="preserve">
|
||||||
|
<value>Upgrade failed, file not found.</value>
|
||||||
|
</data>
|
||||||
|
<data name="InProgress" xml:space="preserve">
|
||||||
|
<value>In progress, please wait...</value>
|
||||||
|
</data>
|
||||||
|
<data name="TryTerminateProcess" xml:space="preserve">
|
||||||
|
<value>Try to terminate the v2rayN process...</value>
|
||||||
|
</data>
|
||||||
|
<data name="FailedTerminateProcess" xml:space="preserve">
|
||||||
|
<value>Failed to terminate the v2rayN.Close it manually,or the upgrade may fail.</value>
|
||||||
|
</data>
|
||||||
|
<data name="StartUnzipping" xml:space="preserve">
|
||||||
|
<value>Start extracting the update package...</value>
|
||||||
|
</data>
|
||||||
|
<data name="SuccessUnzipping" xml:space="preserve">
|
||||||
|
<value>Successfully extracted the update package.</value>
|
||||||
|
</data>
|
||||||
|
<data name="FailedUnzipping" xml:space="preserve">
|
||||||
|
<value>Failed to extract the update package.</value>
|
||||||
|
</data>
|
||||||
|
<data name="FailedUpgrade" xml:space="preserve">
|
||||||
|
<value>Upgrade failed.</value>
|
||||||
|
</data>
|
||||||
|
<data name="SuccessUpgrade" xml:space="preserve">
|
||||||
|
<value>Upgrade success.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Information" xml:space="preserve">
|
||||||
|
<value>Information</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
@@ -117,8 +117,40 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
<data name="Restartv2rayN" xml:space="preserve">
|
||||||
<data name="pac" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<value>正在重启,请等待...</value>
|
||||||
<value>Resources\pac.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;gb2312</value>
|
</data>
|
||||||
|
<data name="Guidelines" xml:space="preserve">
|
||||||
|
<value>请从主应用运行。</value>
|
||||||
|
</data>
|
||||||
|
<data name="UpgradeFileNotFound" xml:space="preserve">
|
||||||
|
<value>升级失败,文件不存在。</value>
|
||||||
|
</data>
|
||||||
|
<data name="InProgress" xml:space="preserve">
|
||||||
|
<value>正在进行中,请等待...</value>
|
||||||
|
</data>
|
||||||
|
<data name="TryTerminateProcess" xml:space="preserve">
|
||||||
|
<value>尝试结束 v2rayN 进程...</value>
|
||||||
|
</data>
|
||||||
|
<data name="FailedTerminateProcess" xml:space="preserve">
|
||||||
|
<value>请手动关闭正在运行的v2rayN,否则可能升级失败。</value>
|
||||||
|
</data>
|
||||||
|
<data name="StartUnzipping" xml:space="preserve">
|
||||||
|
<value>开始解压缩更新包...</value>
|
||||||
|
</data>
|
||||||
|
<data name="SuccessUnzipping" xml:space="preserve">
|
||||||
|
<value>解压缩更新包成功。</value>
|
||||||
|
</data>
|
||||||
|
<data name="FailedUnzipping" xml:space="preserve">
|
||||||
|
<value>解压缩更新包失败。</value>
|
||||||
|
</data>
|
||||||
|
<data name="FailedUpgrade" xml:space="preserve">
|
||||||
|
<value>升级失败。</value>
|
||||||
|
</data>
|
||||||
|
<data name="SuccessUpgrade" xml:space="preserve">
|
||||||
|
<value>升级成功。</value>
|
||||||
|
</data>
|
||||||
|
<data name="Information" xml:space="preserve">
|
||||||
|
<value>提示</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -8,17 +8,17 @@ namespace AmazTool
|
|||||||
{
|
{
|
||||||
public static void Upgrade(string fileName)
|
public static void Upgrade(string fileName)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{LocalizationHelper.GetLocalizedValue("Start_Unzipping")}\n{fileName}");
|
Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}");
|
||||||
|
|
||||||
Waiting(9);
|
Waiting(9);
|
||||||
|
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
{
|
{
|
||||||
Console.WriteLine(LocalizationHelper.GetLocalizedValue("Upgrade_File_Not_Found"));
|
Console.WriteLine(Resx.Resource.UpgradeFileNotFound);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(LocalizationHelper.GetLocalizedValue("Try_Terminate_Process"));
|
Console.WriteLine(Resx.Resource.TryTerminateProcess);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var existing = Process.GetProcessesByName(V2rayN);
|
var existing = Process.GetProcessesByName(V2rayN);
|
||||||
@@ -35,10 +35,10 @@ namespace AmazTool
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Access may be denied without admin right. The user may not be an administrator.
|
// Access may be denied without admin right. The user may not be an administrator.
|
||||||
Console.WriteLine(LocalizationHelper.GetLocalizedValue("Failed_Terminate_Process") + ex.StackTrace);
|
Console.WriteLine(Resx.Resource.FailedTerminateProcess + ex.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(LocalizationHelper.GetLocalizedValue("Start_Unzipping"));
|
Console.WriteLine(Resx.Resource.StartUnzipping);
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -81,16 +81,16 @@ namespace AmazTool
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine(LocalizationHelper.GetLocalizedValue("Failed_Upgrade") + ex.StackTrace);
|
Console.WriteLine(Resx.Resource.FailedUpgrade + ex.StackTrace);
|
||||||
//return;
|
//return;
|
||||||
}
|
}
|
||||||
if (sb.Length > 0)
|
if (sb.Length > 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine(LocalizationHelper.GetLocalizedValue("Failed_Upgrade") + sb.ToString());
|
Console.WriteLine(Resx.Resource.FailedUpgrade + sb.ToString());
|
||||||
//return;
|
//return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(LocalizationHelper.GetLocalizedValue("Restart_v2rayN"));
|
Console.WriteLine(Resx.Resource.Restartv2rayN);
|
||||||
Waiting(9);
|
Waiting(9);
|
||||||
Process process = new()
|
Process process = new()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace PacLib;
|
|
||||||
|
|
||||||
public class PacHandler
|
|
||||||
{
|
|
||||||
private static string _configPath;
|
|
||||||
private static int _httpPort;
|
|
||||||
private static int _pacPort;
|
|
||||||
private static TcpListener? _tcpListener;
|
|
||||||
private static byte[] _writeContent;
|
|
||||||
private static bool _isRunning;
|
|
||||||
private static bool _needRestart = true;
|
|
||||||
|
|
||||||
public static async Task Start(string configPath, int httpPort, int pacPort)
|
|
||||||
{
|
|
||||||
_needRestart = (configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning);
|
|
||||||
|
|
||||||
_configPath = configPath;
|
|
||||||
_httpPort = httpPort;
|
|
||||||
_pacPort = pacPort;
|
|
||||||
|
|
||||||
await InitText();
|
|
||||||
|
|
||||||
if (_needRestart)
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
RunListener();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task InitText()
|
|
||||||
{
|
|
||||||
var path = Path.Combine(_configPath, "pac.txt");
|
|
||||||
if (!File.Exists(path))
|
|
||||||
{
|
|
||||||
await File.AppendAllTextAsync(path, Resources.ResourceManager.GetString("pac"));
|
|
||||||
}
|
|
||||||
|
|
||||||
var pacText = (await File.ReadAllTextAsync(path)).Replace("__PROXY__", $"PROXY 127.0.0.1:{_httpPort};DIRECT;");
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("HTTP/1.0 200 OK");
|
|
||||||
sb.AppendLine("Content-type:application/x-ns-proxy-autoconfig");
|
|
||||||
sb.AppendLine("Connection:close");
|
|
||||||
sb.AppendLine("Content-Length:" + Encoding.UTF8.GetByteCount(pacText));
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.Append(pacText);
|
|
||||||
_writeContent = Encoding.UTF8.GetBytes(sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RunListener()
|
|
||||||
{
|
|
||||||
_tcpListener = TcpListener.Create(_pacPort);
|
|
||||||
_isRunning = true;
|
|
||||||
_tcpListener.Start();
|
|
||||||
Task.Factory.StartNew(async () =>
|
|
||||||
{
|
|
||||||
while (_isRunning)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!_tcpListener.Pending())
|
|
||||||
{
|
|
||||||
await Task.Delay(10);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var client = await _tcpListener.AcceptTcpClientAsync();
|
|
||||||
await Task.Run(() => { WriteContent(client); });
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, TaskCreationOptions.LongRunning);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void WriteContent(TcpClient client)
|
|
||||||
{
|
|
||||||
var stream = client.GetStream();
|
|
||||||
stream.Write(_writeContent, 0, _writeContent.Length);
|
|
||||||
stream.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Stop()
|
|
||||||
{
|
|
||||||
if (_tcpListener == null) return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_isRunning = false;
|
|
||||||
_tcpListener.Stop();
|
|
||||||
_tcpListener = null;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Update="Resources.Designer.cs">
|
|
||||||
<DesignTime>True</DesignTime>
|
|
||||||
<AutoGen>True</AutoGen>
|
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<EmbeddedResource Update="Resources.resx">
|
|
||||||
<Generator>ResXFileCodeGenerator</Generator>
|
|
||||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
|
||||||
</EmbeddedResource>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
95
v2rayN/PacLib/Resources.Designer.cs
generated
95
v2rayN/PacLib/Resources.Designer.cs
generated
@@ -1,95 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
// <auto-generated>
|
|
||||||
// 此代码由工具生成。
|
|
||||||
// 运行时版本:4.0.30319.42000
|
|
||||||
//
|
|
||||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
|
||||||
// 重新生成代码,这些更改将会丢失。
|
|
||||||
// </auto-generated>
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace PacLib {
|
|
||||||
using System;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
|
||||||
/// </summary>
|
|
||||||
// 此类是由 StronglyTypedResourceBuilder
|
|
||||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
|
||||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
|
||||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
|
||||||
internal class Resources {
|
|
||||||
|
|
||||||
private static global::System.Resources.ResourceManager resourceMan;
|
|
||||||
|
|
||||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
|
||||||
|
|
||||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
|
||||||
internal Resources() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
|
||||||
/// </summary>
|
|
||||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
|
||||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
|
||||||
get {
|
|
||||||
if (object.ReferenceEquals(resourceMan, null)) {
|
|
||||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PacLib.Resources", typeof(Resources).Assembly);
|
|
||||||
resourceMan = temp;
|
|
||||||
}
|
|
||||||
return resourceMan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 重写当前线程的 CurrentUICulture 属性,对
|
|
||||||
/// 使用此强类型资源类的所有资源查找执行重写。
|
|
||||||
/// </summary>
|
|
||||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
|
||||||
internal static global::System.Globalization.CultureInfo Culture {
|
|
||||||
get {
|
|
||||||
return resourceCulture;
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
resourceCulture = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查找类似 var proxy = '__PROXY__';
|
|
||||||
///var rules = [
|
|
||||||
/// [
|
|
||||||
/// [],
|
|
||||||
/// []
|
|
||||||
/// ],
|
|
||||||
/// [
|
|
||||||
/// [
|
|
||||||
/// "aftygh.gov.tw",
|
|
||||||
/// "aide.gov.tw",
|
|
||||||
/// "aliyun.com",
|
|
||||||
/// "arte.gov.tw",
|
|
||||||
/// "baidu.com",
|
|
||||||
/// "chinaso.com",
|
|
||||||
/// "chinaz.com",
|
|
||||||
/// "chukuang.gov.tw",
|
|
||||||
/// "cycab.gov.tw",
|
|
||||||
/// "dbnsa.gov.tw",
|
|
||||||
/// "df.gov.tw",
|
|
||||||
/// "eastcoast-nsa.gov.tw",
|
|
||||||
/// "erv-nsa.gov.tw",
|
|
||||||
/// "grb.gov.tw",
|
|
||||||
/// "haosou.com",
|
|
||||||
/// [字符串的其余部分被截断]"; 的本地化字符串。
|
|
||||||
/// </summary>
|
|
||||||
internal static string pac {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("pac", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
kcp,
|
kcp,
|
||||||
ws,
|
ws,
|
||||||
httpupgrade,
|
httpupgrade,
|
||||||
splithttp,
|
|
||||||
xhttp,
|
xhttp,
|
||||||
h2,
|
h2,
|
||||||
http,
|
http,
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
public const string ClashMixinYaml = NamespaceSample + "clash_mixin_yaml";
|
public const string ClashMixinYaml = NamespaceSample + "clash_mixin_yaml";
|
||||||
public const string ClashTunYaml = NamespaceSample + "clash_tun_yaml";
|
public const string ClashTunYaml = NamespaceSample + "clash_tun_yaml";
|
||||||
public const string LinuxAutostartConfig = NamespaceSample + "linux_autostart_config";
|
public const string LinuxAutostartConfig = NamespaceSample + "linux_autostart_config";
|
||||||
|
public const string PacFileName = NamespaceSample + "pac";
|
||||||
|
|
||||||
public const string DefaultSecurity = "auto";
|
public const string DefaultSecurity = "auto";
|
||||||
public const string DefaultNetwork = "tcp";
|
public const string DefaultNetwork = "tcp";
|
||||||
@@ -179,7 +180,7 @@
|
|||||||
public static readonly List<string> SsSecuritiesInXray = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "xchacha20-poly1305", "xchacha20-ietf-poly1305", "none", "plain", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" };
|
public static readonly List<string> SsSecuritiesInXray = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "xchacha20-poly1305", "xchacha20-ietf-poly1305", "none", "plain", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" };
|
||||||
public static readonly List<string> SsSecuritiesInSingbox = new() { "aes-256-gcm", "aes-192-gcm", "aes-128-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "none", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20" };
|
public static readonly List<string> SsSecuritiesInSingbox = new() { "aes-256-gcm", "aes-192-gcm", "aes-128-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "none", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20" };
|
||||||
public static readonly List<string> Flows = new() { "", "xtls-rprx-vision", "xtls-rprx-vision-udp443" };
|
public static readonly List<string> Flows = new() { "", "xtls-rprx-vision", "xtls-rprx-vision-udp443" };
|
||||||
public static readonly List<string> Networks = new() { "tcp", "kcp", "ws", "httpupgrade", "xhttp", "splithttp", "h2", "quic", "grpc" };
|
public static readonly List<string> Networks = new() { "tcp", "kcp", "ws", "httpupgrade", "xhttp", "h2", "quic", "grpc" };
|
||||||
public static readonly List<string> KcpHeaderTypes = new() { "srtp", "utp", "wechat-video", "dtls", "wireguard" };
|
public static readonly List<string> KcpHeaderTypes = new() { "srtp", "utp", "wechat-video", "dtls", "wireguard" };
|
||||||
public static readonly List<string> CoreTypes = new() { "v2fly", "Xray", "sing_box" };
|
public static readonly List<string> CoreTypes = new() { "v2fly", "Xray", "sing_box" };
|
||||||
public static readonly List<string> CoreTypes4VLESS = new() { "Xray", "sing_box" };
|
public static readonly List<string> CoreTypes4VLESS = new() { "Xray", "sing_box" };
|
||||||
|
|||||||
@@ -383,7 +383,7 @@ namespace ServiceLib.Handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
var item = await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(t => t.Port > 0);
|
var item = await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(t => t.Port > 0);
|
||||||
return await SetDefaultServerIndex(config, item.IndexId);
|
return await SetDefaultServerIndex(config, item?.IndexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<ProfileItem?> GetDefaultServer(Config config)
|
public static async Task<ProfileItem?> GetDefaultServer(Config config)
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
case nameof(ETransport.xhttp):
|
case nameof(ETransport.xhttp):
|
||||||
if (Utils.IsNotEmpty(item.RequestHost))
|
if (Utils.IsNotEmpty(item.RequestHost))
|
||||||
{
|
{
|
||||||
@@ -179,7 +178,6 @@ namespace ServiceLib.Handler.Fmt
|
|||||||
item.Path = Utils.UrlDecode(query["path"] ?? "/");
|
item.Path = Utils.UrlDecode(query["path"] ?? "/");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
case nameof(ETransport.xhttp):
|
case nameof(ETransport.xhttp):
|
||||||
item.RequestHost = Utils.UrlDecode(query["host"] ?? "");
|
item.RequestHost = Utils.UrlDecode(query["host"] ?? "");
|
||||||
item.Path = Utils.UrlDecode(query["path"] ?? "/");
|
item.Path = Utils.UrlDecode(query["path"] ?? "/");
|
||||||
|
|||||||
105
v2rayN/ServiceLib/Handler/PacHandler.cs
Normal file
105
v2rayN/ServiceLib/Handler/PacHandler.cs
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace ServiceLib.Handler
|
||||||
|
{
|
||||||
|
public class PacHandler
|
||||||
|
{
|
||||||
|
private static string _configPath;
|
||||||
|
private static int _httpPort;
|
||||||
|
private static int _pacPort;
|
||||||
|
private static TcpListener? _tcpListener;
|
||||||
|
private static byte[] _writeContent;
|
||||||
|
private static bool _isRunning;
|
||||||
|
private static bool _needRestart = true;
|
||||||
|
|
||||||
|
public static async Task Start(string configPath, int httpPort, int pacPort)
|
||||||
|
{
|
||||||
|
_needRestart = (configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning);
|
||||||
|
|
||||||
|
_configPath = configPath;
|
||||||
|
_httpPort = httpPort;
|
||||||
|
_pacPort = pacPort;
|
||||||
|
|
||||||
|
await InitText();
|
||||||
|
|
||||||
|
if (_needRestart)
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
RunListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task InitText()
|
||||||
|
{
|
||||||
|
var path = Path.Combine(_configPath, "pac.txt");
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
var pac = Utils.GetEmbedText(Global.PacFileName);
|
||||||
|
await File.AppendAllTextAsync(path, pac);
|
||||||
|
}
|
||||||
|
|
||||||
|
var pacText =
|
||||||
|
(await File.ReadAllTextAsync(path)).Replace("__PROXY__", $"PROXY 127.0.0.1:{_httpPort};DIRECT;");
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine("HTTP/1.0 200 OK");
|
||||||
|
sb.AppendLine("Content-type:application/x-ns-proxy-autoconfig");
|
||||||
|
sb.AppendLine("Connection:close");
|
||||||
|
sb.AppendLine("Content-Length:" + Encoding.UTF8.GetByteCount(pacText));
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.Append(pacText);
|
||||||
|
_writeContent = Encoding.UTF8.GetBytes(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RunListener()
|
||||||
|
{
|
||||||
|
_tcpListener = TcpListener.Create(_pacPort);
|
||||||
|
_isRunning = true;
|
||||||
|
_tcpListener.Start();
|
||||||
|
Task.Factory.StartNew(async () =>
|
||||||
|
{
|
||||||
|
while (_isRunning)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!_tcpListener.Pending())
|
||||||
|
{
|
||||||
|
await Task.Delay(10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var client = await _tcpListener.AcceptTcpClientAsync();
|
||||||
|
await Task.Run(() => { WriteContent(client); });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, TaskCreationOptions.LongRunning);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteContent(TcpClient client)
|
||||||
|
{
|
||||||
|
var stream = client.GetStream();
|
||||||
|
stream.Write(_writeContent, 0, _writeContent.Length);
|
||||||
|
stream.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Stop()
|
||||||
|
{
|
||||||
|
if (_tcpListener == null) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_isRunning = false;
|
||||||
|
_tcpListener.Stop();
|
||||||
|
_tcpListener = null;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using PacLib;
|
namespace ServiceLib.Handler.SysProxy
|
||||||
|
|
||||||
namespace ServiceLib.Handler.SysProxy
|
|
||||||
{
|
{
|
||||||
public static class SysProxyHandler
|
public static class SysProxyHandler
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<Version>7.2.0</Version>
|
<Version>7.2.1</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
<EmbeddedResource Include="Sample\custom_routing_white" />
|
<EmbeddedResource Include="Sample\custom_routing_white" />
|
||||||
<EmbeddedResource Include="Sample\dns_singbox_normal" />
|
<EmbeddedResource Include="Sample\dns_singbox_normal" />
|
||||||
<EmbeddedResource Include="Sample\dns_v2ray_normal" />
|
<EmbeddedResource Include="Sample\dns_v2ray_normal" />
|
||||||
|
<EmbeddedResource Include="Sample\pac" />
|
||||||
<EmbeddedResource Include="Sample\SampleClientConfig" />
|
<EmbeddedResource Include="Sample\SampleClientConfig" />
|
||||||
<EmbeddedResource Include="Sample\SampleHttpRequest" />
|
<EmbeddedResource Include="Sample\SampleHttpRequest" />
|
||||||
<EmbeddedResource Include="Sample\SampleHttpResponse" />
|
<EmbeddedResource Include="Sample\SampleHttpResponse" />
|
||||||
@@ -46,11 +47,6 @@
|
|||||||
<EmbeddedResource Include="Sample\linux_autostart_config" />
|
<EmbeddedResource Include="Sample\linux_autostart_config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\PacLib\PacLib.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Update="Resx\ResUI.Designer.cs">
|
<Compile Update="Resx\ResUI.Designer.cs">
|
||||||
<DependentUpon>ResUI.resx</DependentUpon>
|
<DependentUpon>ResUI.resx</DependentUpon>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
ret.Msg = ResUI.CheckServerSettings;
|
ret.Msg = ResUI.CheckServerSettings;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.splithttp) or nameof(ETransport.xhttp))
|
if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.xhttp))
|
||||||
{
|
{
|
||||||
ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
|
ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -911,8 +911,7 @@ namespace ServiceLib.Services.CoreConfig
|
|||||||
streamSettings.httpupgradeSettings = httpupgradeSettings;
|
streamSettings.httpupgradeSettings = httpupgradeSettings;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
//splithttp //xhttp
|
//xhttp
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
case nameof(ETransport.xhttp):
|
case nameof(ETransport.xhttp):
|
||||||
streamSettings.network = ETransport.xhttp.ToString();
|
streamSettings.network = ETransport.xhttp.ToString();
|
||||||
XhttpSettings4Ray xhttpSettings = new()
|
XhttpSettings4Ray xhttpSettings = new()
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ namespace v2rayN.Desktop.Views
|
|||||||
cmbHeaderType.Items.Add(it);
|
cmbHeaderType.Items.Add(it);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (network is nameof(ETransport.splithttp) or nameof(ETransport.xhttp))
|
else if (network is nameof(ETransport.xhttp))
|
||||||
{
|
{
|
||||||
Global.XhttpMode.ForEach(it =>
|
Global.XhttpMode.ForEach(it =>
|
||||||
{
|
{
|
||||||
@@ -350,7 +350,6 @@ namespace v2rayN.Desktop.Views
|
|||||||
tipPath.Text = ResUI.TransportPathTip1;
|
tipPath.Text = ResUI.TransportPathTip1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
case nameof(ETransport.xhttp):
|
case nameof(ETransport.xhttp):
|
||||||
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
||||||
tipPath.Text = ResUI.TransportPathTip1;
|
tipPath.Text = ResUI.TransportPathTip1;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
Binding="{Binding Remarks}"
|
Binding="{Binding Remarks}"
|
||||||
Header="{x:Static resx:ResUI.LvRemarks}" />
|
Header="{x:Static resx:ResUI.LvRemarks}" />
|
||||||
<DataGridTextColumn
|
<DataGridTextColumn
|
||||||
Width="150"
|
Width="*"
|
||||||
Binding="{Binding Url}"
|
Binding="{Binding Url}"
|
||||||
Header="{x:Static resx:ResUI.LvUrl}" />
|
Header="{x:Static resx:ResUI.LvUrl}" />
|
||||||
<DataGridCheckBoxColumn
|
<DataGridCheckBoxColumn
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ VisualStudioVersion = 17.3.32811.315
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "v2rayN", "v2rayN\v2rayN.csproj", "{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "v2rayN", "v2rayN\v2rayN.csproj", "{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PacLib", "PacLib\PacLib.csproj", "{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceLib", "ServiceLib\ServiceLib.csproj", "{1B6456C4-FFAA-4298-80F6-7B689A6E9243}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceLib", "ServiceLib\ServiceLib.csproj", "{1B6456C4-FFAA-4298-80F6-7B689A6E9243}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "v2rayN.Desktop", "v2rayN.Desktop\v2rayN.Desktop.csproj", "{5D16541A-F971-4C17-9315-BB8955E3F984}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "v2rayN.Desktop", "v2rayN.Desktop\v2rayN.Desktop.csproj", "{5D16541A-F971-4C17-9315-BB8955E3F984}"
|
||||||
@@ -23,10 +21,6 @@ Global
|
|||||||
{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{1B6456C4-FFAA-4298-80F6-7B689A6E9243}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{1B6456C4-FFAA-4298-80F6-7B689A6E9243}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{1B6456C4-FFAA-4298-80F6-7B689A6E9243}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1B6456C4-FFAA-4298-80F6-7B689A6E9243}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1B6456C4-FFAA-4298-80F6-7B689A6E9243}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1B6456C4-FFAA-4298-80F6-7B689A6E9243}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<Application
|
<Application
|
||||||
x:Class="v2rayN.App"
|
x:Class="v2rayN.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
ShutdownMode="OnExplicitShutdown"
|
ShutdownMode="OnExplicitShutdown"
|
||||||
StartupUri="Views/MainWindow.xaml">
|
StartupUri="Views/MainWindow.xaml">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ namespace v2rayN.Views
|
|||||||
cmbHeaderType.Items.Add(it);
|
cmbHeaderType.Items.Add(it);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (network is nameof(ETransport.splithttp) or nameof(ETransport.xhttp))
|
else if (network is nameof(ETransport.xhttp))
|
||||||
{
|
{
|
||||||
Global.XhttpMode.ForEach(it =>
|
Global.XhttpMode.ForEach(it =>
|
||||||
{
|
{
|
||||||
@@ -345,7 +345,6 @@ namespace v2rayN.Views
|
|||||||
tipPath.Text = ResUI.TransportPathTip1;
|
tipPath.Text = ResUI.TransportPathTip1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nameof(ETransport.splithttp):
|
|
||||||
case nameof(ETransport.xhttp):
|
case nameof(ETransport.xhttp):
|
||||||
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
tipRequestHost.Text = ResUI.TransportRequestHostTip2;
|
||||||
tipPath.Text = ResUI.TransportPathTip1;
|
tipPath.Text = ResUI.TransportPathTip1;
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
Binding="{Binding Remarks}"
|
Binding="{Binding Remarks}"
|
||||||
Header="{x:Static resx:ResUI.LvRemarks}" />
|
Header="{x:Static resx:ResUI.LvRemarks}" />
|
||||||
<DataGridTextColumn
|
<DataGridTextColumn
|
||||||
Width="150"
|
Width="*"
|
||||||
Binding="{Binding Url}"
|
Binding="{Binding Url}"
|
||||||
Header="{x:Static resx:ResUI.LvUrl}" />
|
Header="{x:Static resx:ResUI.LvUrl}" />
|
||||||
<DataGridCheckBoxColumn
|
<DataGridCheckBoxColumn
|
||||||
|
|||||||
Reference in New Issue
Block a user