feat: 添加 GeoBypass 规则集配置与运行时日志监控
在游戏代理启动时,增加对 bypass_cn 模式下 GeoIP 和 Geosite 规则集的配置摘要日志输出。 在 singbox 服务中新增启动前配置检测与运行时日志监控,实时捕获规则集下载状态和错误信息,便于调试网络问题。
This commit is contained in:
1 parent
b48e639490
commit
67504e81d0
3 files changed
+70
No files matched your search
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user