Skip to content

Commit

Permalink
fix: Output correct port-hopping config for Surge
Browse files Browse the repository at this point in the history
  • Loading branch information
geekdada committed Sep 17, 2024
1 parent 8b4c25f commit ecc6901
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/guide/custom-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ module.exports = {
- 类型: `string`
- 默认值: `undefined`

开启 Tuic 和 Hysteria 协议端口跳跃,目前仅 Surge, Stash 和 Mihomo 支持这一特性。例如 `5000,6000-7000`
开启 Tuic 和 Hysteria 协议端口跳跃,目前仅 Surge, Stash 和 Mihomo 支持这一特性。例如 `5000,6000-7000`该配置支持逗号或分号分割的端口列表,以及连字符分割的端口范围,Surgio 会自动转换成 Surge 和 Stash 支持的格式。

### nodeConfig.portHoppingInterval

Expand Down
32 changes: 32 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,43 +141,75 @@ export interface TrojanProviderConfig extends ProviderConfig {
readonly tls13?: boolean
}

export type HttpNodeConfigInput = z.infer<typeof HttpNodeConfigValidator>

export type HttpNodeConfig = z.infer<typeof HttpNodeConfigValidator> &
SurgioInternals

export type HttpsNodeConfigInput = z.infer<typeof HttpsNodeConfigValidator>

export type HttpsNodeConfig = z.infer<typeof HttpsNodeConfigValidator> &
SurgioInternals

export type TrojanNodeConfigInput = z.infer<typeof TrojanNodeConfigValidator>

export type TrojanNodeConfig = z.infer<typeof TrojanNodeConfigValidator> &
SurgioInternals

export type ShadowsocksNodeConfigInput = z.infer<
typeof ShadowsocksNodeConfigValidator
>

export type ShadowsocksNodeConfig = z.infer<
typeof ShadowsocksNodeConfigValidator
> &
SurgioInternals

export type ShadowsocksrNodeConfigInput = z.infer<
typeof ShadowsocksrNodeConfigValidator
>

export type ShadowsocksrNodeConfig = z.infer<
typeof ShadowsocksrNodeConfigValidator
> &
SurgioInternals

export type Socks5NodeConfigInput = z.infer<typeof Socks5NodeConfigValidator>

export type Socks5NodeConfig = z.infer<typeof Socks5NodeConfigValidator> &
SurgioInternals

export type SnellNodeConfigInput = z.infer<typeof SnellNodeConfigValidator>

export type SnellNodeConfig = z.infer<typeof SnellNodeConfigValidator> &
SurgioInternals

export type VmessNodeConfigInput = z.infer<typeof VmessNodeConfigValidator>

export type VmessNodeConfig = z.infer<typeof VmessNodeConfigValidator> &
SurgioInternals

export type VlessNodeConfigInput = z.infer<typeof VlessNodeConfigValidator>

export type VlessNodeConfig = z.infer<typeof VlessNodeConfigValidator> &
SurgioInternals

export type TuicNodeConfigInput = z.input<typeof TuicNodeConfigValidator>

export type TuicNodeConfig = z.infer<typeof TuicNodeConfigValidator> &
SurgioInternals

export type WireguardNodeConfigInput = z.input<
typeof WireguardNodeConfigValidator
>

export type WireguardNodeConfig = z.infer<typeof WireguardNodeConfigValidator> &
SurgioInternals

export type Hysteria2NodeConfigInput = z.input<
typeof Hysteria2NodeConfigValidator
>

export type Hysteria2NodeConfig = z.infer<typeof Hysteria2NodeConfigValidator> &
SurgioInternals

Expand Down
4 changes: 2 additions & 2 deletions src/utils/__tests__/clash.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ test('getClashNodes', async (t) => {
token: 'password',
skipCertVerify: true,
alpn: ['h3'],
portHopping: '5000-6000',
portHopping: '5000-6000;7000',
portHoppingInterval: 10,
},
]),
Expand All @@ -853,7 +853,7 @@ test('getClashNodes', async (t) => {
udp: true,
alpn: ['h3'],
'hop-interval': 10,
ports: '5000-6000',
ports: '5000-6000,7000',
},
],
)
Expand Down
4 changes: 2 additions & 2 deletions src/utils/__tests__/surge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ test('getSurgeNodes - Tuic', (t) => {
port: 443,
token: 'token',
serverCertFingerprintSha256: 'sha256',
portHopping: '5000-6000',
portHopping: '5000-6000;7000',
portHoppingInterval: 10,
},
{
Expand Down Expand Up @@ -550,7 +550,7 @@ test('getSurgeNodes - Tuic', (t) => {
},
]),
[
'测试 Tuic = tuic, example.com, 443, token=token, server-cert-fingerprint-sha256=sha256, port-hopping=5000-6000, port-hopping-interval=10',
'测试 Tuic = tuic, example.com, 443, token=token, server-cert-fingerprint-sha256=sha256, port-hopping=5000-6000;7000, port-hopping-interval=10',
'测试 Tuic = tuic, example.com, 443, token=token, alpn=h3',
'测试 Tuic = tuic, example.com, 443, token=token, skip-cert-verify=true, sni=sni.example.com, alpn=h3',
'测试 Tuic = tuic-v5, example.com, 443, password=password, uuid=uuid, ecn=true, skip-cert-verify=true, sni=sni.example.com, alpn=h3',
Expand Down
6 changes: 3 additions & 3 deletions src/utils/clash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ function nodeListMapper(nodeConfig: PossibleNodeConfigType) {
),
...(clashConfig.clashCore === 'stash' && nodeConfig.portHopping
? {
ports: nodeConfig.portHopping,
ports: nodeConfig.portHopping.replaceAll(';', ','),
}
: null),
...(clashConfig.clashCore === 'stash' &&
Expand Down Expand Up @@ -439,7 +439,7 @@ function nodeListMapper(nodeConfig: PossibleNodeConfigType) {
),
...(clashConfig.clashCore === 'stash' && nodeConfig.portHopping
? {
ports: nodeConfig.portHopping,
ports: nodeConfig.portHopping.replaceAll(';', ','),
}
: null),
...(clashConfig.clashCore === 'stash' && nodeConfig.portHoppingInterval
Expand Down Expand Up @@ -479,7 +479,7 @@ function nodeListMapper(nodeConfig: PossibleNodeConfigType) {
clashConfig.clashCore === 'clash.meta') &&
nodeConfig.portHopping
? {
ports: nodeConfig.portHopping,
ports: nodeConfig.portHopping.replaceAll(';', ','),
}
: null),
...((clashConfig.clashCore === 'stash' ||
Expand Down
10 changes: 9 additions & 1 deletion src/validators/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,15 @@ export const SimpleNodeConfigValidator = z.object({
.optional(),

// Misc
portHopping: z.string().optional(),
portHopping: z
.string()
.transform((val) => {
if (val.includes(',')) {
return val.replaceAll(',', ';')
}
return val
})
.optional(),
portHoppingInterval: z.number().optional(),
underlyingProxy: z.string().optional(),
testUrl: z.string().optional(),
Expand Down

0 comments on commit ecc6901

Please sign in to comment.