ソースを参照

Feat: internal Clash YAML merge

SukkaW 1 年間 前
コミット
c0f979ae05

+ 48 - 11
Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts

@@ -7,6 +7,7 @@ import { compareAndWriteFile, createRuleset } from './lib/create-file';
 import { task } from './trace';
 import { SHARED_DESCRIPTION } from './lib/constants';
 import { createMemoizedPromise } from './lib/memo-promise';
+import * as yaml from 'yaml';
 
 export const getDomesticAndDirectDomainsRulesetPromise = createMemoizedPromise(async () => {
   const domestics = await readFileIntoProcessedArray(path.resolve(import.meta.dir, '../Source/non_ip/domestic.conf'));
@@ -29,6 +30,8 @@ export const getDomesticAndDirectDomainsRulesetPromise = createMemoizedPromise(a
 export const buildDomesticRuleset = task(import.meta.main, import.meta.path)(async (span) => {
   const res = await getDomesticAndDirectDomainsRulesetPromise();
 
+  const dataset = [...Object.entries(DOMESTICS), ...Object.entries(DIRECTS), ...Object.entries(LANS)];
+
   return Promise.all([
     createRuleset(
       span,
@@ -79,20 +82,54 @@ export const buildDomesticRuleset = task(import.meta.main, import.meta.path)(asy
         `#!desc=Last Updated: ${new Date().toISOString()}`,
         '',
         '[Host]',
-        ...([...Object.entries(DOMESTICS), ...Object.entries(DIRECTS), ...Object.entries(LANS)])
-          .flatMap(([, { domains, dns, ...rest }]) => [
-            ...(
-              'hosts' in rest
-                ? Object.entries(rest.hosts).flatMap(([dns, ips]: [dns: string, ips: string[]]) => `${dns} = ${ips.join(', ')}`)
-                : []
-            ),
-            ...domains.flatMap((domain) => [
-              `${domain} = server:${dns}`,
-              `*.${domain} = server:${dns}`
-            ])
+        ...dataset.flatMap(([, { domains, dns, ...rest }]) => [
+          ...(
+            'hosts' in rest
+              ? Object.entries(rest.hosts).flatMap(([dns, ips]: [dns: string, ips: string[]]) => `${dns} = ${ips.join(', ')}`)
+              : []
+          ),
+          ...domains.flatMap((domain) => [
+            `${domain} = server:${dns}`,
+            `*.${domain} = server:${dns}`
           ])
+        ])
       ],
       path.resolve(import.meta.dir, '../Modules/sukka_local_dns_mapping.sgmodule')
+    ),
+    Bun.write(
+      path.resolve(import.meta.dir, '../Internal/clash_nameserver_policy.yaml'),
+      yaml.stringify(
+        {
+          dns: {
+            'nameserver-policy': dataset.reduce<Record<string, string | string[]>>(
+              (acc, [, { domains, dns }]) => {
+                domains.forEach((domain) => {
+                  acc[`+.${domain}`] = dns === 'system'
+                    ? [
+                      'system://',
+                      'system',
+                      'dhcp://system'
+                    ]
+                    : dns;
+                });
+
+                return acc;
+              },
+              {}
+            )
+          },
+          hosts: dataset.reduce<Record<string, string>>(
+            (acc, [, { domains, dns, ...rest }]) => {
+              if ('hosts' in rest) {
+                Object.assign(acc, rest.hosts);
+              }
+              return acc;
+            },
+            {}
+          )
+        },
+        { version: '1.1' }
+      )
     )
   ]);
 });

+ 31 - 14
Build/build-sgmodule-always-realip.ts

@@ -2,10 +2,9 @@ import path from 'path';
 import { task } from './trace';
 import { compareAndWriteFile } from './lib/create-file';
 import { DIRECTS, LANS } from '../Source/non_ip/direct';
+import * as yaml from 'yaml';
 
 const HOSTNAMES = [
-  // Intranet, Router Setup, and mant more
-  ...([Object.entries(DIRECTS), Object.entries(LANS)]).flatMap(data => data.flatMap(([, { domains }]) => domains.flatMap((domain) => [`*.${domain}`, domain]))),
   // Network Detection, Captive Portal
   'msftncsi.com',
   'msftconnecttest.com',
@@ -41,18 +40,36 @@ const HOSTNAMES = [
   '*.battlenet.com.cn',
   '*.blzstatic.cn',
   '*.battlenet.com'
-] as const;
+];
 
 export const buildAlwaysRealIPModule = task(import.meta.main, import.meta.path)(async (span) => {
-  return compareAndWriteFile(
-    span,
-    [
-      '#!name=[Sukka] Always Real IP Plus',
-      `#!desc=Last Updated: ${new Date().toISOString()}`,
-      '',
-      '[General]',
-      `always-real-ip = %APPEND% ${HOSTNAMES.join(', ')}`
-    ],
-    path.resolve(import.meta.dir, '../Modules/sukka_common_always_realip.sgmodule')
-  );
+  // Intranet, Router Setup, and mant more
+  const dataset = ([Object.entries(DIRECTS), Object.entries(LANS)]);
+  const surge = dataset.flatMap(data => data.flatMap(([, { domains }]) => domains.flatMap((domain) => [`*.${domain}`, domain])));
+  const clash = dataset.flatMap(data => data.flatMap(([, { domains }]) => domains.map((domain) => `+.${domain}`)));
+
+  return Promise.all([
+    compareAndWriteFile(
+      span,
+      [
+        '#!name=[Sukka] Always Real IP Plus',
+        `#!desc=Last Updated: ${new Date().toISOString()}`,
+        '',
+        '[General]',
+        `always-real-ip = %APPEND% ${HOSTNAMES.concat(surge).join(', ')}`
+      ],
+      path.resolve(import.meta.dir, '../Modules/sukka_common_always_realip.sgmodule')
+    ),
+    Bun.write(
+      path.resolve(import.meta.dir, '../Internal/clash_fake_ip_filter.yaml'),
+      yaml.stringify(
+        {
+          dns: {
+            'fake-ip-filter': HOSTNAMES.concat(clash)
+          }
+        },
+        { version: '1.1' }
+      )
+    )
+  ]);
 });

+ 10 - 2
Source/non_ip/direct.ts

@@ -1,3 +1,11 @@
+export interface DNSMapping {
+  hosts?: {
+    [domain: string]: string[]
+  },
+  dns: string,
+  domains: string[]
+}
+
 export const DIRECTS = {
   ROUTER: {
     dns: 'system',
@@ -79,7 +87,7 @@ export const DIRECTS = {
       'local.adguard.org'
     ]
   }
-} as const;
+} satisfies Record<string, DNSMapping>;
 
 export const LANS = {
   LAN: {
@@ -111,4 +119,4 @@ export const LANS = {
       '254.169.in-addr.arpa'
     ]
   }
-};
+} satisfies Record<string, DNSMapping>;

+ 3 - 1
Source/non_ip/domestic.ts

@@ -1,3 +1,5 @@
+import type { DNSMapping } from './direct';
+
 export const DOMESTICS = {
   ALIBABA: {
     hosts: {
@@ -307,4 +309,4 @@ export const DOMESTICS = {
       'baomitu.com'
     ]
   }
-} as const;
+} satisfies Record<string, DNSMapping>;

BIN
bun.lockb


+ 2 - 1
package.json

@@ -30,7 +30,8 @@
     "table": "^6.8.2",
     "tar-stream": "^3.1.7",
     "tldts": "^6.1.26",
-    "tldts-experimental": "^6.1.26"
+    "tldts-experimental": "^6.1.26",
+    "yaml": "^2.4.5"
   },
   "devDependencies": {
     "@eslint-sukka/node": "6.0.0-beta.3",