Files
ZenEcho a20e070059 feat: 重构游戏扫描模块并新增系统代理支持
- 重构游戏扫描模块,按平台拆分扫描逻辑(Steam、Microsoft Store、Epic/EA)
- 新增系统代理模式支持,可在系统代理和TUN模式间切换
- 新增语言切换功能,支持中英文界面切换
- 改进主题系统,将主题配置统一管理至store
- 新增系统托盘功能,支持窗口最小化到托盘
- 优化网络连接性能,为TCP ping添加noDelay选项
- 新增游戏分类匹配功能,扫描时自动匹配游戏分类
- 改进日志系统,自动捕获前端提示层日志
- 新增会话网络调优选项,支持MTU、UDP模式等高级配置
- 修复多处UI样式问题,统一颜色变量命名
- 更新项目文档,反映新的Electron架构设计
2026-02-20 16:50:03 +08:00

125 lines
3.5 KiB
TypeScript

import { exec } from 'node:child_process'
import net from 'node:net'
import os from 'node:os'
/**
* Ping 测试结果接口
*/
interface PingResult {
/** 延迟 (毫秒),-1 表示超时或不可达 */
latency: number
/** 丢包率 (0-100) */
loss: number
}
const isWindows = os.platform() === 'win32'
/**
* 执行 ICMP Ping 测试
*
* 使用系统 ping 命令测试目标主机的连通性和延迟。
*
* @param host - 目标主机 (域名或 IP)
* @param timeout - 超时时间 (毫秒),默认 2000ms
* @returns Promise<PingResult> - 测试结果
*/
export function ping(host: string, timeout = 2000): Promise<PingResult> {
return new Promise((resolve) => {
// Windows: -n 1 (count), -w timeout (ms)
// Linux/Mac: -c 1 (count), -W timeout (s)
// Safety check for host to prevent injection
if (/[^a-zA-Z0-9.-]/.test(host)) {
return resolve({ latency: -1, loss: 100 })
}
const cmd = isWindows
? `ping -n 1 -w ${timeout} ${host}`
: `ping -c 1 -W ${Math.ceil(timeout / 1000)} ${host}`
const start = Date.now()
exec(cmd, (error, stdout, stderr) => {
const duration = Date.now() - start
if (error) {
// Ping failed (timeout or other error)
resolve({ latency: -1, loss: 100 })
return
}
// Parse output
let latency = -1
if (isWindows) {
// Windows output formats:
// EN: Reply from 1.1.1.1: bytes=32 time=13ms TTL=56
// CN: 来自 1.1.1.1 的回复: 字节=32 时间=13ms TTL=56
const match = stdout.match(/[=<]([\d\.]+) ?ms/)
if (match && match[1]) {
latency = Math.round(parseFloat(match[1]))
}
} else {
// 64 bytes from 1.1.1.1: icmp_seq=1 ttl=56 time=14.5 ms
const match = stdout.match(/time[=<]([\d\.]+) ?ms/)
if (match && match[1]) {
latency = Math.round(parseFloat(match[1]))
}
}
resolve({
latency: latency > 0 ? latency : -1,
loss: latency > 0 ? 0 : 100
})
})
})
}
/**
* 执行 TCP Ping 测试
*
* 尝试建立 TCP 连接来测试端口连通性和延迟。
* 比 ICMP Ping 更能反映实际服务的可用性。
*
* @param host - 目标主机
* @param port - 目标端口
* @param timeout - 超时时间 (毫秒),默认 2000ms
* @returns Promise<PingResult> - 测试结果
*/
export function tcpPing(host: string, port: number, timeout = 2000): Promise<PingResult> {
return new Promise((resolve) => {
const start = Date.now()
const socket = new net.Socket()
socket.setNoDelay(true)
let resolved = false
const done = (latency: number, loss: number) => {
if (resolved) return
resolved = true
socket.destroy()
resolve({ latency, loss })
}
socket.setTimeout(timeout)
socket.on('connect', () => {
const duration = Date.now() - start
done(duration, 0)
})
socket.on('timeout', () => {
done(-1, 100)
})
socket.on('error', (err) => {
done(-1, 100)
})
try {
socket.connect(port, host)
} catch (e) {
done(-1, 100)
}
})
}