From a418be478a915d9b0726e5d03e691c74f176fe65 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 5 Sep 2023 17:18:11 +0800 Subject: Continue to develop mysterious tool. --- tools/Crupest.V2ray/.gitignore | 5 ++ tools/Crupest.V2ray/Crupest.V2ray/.gitignore | 1 + .../Crupest.V2ray/ConfigGenerationWatcher.cs | 55 +++++++++++++ .../Crupest.V2ray/Crupest.V2ray.csproj | 22 +++++ tools/Crupest.V2ray/Crupest.V2ray/FileUtility.cs | 94 ++++++++++++++++++++++ .../Crupest.V2ray/GeoDataDownloader.cs | 42 ++++++++++ tools/Crupest.V2ray/Crupest.V2ray/Program.cs | 45 +++++++++++ .../PublishProfiles/FolderProfile.pubxml | 13 +++ tools/Crupest.V2ray/Crupest.V2ray/V2rayConfig.cs | 49 +++++++++++ .../Crupest.V2ray/Crupest.V2ray/V2rayController.cs | 88 ++++++++++++++++++++ tools/Crupest.V2ray/Crupest.V2ray/V2rayRouting.cs | 52 ++++++++++++ .../Crupest.V2ray/V2rayRoutingRule.cs | 25 ++++++ .../Crupest.V2ray/V2rayRoutingRuleMatcher.cs | 74 +++++++++++++++++ .../Crupest.V2ray/Crupest.V2ray/V2rayVmessProxy.cs | 54 +++++++++++++ .../Crupest.V2ray/config.json.template | 63 +++++++++++++++ tools/Crupest.V2ray/Crupest.V2ray/proxy.txt | 16 ++++ tools/Crupest.V2ray/CrupestV2ray.sln | 33 ++++++++ tools/V2rayConfigGen/.gitignore | 2 - tools/V2rayConfigGen/V2rayConfigGen.sln | 30 ------- tools/V2rayConfigGen/V2rayConfigGen/.gitignore | 1 - tools/V2rayConfigGen/V2rayConfigGen/FileUtility.cs | 94 ---------------------- tools/V2rayConfigGen/V2rayConfigGen/Program.cs | 22 ----- tools/V2rayConfigGen/V2rayConfigGen/V2rayConfig.cs | 48 ----------- .../V2rayConfigGen/V2rayConfigGen.csproj | 22 ----- .../V2rayConfigGen/V2rayConfigGen/V2rayRouting.cs | 52 ------------ .../V2rayConfigGen/V2rayRoutingRule.cs | 27 ------- .../V2rayConfigGen/V2rayRoutingRuleMatcher.cs | 72 ----------------- .../V2rayConfigGen/V2rayVmessProxy.cs | 52 ------------ .../V2rayConfigGen/config.json.template | 63 --------------- tools/V2rayConfigGen/V2rayConfigGen/proxy.txt | 16 ---- 30 files changed, 731 insertions(+), 501 deletions(-) create mode 100644 tools/Crupest.V2ray/.gitignore create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/.gitignore create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/ConfigGenerationWatcher.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/Crupest.V2ray.csproj create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/FileUtility.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/GeoDataDownloader.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/Program.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/Properties/PublishProfiles/FolderProfile.pubxml create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/V2rayConfig.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/V2rayController.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/V2rayRouting.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/V2rayRoutingRule.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/V2rayRoutingRuleMatcher.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/V2rayVmessProxy.cs create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/config.json.template create mode 100644 tools/Crupest.V2ray/Crupest.V2ray/proxy.txt create mode 100644 tools/Crupest.V2ray/CrupestV2ray.sln delete mode 100755 tools/V2rayConfigGen/.gitignore delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen.sln delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/.gitignore delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/FileUtility.cs delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/Program.cs delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/V2rayConfig.cs delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/V2rayConfigGen.csproj delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/V2rayRouting.cs delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/V2rayRoutingRule.cs delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/V2rayRoutingRuleMatcher.cs delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/V2rayVmessProxy.cs delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/config.json.template delete mode 100755 tools/V2rayConfigGen/V2rayConfigGen/proxy.txt (limited to 'tools') diff --git a/tools/Crupest.V2ray/.gitignore b/tools/Crupest.V2ray/.gitignore new file mode 100644 index 0000000..15db15d --- /dev/null +++ b/tools/Crupest.V2ray/.gitignore @@ -0,0 +1,5 @@ +.vs +bin +obj +*.pubxml.user +*.csproj.user diff --git a/tools/Crupest.V2ray/Crupest.V2ray/.gitignore b/tools/Crupest.V2ray/Crupest.V2ray/.gitignore new file mode 100644 index 0000000..c936492 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/.gitignore @@ -0,0 +1 @@ +vmess.txt diff --git a/tools/Crupest.V2ray/Crupest.V2ray/ConfigGenerationWatcher.cs b/tools/Crupest.V2ray/Crupest.V2ray/ConfigGenerationWatcher.cs new file mode 100644 index 0000000..9ca5741 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/ConfigGenerationWatcher.cs @@ -0,0 +1,55 @@ +namespace Crupest.V2ray; + +public class ConfigGenerationWatcher +{ + public ConfigGenerationWatcher() : this(Program.ExeDir, Program.ConfigTemplateFileName, Program.VmessConfigFileName, Program.ProxyConfigFileName, Path.Combine(Program.ExeDir, Program.ConfigOutputFileName), new List()) + { + + } + + public ConfigGenerationWatcher(string directory, string configTemplateFileName, string vmessConfigFileName, string proxyConfigFileName, string configOutputPath, List otherWatchFiles) + { + Directory = directory; + ConfigTemplateFileName = configTemplateFileName; + VmessConfigFileName = vmessConfigFileName; + ProxyConfigFileName = proxyConfigFileName; + ConfigOutputPath = configOutputPath; + OtherWatchFiles = otherWatchFiles; + } + + public string Directory { get; set; } + public string ConfigTemplateFileName { get; set; } + public string VmessConfigFileName { get; set; } + public string ProxyConfigFileName { get; set; } + public List OtherWatchFiles { get; set; } + public string ConfigOutputPath { get; set; } + + public string ConfigTemplateFilePath => Path.Combine(Directory, ConfigTemplateFileName); + public string VmessConfigFilePath => Path.Combine(Directory, VmessConfigFileName); + public string ProxyConfigFilePath => Path.Combine(Directory, ProxyConfigFileName); + + public delegate void OnConfigChangedHandler(); + + public void Generate() + { + var config = V2rayConfig.FromFiles(ConfigTemplateFilePath, VmessConfigFilePath, ProxyConfigFilePath); + + File.WriteAllText(ConfigOutputPath, config.ToJson()); + } + + public void Run(OnConfigChangedHandler onChanged) + { + var sourceWatcher = new FileSystemWatcher(Directory); + sourceWatcher.Filters.Add(ConfigTemplateFileName); + sourceWatcher.Filters.Add(VmessConfigFileName); + sourceWatcher.Filters.Add(ProxyConfigFileName); + OtherWatchFiles.ForEach((f) => sourceWatcher.Filters.Add(f)); + sourceWatcher.NotifyFilter = NotifyFilters.LastWrite; + + while (true) + { + var result = sourceWatcher.WaitForChanged(WatcherChangeTypes.Changed); + onChanged(); + } + } +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/Crupest.V2ray.csproj b/tools/Crupest.V2ray/Crupest.V2ray/Crupest.V2ray.csproj new file mode 100644 index 0000000..38f0937 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/Crupest.V2ray.csproj @@ -0,0 +1,22 @@ + + + + Exe + net7.0 + enable + enable + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/tools/Crupest.V2ray/Crupest.V2ray/FileUtility.cs b/tools/Crupest.V2ray/Crupest.V2ray/FileUtility.cs new file mode 100644 index 0000000..08de673 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/FileUtility.cs @@ -0,0 +1,94 @@ +using System.Text.Json; +using System.Text.RegularExpressions; + +namespace Crupest.V2ray; + +public static partial class FileUtility +{ + public static List ReadList(string str) + { + return str.Split("\n", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList(); + } + + public static Dictionary ReadDictionary(string str, bool keyToLower = true) + { + var lines = str.Split("\n", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + var result = new Dictionary(); + for (int lineNumber = 0; lineNumber < lines.Length; lineNumber++) + { + var line = lines[lineNumber]; + if (!line.Contains('=')) + { + throw new FormatException($"Line {lineNumber + 1} does not contain a '='."); + } + var equalIndex = line.IndexOf('='); + var key = line[..equalIndex].Trim(); + if (keyToLower) key = key.ToLower(); + var value = line[(equalIndex + 1)..].Trim(); + result[key] = value; + } + return result; + } + + public static List ReadListFile(string path, bool required = true) + { + if (File.Exists(path)) + { + return ReadList(File.ReadAllText(path)); + } + else + { + if (required) + { + throw new FileNotFoundException($"File {path} is required but it does not exist."); + } + return new(); + } + } + + public static Dictionary ReadDictionaryFile(string path, bool required = true, bool keyToLower = true) + { + if (File.Exists(path)) + { + return ReadDictionary(File.ReadAllText(path), keyToLower); + } + else + { + if (required) + { + throw new FileNotFoundException($"File {path} is required but it does not exist."); + } + return new(); + } + } + + private static Regex TemplateValuePattern { get; } = CreateTemplateValuePattern(); + + [GeneratedRegex(@"\$\{\s*([_a-zA-Z][_a-zA-Z0-9]*)\s*\}")] + private static partial Regex CreateTemplateValuePattern(); + + public static string TextFromTemplate(string template, Dictionary dict) + { + return TemplateValuePattern.Replace(template, (match) => + { + var key = match.Groups[1].Value; + if (dict.ContainsKey(key)) + { + return dict[key]; + } + return match.Value; + }); + } + + public static string JsonFormat(string json) + { + var options = new JsonSerializerOptions + { + WriteIndented = true, + AllowTrailingCommas = true, + ReadCommentHandling = JsonCommentHandling.Skip + }; + + return JsonSerializer.Serialize(JsonSerializer.Deserialize(json, options), options); + } +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/GeoDataDownloader.cs b/tools/Crupest.V2ray/Crupest.V2ray/GeoDataDownloader.cs new file mode 100644 index 0000000..d3efc1f --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/GeoDataDownloader.cs @@ -0,0 +1,42 @@ +namespace Crupest.V2ray; + +public class GeoDataDownloader +{ + public record GithubReleaseAsset(string ResourceName, string User, string Repo, string AssetName, string Output); + + public GeoDataDownloader() + { + Resources = new() + { + new("geosite", "v2fly", "domain-list-community", "dlc.dat", "geosite.dat"), + new("geoip", "v2fly", "geoip", "geoip.dat", "geoip.dat"), + new("geosite", "v2fly", "geoip", "geoip-only-cn-private.dat", "geoip-only-cn-private.dat") + }; + } + + public List Resources { get; set; } + + public static string GetReleaseFileUrl(string user, string repo, string assetName) + { + return $"https://github.com/{user}/{repo}/releases/latest/download/{assetName}"; + } + + public static void GithubDownload(HttpClient httpClient, string user, string repo, string assetName, string outputPath) + { + using var responseStream = httpClient.GetStreamAsync(GetReleaseFileUrl(user, repo, assetName)).Result; + using var outputFileStream = File.OpenWrite(outputPath); + responseStream.CopyTo(outputFileStream); + } + + public void Download(string outputDir) + { + using var httpClient = new HttpClient(); + + foreach (var resource in Resources) + { + Console.WriteLine($"Downloading {resource.ResourceName}..."); + GithubDownload(httpClient, resource.User, resource.Repo, resource.AssetName, Path.Combine(outputDir, resource.Output)); + Console.WriteLine($"Downloaded {resource.ResourceName}!"); + } + } +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/Program.cs b/tools/Crupest.V2ray/Crupest.V2ray/Program.cs new file mode 100644 index 0000000..793f6e7 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/Program.cs @@ -0,0 +1,45 @@ +using System.Diagnostics; +using System.Reflection; + +namespace Crupest.V2ray; + +public static class Program +{ + public const string ConfigTemplateFileName = "config.json.template"; + public const string VmessConfigFileName = "vmess.txt"; + public const string ProxyConfigFileName = "proxy.txt"; + public const string ConfigOutputFileName = "config.json"; + + public static string ExeDir { get; } = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new Exception("Can't get the path of exe.")); + + + public static void Main(string[] args) + { + if (args.Length != 0) + { + if (args.Length != 1) + { + throw new Exception("Invalid command line arguments."); + } + var verb = args[0].ToLower(); + if (verb == "download-geodata" || verb == "dg") + { + var geoDataDonwloader = new GeoDataDownloader(); + geoDataDonwloader.Download(ExeDir); + return; + } + } + + var v2rayController = new V2rayController(); + var configGenerationWatcher = new ConfigGenerationWatcher(); + + configGenerationWatcher.Generate(); + v2rayController.Start(); + + configGenerationWatcher.Run(() => + { + configGenerationWatcher.Generate(); + v2rayController.Restart(); + }); + } +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/Properties/PublishProfiles/FolderProfile.pubxml b/tools/Crupest.V2ray/Crupest.V2ray/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 0000000..bbdd2ad --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,13 @@ + + + + + Release + Any CPU + bin\Release\net7.0\publish\ + FileSystem + <_TargetId>Folder + + \ No newline at end of file diff --git a/tools/Crupest.V2ray/Crupest.V2ray/V2rayConfig.cs b/tools/Crupest.V2ray/Crupest.V2ray/V2rayConfig.cs new file mode 100644 index 0000000..82dc11c --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/V2rayConfig.cs @@ -0,0 +1,49 @@ +using System.Text.Json; + +namespace Crupest.V2ray; + +public class V2rayConfig +{ + private const string VmessAnchor = "VMESS_PROXY_ANCHOR"; + private const string RoutingAnchor = "ROUTING_ANCHOR"; + + public V2rayConfig(string template, V2rayVmessProxy vmess, V2rayRouting router) + { + Template = template; + Vmess = vmess; + Routing = router; + } + + public string Template { get; set; } + public V2rayVmessProxy Vmess { get; set; } + public V2rayRouting Routing { get; set; } + + public string ToJson(bool pretty = true) + { + var jsonOptions = new JsonSerializerOptions(new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, + }); + + var templateValues = new Dictionary + { + [VmessAnchor] = JsonSerializer.Serialize(Vmess.ToOutboundJsonObject(), jsonOptions), + [RoutingAnchor] = JsonSerializer.Serialize(Routing.ToJsonObject(), jsonOptions) + }; + + return FileUtility.JsonFormat(FileUtility.TextFromTemplate(Template, templateValues)); + } + + public static V2rayConfig FromFiles(string templatePath, string vmessPath, string routingPath) + { + var template = File.ReadAllText(templatePath); + var vmessDict = FileUtility.ReadDictionaryFile(vmessPath); + var proxyRoutingList = FileUtility.ReadListFile(routingPath); + + var vmess = V2rayVmessProxy.FromDictionary(vmessDict); + var routing = V2rayRouting.FromStringList(proxyRoutingList); + + return new V2rayConfig(template, vmess, routing); + } +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/V2rayController.cs b/tools/Crupest.V2ray/Crupest.V2ray/V2rayController.cs new file mode 100644 index 0000000..5b8fcac --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/V2rayController.cs @@ -0,0 +1,88 @@ +using System.Diagnostics; + +namespace Crupest.V2ray; + +public class V2rayController +{ + public const string V2RayAssetLocationEnvironmentVariableName = "V2RAY_LOCATION_ASSET"; + public const string V2RayConfigLocationEnvironmentVariableName = "V2RAY_LOCATION_CONFIG"; + + public V2rayController(string v2rayExePath = "v2ray") : this(v2rayExePath, Program.ExeDir, Program.ExeDir) + { + + } + + public V2rayController(string v2rayExePath, string configDirPath, string assetDirPath) + { + V2rayExePath = v2rayExePath; + ConfigDirPath = configDirPath; + AssetDirPath = assetDirPath; + } + + public string V2rayExePath { get; } + public string ConfigDirPath { get; } + public string AssetDirPath { get; } + public Process? CurrentProcess { get; private set; } + + private Process CreateProcess() + { + var process = new Process(); + + var startInfo = new ProcessStartInfo + { + FileName = V2rayExePath, + }; + startInfo.EnvironmentVariables[V2RayConfigLocationEnvironmentVariableName] = ConfigDirPath; + startInfo.EnvironmentVariables[V2RayAssetLocationEnvironmentVariableName] = AssetDirPath; + + process.StartInfo = startInfo; + process.OutputDataReceived += (_, args) => + { + Console.Out.Write(args.Data); + }; + process.ErrorDataReceived += (_, args) => + { + Console.Error.WriteLine(args.Data); + }; + + return process; + } + + public void Stop() + { + if (CurrentProcess is not null) + { + CurrentProcess.Kill(); + CurrentProcess.Dispose(); + CurrentProcess = null; + Console.WriteLine("V2ray stopped."); + } + } + + public void Start(bool stopOld = false) + { + if (stopOld) Stop(); + + if (CurrentProcess is null) + { + CurrentProcess = CreateProcess(); + CurrentProcess.EnableRaisingEvents = true; + CurrentProcess.Exited += (_, _) => + { + if (CurrentProcess.ExitCode != 0) + { + const string message = "V2ray exits with error."; + Console.Error.WriteLine(message); + throw new Exception(message); + } + }; + CurrentProcess.Start(); + Console.WriteLine("V2ray started."); + } + } + + public void Restart() + { + Start(true); + } +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/V2rayRouting.cs b/tools/Crupest.V2ray/Crupest.V2ray/V2rayRouting.cs new file mode 100644 index 0000000..7265b09 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/V2rayRouting.cs @@ -0,0 +1,52 @@ +namespace Crupest.V2ray; + +public record V2rayRouting(List Rules, string DomainStrategy = "IpOnDemand") +{ + public record DomainRuleJsonObject(List Domains, string OutboundTag, string Type = "field"); + + public record IpRuleJsonObject(List Ip, string OutboundTag, string Type = "field"); + + public record RoutingJsonObject(string DomainStrategy, List Rules); + + public V2rayRouting() : this(new List()) + { + + } + + public RoutingJsonObject ToJsonObject() + { + var ruleJsonObjects = new List(); + + foreach (var (outBoundTag, proxyRules) in V2rayRoutingRule.GroupByOutboundTag(Rules)) + { + foreach (var (matchByKind, rules) in V2rayRoutingRule.GroupByMatchByKind(proxyRules)) + { + ruleJsonObjects.Add( + matchByKind switch + { + V2rayRoutingRuleMatcher.MatchByKind.Ip => new IpRuleJsonObject(rules.Select(r => r.Matcher.ToString()).ToList(), outBoundTag), + V2rayRoutingRuleMatcher.MatchByKind.Domain => new DomainRuleJsonObject(rules.Select(r => r.Matcher.ToString()).ToList(), outBoundTag), + _ => throw new Exception("Unknown match by kind."), + } + ); + } + } + + return new RoutingJsonObject(DomainStrategy, ruleJsonObjects); + } + + public static V2rayRouting FromStringList(List list, string outboundTag = "proxy") + { + var router = new V2rayRouting(); + + foreach (var line in list) + { + var matcher = V2rayRoutingRuleMatcher.Parse(line); + if (matcher != null) + router.Rules.Add(new V2rayRoutingRule(matcher, outboundTag)); + } + + return router; + } +} + diff --git a/tools/Crupest.V2ray/Crupest.V2ray/V2rayRoutingRule.cs b/tools/Crupest.V2ray/Crupest.V2ray/V2rayRoutingRule.cs new file mode 100644 index 0000000..0218183 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/V2rayRoutingRule.cs @@ -0,0 +1,25 @@ +namespace Crupest.V2ray; + +public record V2rayRoutingRule(V2rayRoutingRuleMatcher Matcher, string OutboundTag) +{ + public static Dictionary> GroupByOutboundTag(List rules) + { + var result = new Dictionary>(); + foreach (var group in rules.GroupBy(r => r.OutboundTag)) + { + result[group.Key] = group.ToList(); + } + return result; + } + + public static Dictionary> GroupByMatchByKind(List rules) + { + var result = new Dictionary>(); + foreach (var group in rules.GroupBy(r => r.Matcher.MatchBy)) + { + result[group.Key] = group.ToList(); + } + return result; + } +} + diff --git a/tools/Crupest.V2ray/Crupest.V2ray/V2rayRoutingRuleMatcher.cs b/tools/Crupest.V2ray/Crupest.V2ray/V2rayRoutingRuleMatcher.cs new file mode 100644 index 0000000..a13237c --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/V2rayRoutingRuleMatcher.cs @@ -0,0 +1,74 @@ +namespace Crupest.V2ray; + +public record V2rayRoutingRuleMatcher(V2rayRoutingRuleMatcher.MatchKind Kind, string Value) +{ + public enum MatchByKind + { + Domain, + Ip + } + + public enum MatchKind + { + GeoIp, + GeoSite, + DomainPlain, + DomainSuffix, + DomainRegex, + DomainFull, + } + + public MatchByKind MatchBy + { + get + { + return Kind switch + { + MatchKind.GeoIp => MatchByKind.Ip, + _ => MatchByKind.Domain + }; + } + } + + public static V2rayRoutingRuleMatcher? Parse(string line) + { + if (line.IndexOf('#') != -1) + { + line = line[..line.IndexOf('#')]; + } + + line = line.Trim(); + + if (line.Length == 0) { return null; } + + var kind = MatchKind.DomainSuffix; + + foreach (var name in Enum.GetNames()) + { + if (line.StartsWith(name)) + { + kind = Enum.Parse(name); + line = line[name.Length..]; + line = line.Trim(); + break; + } + } + + return new V2rayRoutingRuleMatcher(kind, line); + } + + + public override string ToString() + { + return Kind switch + { + MatchKind.GeoSite => $"geosite:{Value}", + MatchKind.GeoIp => $"geoip:{Value}", + MatchKind.DomainPlain => Value, + MatchKind.DomainSuffix => $"domain:{Value}", + MatchKind.DomainFull => $"full:{Value}", + MatchKind.DomainRegex => $"regexp:{Value}", + _ => throw new Exception("Unknown matcher kind."), + }; + } +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/V2rayVmessProxy.cs b/tools/Crupest.V2ray/Crupest.V2ray/V2rayVmessProxy.cs new file mode 100644 index 0000000..e701463 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/V2rayVmessProxy.cs @@ -0,0 +1,54 @@ +namespace Crupest.V2ray; + +public class V2rayVmessProxy +{ + public record VmessOutboundJsonObject(string Protocol, SettingsJsonObject Settings, string Tag, StreamSettingsJsonObject StreamSettings) + { + public static VmessOutboundJsonObject ByWs(string address, int port, string uuid, string tag, string path) + { + return new VmessOutboundJsonObject("vmess", new SettingsJsonObject( + new List { new VnextJsonObject(address, port, new List { new VnextUserJsonObject(uuid) }) } + ), tag, StreamSettingsJsonObject.Ws(path)); + } + } + + public record SettingsJsonObject(List Vnext); + + public record VnextJsonObject(string Address, int Port, List Users); + + public record VnextUserJsonObject(string Id, int AlterId = 0, string Security = "auto", int Level = 0); + + public record StreamSettingsJsonObject(string Network, string Security, WsSettingsJsonObject WsSettings) + { + public static StreamSettingsJsonObject Ws(string path) + { + return new StreamSettingsJsonObject("ws", "tls", new WsSettingsJsonObject(path, new())); + } + } + + public record WsSettingsJsonObject(string Path, Dictionary Headers); + + public string Host { get; set; } + public int Port { get; set; } + public string Path { get; set; } + public string UserId { get; set; } + + + public V2rayVmessProxy(string host, int port, string userId, string path) + { + Host = host; + Port = port; + UserId = userId; + Path = path; + } + + public VmessOutboundJsonObject ToOutboundJsonObject(string tag = "proxy") + { + return VmessOutboundJsonObject.ByWs(Host, Port, UserId, tag, Path); + } + + public static V2rayVmessProxy FromDictionary(Dictionary dict) + { + return new V2rayVmessProxy(dict["host"], int.Parse(dict["port"]), dict["userid"], dict["path"]); + } +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/config.json.template b/tools/Crupest.V2ray/Crupest.V2ray/config.json.template new file mode 100644 index 0000000..47187bb --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/config.json.template @@ -0,0 +1,63 @@ +{ + "log": { + "loglevel": "info" + }, + "inbounds": [ + { + "port": 2081, + "listen": "127.0.0.1", + "tag": "socks-inbound", + "protocol": "socks", + "settings": { + "auth": "noauth" + } + }, + { + "port": 2080, + "listen": "127.0.0.1", + "tag": "http-inbound", + "protocol": "http", + "settings": { + "auth": "noauth" + } + } + ], + "outbounds": [ + { + "protocol": "freedom", + "settings": {}, + "tag": "direct" + }, + { + "protocol": "blackhole", + "settings": {}, + "tag": "blocked" + }, + ${VMESS_PROXY_ANCHOR} + ], + "routing": ${ROUTING_ANCHOR}, + "dns": { + "hosts": {}, + "servers": [ + "https://doh.pub/dns-query", + "1.1.1.1", + "8.8.8.8", + "localhost" + ] + }, + "policy": { + "levels": { + "0": { + "uplinkOnly": 0, + "downlinkOnly": 0 + } + }, + "system": { + "statsInboundUplink": false, + "statsInboundDownlink": false, + "statsOutboundUplink": false, + "statsOutboundDownlink": false + } + }, + "other": {} +} diff --git a/tools/Crupest.V2ray/Crupest.V2ray/proxy.txt b/tools/Crupest.V2ray/Crupest.V2ray/proxy.txt new file mode 100644 index 0000000..4e9d3e8 --- /dev/null +++ b/tools/Crupest.V2ray/Crupest.V2ray/proxy.txt @@ -0,0 +1,16 @@ +GeoSite github +GeoSite google +GeoSite youtube +GeoSite twitter +GeoSite facebook +GeoSite discord +GeoSite reddit +GeoSite wikimedia +GeoSite stackexchange +GeoSite libgen +GeoSite python +GeoSite ruby +GeoSite creativecommons +GeoSite sci-hub +GeoSite v2ray +GeoSite imgur diff --git a/tools/Crupest.V2ray/CrupestV2ray.sln b/tools/Crupest.V2ray/CrupestV2ray.sln new file mode 100644 index 0000000..3045b4e --- /dev/null +++ b/tools/Crupest.V2ray/CrupestV2ray.sln @@ -0,0 +1,33 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34024.191 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F4C2CE80-CDF8-4B08-8912-D1F0F14196AD}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Crupest.V2ray", "Crupest.V2ray\Crupest.V2ray.csproj", "{154D49F2-242E-4384-8D34-73774231AA75}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {154D49F2-242E-4384-8D34-73774231AA75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {154D49F2-242E-4384-8D34-73774231AA75}.Debug|Any CPU.Build.0 = Debug|Any CPU + {154D49F2-242E-4384-8D34-73774231AA75}.Release|Any CPU.ActiveCfg = Release|Any CPU + {154D49F2-242E-4384-8D34-73774231AA75}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {154D49F2-242E-4384-8D34-73774231AA75} = {F4C2CE80-CDF8-4B08-8912-D1F0F14196AD} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B1E8FD9C-9157-4F4E-8265-4B37F30EEC5E} + EndGlobalSection +EndGlobal diff --git a/tools/V2rayConfigGen/.gitignore b/tools/V2rayConfigGen/.gitignore deleted file mode 100755 index 1746e32..0000000 --- a/tools/V2rayConfigGen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bin -obj diff --git a/tools/V2rayConfigGen/V2rayConfigGen.sln b/tools/V2rayConfigGen/V2rayConfigGen.sln deleted file mode 100755 index e864a06..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen.sln +++ /dev/null @@ -1,30 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.7.34024.191 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "V2rayConfigGen", "V2rayConfigGen\V2rayConfigGen.csproj", "{05719320-C91F-4D2A-82A5-1D0247DDB389}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F4C2CE80-CDF8-4B08-8912-D1F0F14196AD}" - ProjectSection(SolutionItems) = preProject - .gitignore = .gitignore - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {05719320-C91F-4D2A-82A5-1D0247DDB389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {05719320-C91F-4D2A-82A5-1D0247DDB389}.Debug|Any CPU.Build.0 = Debug|Any CPU - {05719320-C91F-4D2A-82A5-1D0247DDB389}.Release|Any CPU.ActiveCfg = Release|Any CPU - {05719320-C91F-4D2A-82A5-1D0247DDB389}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {B1E8FD9C-9157-4F4E-8265-4B37F30EEC5E} - EndGlobalSection -EndGlobal diff --git a/tools/V2rayConfigGen/V2rayConfigGen/.gitignore b/tools/V2rayConfigGen/V2rayConfigGen/.gitignore deleted file mode 100755 index c936492..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vmess.txt diff --git a/tools/V2rayConfigGen/V2rayConfigGen/FileUtility.cs b/tools/V2rayConfigGen/V2rayConfigGen/FileUtility.cs deleted file mode 100755 index 08de673..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/FileUtility.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System.Text.Json; -using System.Text.RegularExpressions; - -namespace Crupest.V2ray; - -public static partial class FileUtility -{ - public static List ReadList(string str) - { - return str.Split("\n", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList(); - } - - public static Dictionary ReadDictionary(string str, bool keyToLower = true) - { - var lines = str.Split("\n", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); - var result = new Dictionary(); - for (int lineNumber = 0; lineNumber < lines.Length; lineNumber++) - { - var line = lines[lineNumber]; - if (!line.Contains('=')) - { - throw new FormatException($"Line {lineNumber + 1} does not contain a '='."); - } - var equalIndex = line.IndexOf('='); - var key = line[..equalIndex].Trim(); - if (keyToLower) key = key.ToLower(); - var value = line[(equalIndex + 1)..].Trim(); - result[key] = value; - } - return result; - } - - public static List ReadListFile(string path, bool required = true) - { - if (File.Exists(path)) - { - return ReadList(File.ReadAllText(path)); - } - else - { - if (required) - { - throw new FileNotFoundException($"File {path} is required but it does not exist."); - } - return new(); - } - } - - public static Dictionary ReadDictionaryFile(string path, bool required = true, bool keyToLower = true) - { - if (File.Exists(path)) - { - return ReadDictionary(File.ReadAllText(path), keyToLower); - } - else - { - if (required) - { - throw new FileNotFoundException($"File {path} is required but it does not exist."); - } - return new(); - } - } - - private static Regex TemplateValuePattern { get; } = CreateTemplateValuePattern(); - - [GeneratedRegex(@"\$\{\s*([_a-zA-Z][_a-zA-Z0-9]*)\s*\}")] - private static partial Regex CreateTemplateValuePattern(); - - public static string TextFromTemplate(string template, Dictionary dict) - { - return TemplateValuePattern.Replace(template, (match) => - { - var key = match.Groups[1].Value; - if (dict.ContainsKey(key)) - { - return dict[key]; - } - return match.Value; - }); - } - - public static string JsonFormat(string json) - { - var options = new JsonSerializerOptions - { - WriteIndented = true, - AllowTrailingCommas = true, - ReadCommentHandling = JsonCommentHandling.Skip - }; - - return JsonSerializer.Serialize(JsonSerializer.Deserialize(json, options), options); - } -} diff --git a/tools/V2rayConfigGen/V2rayConfigGen/Program.cs b/tools/V2rayConfigGen/V2rayConfigGen/Program.cs deleted file mode 100755 index bebdc7a..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/Program.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Reflection; - -namespace Crupest.V2ray; - -public static class Program -{ - public const string ConfigTemplateFile = "config.json.template"; - public const string VmessConfigFile = "vmess.txt"; - public const string ProxyGeoSitesFile = "proxy.txt"; - - public static void Main(string[] args) - { - var exeLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - var config = V2rayConfig.FromFiles( - Path.Combine(exeLocation, ConfigTemplateFile), - Path.Combine(exeLocation, VmessConfigFile), - Path.Combine(exeLocation, ProxyGeoSitesFile) - ); - - Console.Write(config.ToJson()); - } -} diff --git a/tools/V2rayConfigGen/V2rayConfigGen/V2rayConfig.cs b/tools/V2rayConfigGen/V2rayConfigGen/V2rayConfig.cs deleted file mode 100755 index 0d8b0bb..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/V2rayConfig.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text.Json; - -namespace Crupest.V2ray; - -public class V2rayConfig -{ - private const string VmessAnchor = "VMESS_PROXY_ANCHOR"; - private const string RoutingAnchor = "ROUTING_ANCHOR"; - - public V2rayConfig(string template, V2rayVmessProxy vmess, V2rayRouting router) { - Template = template; - Vmess = vmess; - Routing = router; - } - - public string Template { get; set; } - public V2rayVmessProxy Vmess { get; set; } - public V2rayRouting Routing { get; set; } - - public string ToJson(bool pretty = true) - { - var jsonOptions = new JsonSerializerOptions(new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, - }); - - var templateValues = new Dictionary - { - [VmessAnchor] = JsonSerializer.Serialize(Vmess.ToOutboundJsonObject(), jsonOptions), - [RoutingAnchor] = JsonSerializer.Serialize(Routing.ToJsonObject(), jsonOptions) - }; - - return FileUtility.JsonFormat(FileUtility.TextFromTemplate(Template, templateValues)); - } - - public static V2rayConfig FromFiles(string templatePath, string vmessPath, string routingPath) - { - var template = File.ReadAllText(templatePath); - var vmessDict = FileUtility.ReadDictionaryFile(vmessPath); - var proxyRoutingList = FileUtility.ReadListFile(routingPath); - - var vmess = V2rayVmessProxy.FromDictionary(vmessDict); - var routing = V2rayRouting.FromStringList(proxyRoutingList); - - return new V2rayConfig(template, vmess, routing); - } -} diff --git a/tools/V2rayConfigGen/V2rayConfigGen/V2rayConfigGen.csproj b/tools/V2rayConfigGen/V2rayConfigGen/V2rayConfigGen.csproj deleted file mode 100755 index 38f0937..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/V2rayConfigGen.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - Exe - net7.0 - enable - enable - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - diff --git a/tools/V2rayConfigGen/V2rayConfigGen/V2rayRouting.cs b/tools/V2rayConfigGen/V2rayConfigGen/V2rayRouting.cs deleted file mode 100755 index fe59491..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/V2rayRouting.cs +++ /dev/null @@ -1,52 +0,0 @@ -namespace Crupest.V2ray; - -public record V2rayRouting(List Rules, string DomainStrategy = "IpOnDemand") -{ - public record DomainRuleJsonObject(List Domains, string OutboundTag, string Type = "field"); - - public record IpRuleJsonObject(List Ip, string OutboundTag, string Type = "field"); - - public record RoutingJsonObject(string DomainStrategy, List Rules); - - public V2rayRouting() : this(new List()) - { - - } - - public RoutingJsonObject ToJsonObject() - { - var ruleJsonObjects = new List(); - - foreach (var(outBoundTag, proxyRules) in V2rayRoutingRule.GroupByOutboundTag(Rules)) - { - foreach (var (matchByKind, rules) in V2rayRoutingRule.GroupByMatchByKind(proxyRules)) - { - ruleJsonObjects.Add( - matchByKind switch - { - V2rayRoutingRuleMatcher.MatchByKind.Ip => new IpRuleJsonObject(rules.Select(r => r.Matcher.ToString()).ToList(), outBoundTag), - V2rayRoutingRuleMatcher.MatchByKind.Domain => new DomainRuleJsonObject(rules.Select(r => r.Matcher.ToString()).ToList(), outBoundTag), - _ => throw new Exception("Unknown match by kind."), - } - ); - } - } - - return new RoutingJsonObject(DomainStrategy ,ruleJsonObjects); - } - - public static V2rayRouting FromStringList(List list, string outboundTag = "proxy") - { - var router = new V2rayRouting(); - - foreach (var line in list) - { - var matcher = V2rayRoutingRuleMatcher.Parse(line); - if (matcher != null) - router.Rules.Add(new V2rayRoutingRule(matcher, outboundTag)); - } - - return router; - } -} - diff --git a/tools/V2rayConfigGen/V2rayConfigGen/V2rayRoutingRule.cs b/tools/V2rayConfigGen/V2rayConfigGen/V2rayRoutingRule.cs deleted file mode 100755 index 23c08e7..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/V2rayRoutingRule.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Linq; - -namespace Crupest.V2ray; - -public record V2rayRoutingRule(V2rayRoutingRuleMatcher Matcher, string OutboundTag) -{ - public static Dictionary> GroupByOutboundTag(List rules) - { - var result = new Dictionary>(); - foreach (var group in rules.GroupBy(r => r.OutboundTag)) - { - result[group.Key] = group.ToList(); - } - return result; - } - - public static Dictionary> GroupByMatchByKind(List rules) - { - var result = new Dictionary>(); - foreach (var group in rules.GroupBy(r => r.Matcher.MatchBy)) - { - result[group.Key] = group.ToList(); - } - return result; - } -} - diff --git a/tools/V2rayConfigGen/V2rayConfigGen/V2rayRoutingRuleMatcher.cs b/tools/V2rayConfigGen/V2rayConfigGen/V2rayRoutingRuleMatcher.cs deleted file mode 100755 index be27231..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/V2rayRoutingRuleMatcher.cs +++ /dev/null @@ -1,72 +0,0 @@ -namespace Crupest.V2ray; - -public record V2rayRoutingRuleMatcher(V2rayRoutingRuleMatcher.MatchKind Kind, string Value) -{ - public enum MatchByKind - { - Domain, - Ip - } - - public enum MatchKind - { - GeoIp, - GeoSite, - DomainPlain, - DomainSuffix, - DomainRegex, - DomainFull, - } - - public MatchByKind MatchBy - { - get - { - return Kind switch - { - MatchKind.GeoIp => MatchByKind.Ip, - _ => MatchByKind.Domain - }; - } - } - - public static V2rayRoutingRuleMatcher? Parse(string line) - { - if (line.IndexOf('#') != -1) - { - line = line[..line.IndexOf('#')]; - } - - line = line.Trim(); - - if (line.Length == 0) { return null; } - - var kind = MatchKind.DomainSuffix; - - foreach (var name in Enum.GetNames()) { - if (line.StartsWith(name)) { - kind = Enum.Parse(name); - line = line[name.Length..]; - line = line.Trim(); - break; - } - } - - return new V2rayRoutingRuleMatcher(kind, line); - } - - - public override string ToString() - { - return Kind switch - { - MatchKind.GeoSite => $"geosite:{Value}", - MatchKind.GeoIp => $"geoip:{Value}", - MatchKind.DomainPlain => Value, - MatchKind.DomainSuffix => $"domain:{Value}", - MatchKind.DomainFull => $"full:{Value}", - MatchKind.DomainRegex => $"regexp:{Value}", - _ => throw new Exception("Unknown matcher kind."), - }; - } -} diff --git a/tools/V2rayConfigGen/V2rayConfigGen/V2rayVmessProxy.cs b/tools/V2rayConfigGen/V2rayConfigGen/V2rayVmessProxy.cs deleted file mode 100755 index 25d466e..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/V2rayVmessProxy.cs +++ /dev/null @@ -1,52 +0,0 @@ -namespace Crupest.V2ray; - -public class V2rayVmessProxy -{ - public record VmessOutboundJsonObject(string Protocol, SettingsJsonObject Settings, string Tag, StreamSettingsJsonObject StreamSettings) - { - public static VmessOutboundJsonObject ByWs(string address, int port, string uuid, string tag, string path) - { - return new VmessOutboundJsonObject("vmess", new SettingsJsonObject( - new List{ new VnextJsonObject(address, port, new List { new VnextUserJsonObject(uuid) }) } - ), tag, StreamSettingsJsonObject.Ws(path)); - } - } - - public record SettingsJsonObject(List Vnext); - - public record VnextJsonObject(string Address, int Port, List Users); - - public record VnextUserJsonObject(string Id, int AlterId = 0, string Security = "auto", int Level = 0); - - public record StreamSettingsJsonObject(string Network, string Security, WsSettingsJsonObject WsSettings) { - public static StreamSettingsJsonObject Ws(string path) - { - return new StreamSettingsJsonObject("ws", "tls", new WsSettingsJsonObject(path, new())); - } - } - - public record WsSettingsJsonObject(string Path, Dictionary Headers); - - public string Host { get; set; } - public int Port { get; set; } - public string Path { get; set; } - public string UserId { get; set; } - - - public V2rayVmessProxy(string host, int port, string userId, string path) { - Host = host; - Port = port; - UserId = userId; - Path = path; - } - - public VmessOutboundJsonObject ToOutboundJsonObject(string tag = "proxy") - { - return VmessOutboundJsonObject.ByWs(Host, Port, UserId, tag, Path); - } - - public static V2rayVmessProxy FromDictionary(Dictionary dict) - { - return new V2rayVmessProxy(dict["host"], int.Parse(dict["port"]), dict["userid"], dict["path"]); - } -} diff --git a/tools/V2rayConfigGen/V2rayConfigGen/config.json.template b/tools/V2rayConfigGen/V2rayConfigGen/config.json.template deleted file mode 100755 index 9ba8af6..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/config.json.template +++ /dev/null @@ -1,63 +0,0 @@ -{ - "log": { - "loglevel": "warning" - }, - "inbounds": [ - { - "port": 2081, - "listen": "127.0.0.1", - "tag": "socks-inbound", - "protocol": "socks", - "settings": { - "auth": "noauth" - } - }, - { - "port": 2080, - "listen": "127.0.0.1", - "tag": "http-inbound", - "protocol": "http", - "settings": { - "auth": "noauth" - } - } - ], - "outbounds": [ - { - "protocol": "freedom", - "settings": {}, - "tag": "direct" - }, - { - "protocol": "blackhole", - "settings": {}, - "tag": "blocked" - }, - ${VMESS_PROXY_ANCHOR} - ], - "routing": ${ROUTING_ANCHOR}, - "dns": { - "hosts": {}, - "servers": [ - "https://doh.pub/dns-query", - "1.1.1.1", - "8.8.8.8", - "localhost" - ] - }, - "policy": { - "levels": { - "0": { - "uplinkOnly": 0, - "downlinkOnly": 0 - } - }, - "system": { - "statsInboundUplink": false, - "statsInboundDownlink": false, - "statsOutboundUplink": false, - "statsOutboundDownlink": false - } - }, - "other": {} -} diff --git a/tools/V2rayConfigGen/V2rayConfigGen/proxy.txt b/tools/V2rayConfigGen/V2rayConfigGen/proxy.txt deleted file mode 100755 index 4e9d3e8..0000000 --- a/tools/V2rayConfigGen/V2rayConfigGen/proxy.txt +++ /dev/null @@ -1,16 +0,0 @@ -GeoSite github -GeoSite google -GeoSite youtube -GeoSite twitter -GeoSite facebook -GeoSite discord -GeoSite reddit -GeoSite wikimedia -GeoSite stackexchange -GeoSite libgen -GeoSite python -GeoSite ruby -GeoSite creativecommons -GeoSite sci-hub -GeoSite v2ray -GeoSite imgur -- cgit v1.2.3