aboutsummaryrefslogtreecommitdiff
path: root/tools/Crupest.V2ray/Crupest.V2ray/SurgeConfigGenerator.cs
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2024-09-17 23:59:44 +0800
committercrupest <crupest@outlook.com>2024-10-03 01:22:38 +0800
commitfb9cbc7d9c1dffc45360536c3ec543a275accf89 (patch)
treecee500837fb1fbc2e10d03af04d087a099fc11b8 /tools/Crupest.V2ray/Crupest.V2ray/SurgeConfigGenerator.cs
parentb610b87deaae8ed029793049c6f75dcc87353424 (diff)
downloadcrupest-fb9cbc7d9c1dffc45360536c3ec543a275accf89.tar.gz
crupest-fb9cbc7d9c1dffc45360536c3ec543a275accf89.tar.bz2
crupest-fb9cbc7d9c1dffc45360536c3ec543a275accf89.zip
feat(secret): add surge rule set generation.
TODO: 1. Remove ruby tools. 2. Rename v2ray.
Diffstat (limited to 'tools/Crupest.V2ray/Crupest.V2ray/SurgeConfigGenerator.cs')
-rw-r--r--tools/Crupest.V2ray/Crupest.V2ray/SurgeConfigGenerator.cs60
1 files changed, 60 insertions, 0 deletions
diff --git a/tools/Crupest.V2ray/Crupest.V2ray/SurgeConfigGenerator.cs b/tools/Crupest.V2ray/Crupest.V2ray/SurgeConfigGenerator.cs
new file mode 100644
index 0000000..bd52234
--- /dev/null
+++ b/tools/Crupest.V2ray/Crupest.V2ray/SurgeConfigGenerator.cs
@@ -0,0 +1,60 @@
+namespace Crupest.V2ray;
+
+public class SurgeConfigGenerator(ProxyFile proxyFile, GeoSiteData geoSiteData)
+{
+ public ProxyFile ProxyFile { get; } = proxyFile;
+ public GeoSiteData GeoSiteData { get; } = geoSiteData;
+
+ private static string ToSurgeRuleString(V2rayHostMatcherKind kind, string value)
+ {
+ var ruleType = kind switch
+ {
+ V2rayHostMatcherKind.DomainFull => "DOMAIN",
+ V2rayHostMatcherKind.DomainSuffix => "DOMAIN-SUFFIX",
+ V2rayHostMatcherKind.DomainKeyword => "DOMAIN-KEYWORD",
+ V2rayHostMatcherKind.DomainRegex => "URL-REGEX",
+ _ => throw new Exception("Unacceptable matcher kind for Surge rule.")
+ };
+
+ return $"{ruleType},{value}";
+ }
+
+ private static List<V2rayHostMatcherKind> DomainMatcherKinds { get; } = [
+ V2rayHostMatcherKind.DomainFull, V2rayHostMatcherKind.DomainKeyword,
+ V2rayHostMatcherKind.DomainRegex, V2rayHostMatcherKind.DomainSuffix,
+ ];
+
+ public string GenerateChinaRuleSet()
+ {
+ var geoSites = ProxyFile.MatcherConfig.Items.Where(i => i.Kind == V2rayHostMatcherKind.GeoSite).Select(i => i.Matcher).ToList();
+ var cnRules = GeoSiteData.GetEntriesRecursive(geoSites, DomainMatcherKinds, ["cn"]).ToList();
+ return string.Join('\n', cnRules.Select(r => ToSurgeRuleString(r.Kind, r.Value)));
+ }
+
+ public string GenerateGlobalRuleSet()
+ {
+ var geoSites = ProxyFile.MatcherConfig.Items.Where(i => i.Kind == V2rayHostMatcherKind.GeoSite).Select(i => i.Matcher).ToList();
+ var nonCnRules = GeoSiteData.GetEntriesRecursive(geoSites, DomainMatcherKinds).Where(e => !e.Attributes.Contains("cn")).ToList();
+ var domainRules = ProxyFile.MatcherConfig.Items.Where(i => DomainMatcherKinds.Contains(i.Kind)).ToList();
+ return string.Join('\n', [
+ ..nonCnRules.Select(r => ToSurgeRuleString(r.Kind, r.Value)),
+ ..domainRules.Select(r => ToSurgeRuleString(r.Kind, r.Matcher))
+ ]);
+ }
+
+ public static SurgeConfigGenerator Create(string proxyFilePath, bool clean, bool silent)
+ {
+ var proxyFile = new ProxyFile(proxyFilePath);
+ var geoSiteData = GeoDataManager.Instance.GetOrCreateGeoSiteData(clean, silent);
+ return new SurgeConfigGenerator(proxyFile, geoSiteData);
+ }
+
+ public static void GenerateTo(string proxyFilePath, string cnPath, string globalPath, bool clean, bool silent)
+ {
+ var generator = Create(proxyFilePath, clean, silent);
+ File.WriteAllText(cnPath, generator.GenerateChinaRuleSet());
+ if (!silent) Console.WriteLine($"China rule set written to {cnPath}.");
+ File.WriteAllText(globalPath, generator.GenerateGlobalRuleSet());
+ if (!silent) Console.WriteLine($"Global rule set written to {globalPath}.");
+ }
+}