feat: 添加 GeoBypass 规则集配置与运行时日志监控

在游戏代理启动时,增加对 bypass_cn 模式下 GeoIP 和 Geosite 规则集的配置摘要日志输出。
在 singbox 服务中新增启动前配置检测与运行时日志监控,实时捕获规则集下载状态和错误信息,便于调试网络问题。
This commit is contained in:
ZenEcho committed 2026-03-01 17:22:54 +08:00
1 parent b48e639490
commit 67504e81d0
3 files changed
+70

No files matched your search

+52
View File
@@ -106,6 +106,7 @@ export class SingBoxService {
this.safeSend('singbox-error', e.message)
throw e
}
await this.logGeoBypassConfigSummary(configPath)
this.log('正在启动 sing-box...')
this.lastLogs = []
@@ -122,12 +123,14 @@ export class SingBoxService {
const text = data.toString().trim()
pushLog(text)
this.log(stripAnsi(text))
this.inspectGeoBypassRuntimeLine(text)
})
this.process.stderr?.on('data', (data) => {
const text = data.toString().trim()
pushLog(text)
this.log(stripAnsi(text), 'error')
this.inspectGeoBypassRuntimeLine(text)
})
const started = await new Promise<void>((resolve, reject) => {
@@ -229,6 +232,55 @@ export class SingBoxService {
this.safeSend('singbox-log', { message, type, timestamp: Date.now() })
}
private async logGeoBypassConfigSummary(configPath: string): Promise<void> {
try {
const raw = await fs.readFile(configPath, 'utf8')
const parsed = JSON.parse(raw) as any
const routeRuleSet = Array.isArray(parsed?.route?.rule_set) ? parsed.route.rule_set : []
const geoip = routeRuleSet.find((item: any) => String(item?.tag || '') === 'geoip-cn')
const geosite = routeRuleSet.find((item: any) => String(item?.tag || '') === 'geosite-cn')
const enabled = !!(geoip || geosite)
this.log(
`[GeoBypass] 启动前配置检测: enabled=${enabled}, geoipUrl=${String(geoip?.url || '(none)')}, geositeUrl=${String(geosite?.url || '(none)')}`
)
} catch (e: any) {
this.log(`[GeoBypass] 启动前配置检测失败: ${String(e?.message || e)}`, 'error')
}
}
private inspectGeoBypassRuntimeLine(rawLine: string): void {
const line = stripAnsi(String(rawLine || '').trim())
if (!line) return
const lower = line.toLowerCase()
const related = lower.includes('geoip-cn')
|| lower.includes('geosite-cn')
|| lower.includes('cn.srs')
|| lower.includes('rule-set')
if (!related) return
const failed = lower.includes('fail')
|| lower.includes('error')
|| lower.includes('timeout')
|| lower.includes('refused')
|| lower.includes('not found')
|| lower.includes('forbidden')
if (failed) {
this.log(`[GeoBypass] 规则下载失败迹象: ${line}`, 'error')
return
}
const downloaded = lower.includes('download')
|| lower.includes('update')
|| lower.includes('fetch')
|| lower.includes('loaded')
if (downloaded) {
this.log(`[GeoBypass] 规则下载日志: ${line}`)
return
}
this.log(`[GeoBypass] 规则相关日志: ${line}`)
}
private sendStatus(status: 'running' | 'stopped') {
this.safeSend('singbox-status', status)
}
+12
View File
@@ -419,6 +419,18 @@ export const useGameStore = defineStore('games', () => {
port: systemProxyPortToUse
}
}))
try {
const parsed = JSON.parse(config) as any
const routeRuleSet = Array.isArray(parsed?.route?.rule_set) ? parsed.route.rule_set : []
const geoip = routeRuleSet.find((item: any) => String(item?.tag || '') === 'geoip-cn')
const geosite = routeRuleSet.find((item: any) => String(item?.tag || '') === 'geosite-cn')
const enabled = !!(geoip || geosite)
console.info(
`[GeoBypass] 启动配置摘要 game=${rawGame.name || rawGame.id}: enabled=${enabled}, geoipUrl=${String(geoip?.url || '(none)')}, geositeUrl=${String(geosite?.url || '(none)')}`
)
} catch (e) {
console.warn('[GeoBypass] 启动前解析 config 摘要失败:', e)
}
await singboxApi.restart(config)
if (useSystemProxy) {
+6
View File
@@ -330,6 +330,9 @@ export function generateSingboxConfig(game: Game, node: NodeConfig, dnsOptions?:
if (hasBypassCn) {
// -- 绕过大陆模式 (Bypass CN) --
console.info(
`[GeoBypass] bypass_cn 已命中: proxyMode=${game.proxyMode}, processScope=${hasRoutingProcessScope ? 'on' : 'off'}, processes=${processes.join(',') || '(none)'}`
)
// 私有 IP 直连
const privateRule: Record<string, any> = {
@@ -349,6 +352,7 @@ export function generateSingboxConfig(game: Game, node: NodeConfig, dnsOptions?:
url: LOYALSOLDIER_GEOIP_CN_SRS_URL,
download_detour: 'proxy' // 规则集下载走代理
})
console.info(`[GeoBypass] 已注入规则集: tag=${GEOIP_CN_RULE_SET_TAG}, url=${LOYALSOLDIER_GEOIP_CN_SRS_URL}, download_detour=proxy`)
// 下载并配置 CN 域名规则集
ensureRemoteRuleSet(config, {
@@ -358,6 +362,7 @@ export function generateSingboxConfig(game: Game, node: NodeConfig, dnsOptions?:
url: SAGERNET_GEOSITE_CN_SRS_URL,
download_detour: 'proxy'
})
console.info(`[GeoBypass] 已注入规则集: tag=${GEOSITE_CN_RULE_SET_TAG}, url=${SAGERNET_GEOSITE_CN_SRS_URL}, download_detour=proxy`)
// CN IP 直连规则
const geoipRule: Record<string, any> = {
@@ -378,6 +383,7 @@ export function generateSingboxConfig(game: Game, node: NodeConfig, dnsOptions?:
geositeRule.process_name = processes
}
config.route.rules.push(geositeRule)
console.info('[GeoBypass] 已注入直连规则: geoip-cn + geosite-cn -> direct')
// 如果有进程限制,则剩下的流量中,只有该进程走代理
// (全局 final 默认为 direct)