把入站固定到某条订阅线路

订阅线路不在内核的全局名字表里,入站的 proxy 指不到它(决策记录 0005)。做法是自动建
一个只装它的策略组再指过去,用户看到的只是「这个口固定走这条线」,组是实现细节:
不出现在策略组列表里,列表和详情里都显示成线路本身的名字,没人再引用时自动删掉。

筛选条件必须做对两件事,都写了测试:转义正则元字符(线路名形如 [vmess]DMIT.LAX.Pro
里的方括号和点不转义会匹配错),以及前后加锚点(内核是部分匹配,不加锚点时「香港01」
会把「香港011」也捞进来)。线路名含反引号时表达不了——那是内核切分多个筛选条件的
分隔符——这种情况明说做不到而不是生成一个会静默匹配错的组。

实测:生成的配置 mihomo -t 通过;起一个临时内核问 /proxies,这个组解析出来的成员
恰好只有那一条线路,且确实进了名字表所以入站指得到。
This commit is contained in:
im0o
2026-08-10 19:33:44 +08:00
parent 08ab73a4f1
commit cb8effe05b
6 changed files with 333 additions and 6 deletions
+11 -3
View File
@@ -9,6 +9,7 @@
import { computed } from 'vue'
import type { Inbound, OutboundMode } from '@shared/inbounds.ts'
import { lastSwitchableGroup, resolveChain } from '@shared/outbound-chain.ts'
import { generatedGroupName } from '@shared/filter-groups.ts'
import { latestDelay } from '../api'
import { kernel, providerLines, runtime } from '../runtime'
import OutboundCard from '../components/OutboundCard.vue'
@@ -34,6 +35,8 @@ const emit = defineEmits<{
remove: []
select: [group: string, member: string]
test: [name: string]
/** 把这一路入站固定到某条订阅线路 */
pin: [line: string]
}>()
/**
@@ -67,7 +70,11 @@ const BUILTINS: Array<{ mode: OutboundMode; label: string; sub: string }> = [
{ mode: { kind: 'global' }, label: 'GLOBAL', sub: '跟随 GLOBAL 组' },
]
const LINE_LOCKED = '订阅线路无法被入站直接引用,需要通过筛选组间接引入。该功能尚未实现。'
/** 这一路入站是不是已经固定在某条订阅线路上。 */
function isPinnedTo(line: string): boolean {
const mode = props.inbound.outbound
return mode.kind === 'named' && mode.name === generatedGroupName(line)
}
</script>
<template>
@@ -192,10 +199,11 @@ const LINE_LOCKED = '订阅线路无法被入站直接引用,需要通过筛
:name="line"
:sub="describe(line)"
:delay="delayOf(line)"
:selected="false"
:disabled-reason="LINE_LOCKED"
:selected="isPinnedTo(line)"
:pending="pendingOutbound === generatedGroupName(line)"
:testing="isTesting(line)"
testable
@pick="emit('pin', line)"
@test="emit('test', line)"
/>
</div>