feat: TCP server/client mode config, protocol display in settings

This commit is contained in:
2026-07-27 19:09:53 +08:00
parent f715cb85e6
commit 759d35bc93
3 changed files with 32 additions and 7 deletions
+1
View File
@@ -17,6 +17,7 @@ DEFAULT_CONFIG: dict[str, Any] = {
"theme": "dark",
"sidebar_collapsed": False,
"telemetry_port": 20777,
"tcp_port": 20778,
"use_unified_port": True,
"game_ports": {},
"ui_test_mode": False,
+25 -6
View File
@@ -107,13 +107,32 @@ class TelemetryListener:
self._current_protocol = "udp"
if self._current_protocol == "tcp":
self._tcp = TCPListener(self._handle_packet)
ok = await self._tcp.start(host, port)
if ok:
import json as _json
mode = "server"
tcp_path = "/"
if selected_game:
gp = game_plugin_manager.get(selected_game)
if gp and gp.manifest_path:
try:
with open(f"{gp.manifest_path}/manifest.json", "r") as f:
m = _json.load(f)
mode = m.get("mode", "server")
tcp_path = m.get("path", "/")
except Exception:
pass
if mode == "server":
self._tcp = TCPListener(self._handle_packet)
ok = await self._tcp.start(host, port)
if ok:
self._running = True
self.forwarder.reload_targets()
logger.info("TCP server started on %s:%d [game=%s]", host, port, selected_game or "none")
return ok
else:
logger.info("TCP client mode - awaiting manual connection to upstream")
self._running = True
self.forwarder.reload_targets()
logger.info("TCP listener started on %s:%d [game=%s]", host, port, selected_game or "none")
return ok
return True
else:
loop = asyncio.get_event_loop()
try:
+6 -1
View File
@@ -221,7 +221,12 @@ const PageSettings = {
_gamePortListHtml(games, cfg) {
const gamePorts = cfg.game_ports || {};
return games.map(g => '<div class="game-port-row" style="display:flex;gap:8px;align-items:center;margin-bottom:6px"><span class="gp-id" style="width:140px;font-size:13px;color:var(--text-secondary)">' + g.name + '</span><input class="gp-port" type="number" value="' + (gamePorts[g.id] || g.default_port || 20777) + '" min="1024" max="65535" style="width:100px"><span style="font-size:11px;color:var(--text-tertiary)">默认: ' + (g.default_port || 20777) + '</span></div>').join('');
return games.map(g => {
const proto = g.protocol || 'udp';
const mode = g.mode || (proto === 'tcp' ? 'server' : '');
const protoLabel = proto.toUpperCase() + (mode ? '/' + mode : '');
return '<div class="game-port-row" style="display:flex;gap:8px;align-items:center;margin-bottom:6px"><span class="gp-id" style="width:120px;font-size:13px;color:var(--text-secondary)">' + g.name + '</span><span style="width:70px;font-size:11px;color:var(--text-tertiary)">' + protoLabel + '</span><input class="gp-port" type="number" value="' + (gamePorts[g.id] || g.default_port || (proto==='tcp'?cfg.tcp_port||20778:20777)) + '" min="1024" max="65535" style="width:100px"><span style="font-size:11px;color:var(--text-tertiary)">默认: ' + (g.default_port || (proto==='tcp'?cfg.tcp_port||20778:20777)) + '</span></div>';
}).join('');
},
_forwardListHtml(forwards) {