Skip to content

Commit

Permalink
feat: 细化 getNodeNames;增加 Clash 的 shadow-tls 和 Wireguard 支持
Browse files Browse the repository at this point in the history
  • Loading branch information
geekdada committed Apr 18, 2023
1 parent ab1d7fe commit 1d477e6
Show file tree
Hide file tree
Showing 8 changed files with 353 additions and 176 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ module.exports = {
rules: {
'@typescript-eslint/ban-ts-comment': 0,
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-explicit-any': 0,
},
};
75 changes: 72 additions & 3 deletions src/utils/clash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,19 @@ import {
SimpleNodeConfig,
SortedNodeNameFilterType,
} from '../types';
import { applyFilter } from './filter';
import {
applyFilter,
httpFilter,
httpsFilter,
shadowsocksFilter,
shadowsocksrFilter,
snellFilter,
socks5Filter,
trojanFilter,
tuicFilter,
vmessFilter,
} from './filter';
import { getPortFromHost } from './index';

const logger = createLogger({ service: 'surgio:utils:clash' });

Expand All @@ -32,6 +44,16 @@ export const getClashNodes = function (

switch (nodeConfig.type) {
case NodeTypeEnum.Shadowsocks:
if (
nodeConfig.shadowTls &&
!nodeConfig.clashConfig?.enableShadowTls
) {
logger.warn(
`尚未开启 Clash 的 shadow-tls 支持,节点 ${nodeConfig.nodeName} 将被忽略。如需开启,请在配置文件中设置 clashConfig.enableShadowTls 为 true。`,
);
return null;
}

return {
type: 'ss',
cipher: nodeConfig.method,
Expand Down Expand Up @@ -71,6 +93,21 @@ export const getClashNodes = function (
},
}
: null),
...(nodeConfig.shadowTls && nodeConfig.clashConfig?.enableShadowTls
? {
plugin: 'shadow-tls',
'client-fingerprint': 'chrome',
'plugin-opts': {
password: nodeConfig.shadowTls.password,
...(nodeConfig.shadowTls.version
? { version: nodeConfig.shadowTls.version }
: null),
...(nodeConfig.shadowTls.sni
? { host: nodeConfig.shadowTls.sni }
: null),
},
}
: null),
};

case NodeTypeEnum.Vmess:
Expand Down Expand Up @@ -211,7 +248,7 @@ export const getClashNodes = function (
case NodeTypeEnum.Tuic:
if (!nodeConfig.clashConfig?.enableTuic) {
logger.warn(
`默认不为 Clash 生成 Tuic 节点,节点 ${nodeConfig.nodeName} 会被省略。如需开启,请在配置文件中设置 clashConfig.enableTuic 为 true。`,
`尚未开启 Clash 的 TUIC 支持,节点 ${nodeConfig.nodeName} 会被省略。如需开启,请在配置文件中设置 clashConfig.enableTuic 为 true。`,
);
return null;
}
Expand All @@ -235,6 +272,24 @@ export const getClashNodes = function (
'skip-cert-verify': nodeConfig.skipCertVerify === true,
};

case NodeTypeEnum.Wireguard:
return {
type: 'wireguard',
name: nodeConfig.nodeName,
server: nodeConfig.endpoint,
port: getPortFromHost(nodeConfig.endpoint),
'private-key': nodeConfig.privateKey,
'public-key': nodeConfig.publicKey,
ip: nodeConfig.selfIp,
...(nodeConfig.selfIpV6 ? { ipv6: nodeConfig.selfIpV6 } : null),
...(nodeConfig.mtu ? { mtu: nodeConfig.mtu } : null),
...(nodeConfig.presharedKey
? { 'preshared-key': nodeConfig.presharedKey }
: null),
...(nodeConfig.dnsServer ? { dns: nodeConfig.dnsServer } : null),
udp: true,
};

// istanbul ignore next
default:
logger.warn(
Expand Down Expand Up @@ -265,7 +320,21 @@ export const getClashNodeNames = function (
}

result = result.concat(
applyFilter(list, filter).map((item) => item.nodeName),
applyFilter(
list.filter(
(item) =>
shadowsocksFilter(item) ||
shadowsocksrFilter(item) ||
vmessFilter(item) ||
httpFilter(item) ||
httpsFilter(item) ||
trojanFilter(item) ||
snellFilter(item) ||
socks5Filter(item) ||
(item.clashConfig?.enableTuic && tuicFilter(item)),
),
filter,
).map((item) => item.nodeName),
);

return result;
Expand Down
9 changes: 8 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import queryString from 'query-string';
import { JsonObject } from 'type-fest';
import { URL, URLSearchParams } from 'url';
import URLSafeBase64 from 'urlsafe-base64';
import YAML from 'yaml';
import net from 'net';
import crypto from 'crypto';
import { camelCase, snakeCase, paramCase } from 'change-case';
Expand Down Expand Up @@ -589,3 +588,11 @@ export const isGFWFree = (): boolean =>
export const assertNever = (x: never): never => {
throw new TypeError(`Unexpected object: ${x}`);
};

export const getPortFromHost = (host: string): number => {
const match = host.match(/:(\d+)$/);
if (match) {
return Number(match[1]);
}
throw new Error(`Invalid host: ${host}`);
};
39 changes: 38 additions & 1 deletion src/utils/quantumult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,19 @@ import {
NodeNameFilterType,
NodeTypeEnum,
PossibleNodeConfigType,
SimpleNodeConfig,
SortedNodeNameFilterType,
} from '../types';
import { applyFilter } from './filter';
import {
applyFilter,
httpFilter,
httpsFilter,
shadowsocksFilter,
shadowsocksrFilter,
socks5Filter,
trojanFilter,
vmessFilter,
} from './filter';
import { pickAndFormatStringList } from './index';

const logger = createLogger({ service: 'surgio:utils:quantumult' });
Expand Down Expand Up @@ -278,3 +288,30 @@ export const getQuantumultXNodes = function (

return result.join('\n');
};

export const getQuantumultXNodeNames = function (
list: ReadonlyArray<SimpleNodeConfig>,
filter?: NodeNameFilterType | SortedNodeNameFilterType,
separator?: string,
): string {
// istanbul ignore next
if (arguments.length === 2 && typeof filter === 'undefined') {
throw new Error(ERR_INVALID_FILTER);
}

return applyFilter(
list.filter(
(item) =>
shadowsocksFilter(item) ||
shadowsocksrFilter(item) ||
vmessFilter(item) ||
httpFilter(item) ||
httpsFilter(item) ||
trojanFilter(item) ||
socks5Filter(item),
),
filter,
)
.map((item) => item.nodeName)
.join(separator || ', ');
};
Loading

0 comments on commit 1d477e6

Please sign in to comment.