ykxmz 1.5.0:手表端 TLS 证书兼容 + 三端分开打包 + 下载区

手表端
- 内置 GTS Root R4 / GlobalSign Root CA
  修 SSLHandshakeException: Chain validation failed
- 连接错误翻译成人话:证书 / 时间 / 解析 / 超时分别给提示
- 经中转连上后用服务器报的地址刷新已配对记录
- 版本号 1.3.0 -> 1.5.0(AndroidManifest 之前漏改了)

服务器端
- 支持 chunked 请求体,修每 16 秒一次的连接错乱与大面积 502
- 网络调优 net-tune.sh(开机自动应用)
- 新增下载区,管理页加下载卡片
- 隧道改 HTTP/2 + 双连接

打包方式变更
- 从一个合并 zip 改成三个独立产物:
    ykxmz-agent-*.zip    被控端
    ykxmz-server-*.zip   服务器端
    ykxmz-watch-*.apk    控制端
This commit is contained in:
xmz7891
2026-10-06 23:08:05 +08:00
parent edac13dbe2
commit 8111fb6d97
20 changed files with 3770 additions and 2943 deletions
+172
View File
@@ -0,0 +1,172 @@
# -*- coding: utf-8 -*-
r"""把 test_package_remote.py 改成适配"三端分开出"。
原来:
ZIP = dist/ykxmz-1.5.0.zip (一个合并包)
解压后是 1-agent/ 2-server/ 3-watch/ + 顶层 README
现在:
dist/ykxmz-agent-1.5.0.zip 被控端
dist/ykxmz-server-1.5.0.zip 服务器端
dist/ykxmz-watch-1.5.0.apk 控制端(直接给)
测试要验证的东西不变(三部分内容完整、能跑起来、文档带 BOM),
只是"从哪拿"变了。
"""
from __future__ import annotations
import ast
import re
import sys
from pathlib import Path
TEST = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\_tests"
r"\test_package_remote.py")
OLD_HEAD = '''ROOT = Path(__file__).resolve().parent.parent
ZIP = ROOT / "dist" / "ykxmz-1.5.0.zip"'''
NEW_HEAD = '''ROOT = Path(__file__).resolve().parent.parent
# 三端分开出(用户要求):
# 被控端 -> 一个 zip
# 服务器端 -> 一个 zip
# 控制端 -> 直接给 APK(不打 zip)
AGENT_ZIP = ROOT / "dist" / "ykxmz-agent-1.5.0.zip"
SERVER_ZIP = ROOT / "dist" / "ykxmz-server-1.5.0.zip"
WATCH_APK = ROOT / "dist" / "ykxmz-watch-1.5.0.apk"'''
OLD_OPEN = '''def main() -> int:
if not ZIP.is_file():
print(f" 找不到 {ZIP}")
return 1
work = Path(tempfile.mkdtemp(prefix="verify_pkg_"))
relay_proc = agent_proc = None
try:
# ---------------- 1. 解压 ----------------
print("一、解压")
with zipfile.ZipFile(ZIP) as archive:
archive.extractall(work)
top = work / ZIP.stem
check("顶层目录存在", top.is_dir(), top)
agent_dir = top / "1-agent"
relay_dir = top / "2-server"
watch_dir = top / "3-watch"
check("三个部分目录都在",
agent_dir.is_dir() and relay_dir.is_dir() and watch_dir.is_dir())
check("顶层说明在", (top / "README.txt").is_file())
exe = agent_dir / "ykxmz.exe"
relay_py = relay_dir / "relay.py"
install_sh = relay_dir / "install.sh"
apk = next(watch_dir.glob("*.apk"), None)
check("被控端 EXE 在", exe.is_file())
check("服务器端 relay.py 在", relay_py.is_file())
check("服务器端 install.sh 在", install_sh.is_file())
check("控制端 APK 在", apk is not None, apk)
# 说明文档要有 BOM(否则记事本会认成 GBK 乱码)
for label, path in (("顶层", top / "README.txt"),
("被控端", agent_dir / "README-agent.txt"),
("服务器端", relay_dir / "README-server.txt"),
("控制端", watch_dir / "README-watch.txt")):
raw = path.read_bytes() if path.is_file() else b""
check(f"{label}说明有 UTF-8 BOM",
raw[:3] == b"\\xef\\xbb\\xbf", raw[:3])'''
NEW_OPEN = '''def main() -> int:
# 1) 三个产物都要在
for label, path in (("被控端包", AGENT_ZIP), ("服务器端包", SERVER_ZIP),
("控制端 APK", WATCH_APK)):
if not path.is_file():
print(f" 找不到{label}: {path}")
return 1
work = Path(tempfile.mkdtemp(prefix="verify_pkg_"))
relay_proc = agent_proc = None
try:
# ---------------- 1. 解压两个 zip ----------------
print("一、解压(两个 zip)")
with zipfile.ZipFile(AGENT_ZIP) as archive:
archive.extractall(work)
with zipfile.ZipFile(SERVER_ZIP) as archive:
archive.extractall(work)
# 两个包各自带一层版本目录
agent_dir = work / AGENT_ZIP.stem
relay_dir = work / SERVER_ZIP.stem
check("被控端目录存在", agent_dir.is_dir(), agent_dir)
check("服务器端目录存在", relay_dir.is_dir(), relay_dir)
exe = agent_dir / "ykxmz.exe"
relay_py = relay_dir / "relay.py"
install_sh = relay_dir / "install.sh"
apk = WATCH_APK
check("被控端 EXE 在", exe.is_file())
check("服务器端 relay.py 在", relay_py.is_file())
check("服务器端 install.sh 在", install_sh.is_file())
check("服务器端带了网络调优脚本", (relay_dir / "net-tune.sh").is_file())
check("服务器端带了看门狗", (relay_dir / "watchdog.sh").is_file())
check("控制端 APK 在(直接在 dist 里)", apk.is_file(), apk)
# 说明文档要有 BOM(否则记事本会认成 GBK 乱码)
for label, path in (("被控端", agent_dir / "README-agent.txt"),
("服务器端", relay_dir / "README-server.txt"),
("控制端(旁边那份)",
ROOT / "dist" / "ykxmz-watch-1.5.0-说明.txt")):
raw = path.read_bytes() if path.is_file() else b""
check(f"{label}说明有 UTF-8 BOM",
raw[:3] == b"\\xef\\xbb\\xbf", raw[:3])
# 三份正式文档:两个包里都要有
for label, base in (("被控端包", agent_dir), ("服务器端包", relay_dir)):
for doc in ("LICENSE.txt", "BEFORE-INSTALL.txt",
"AFTER-INSTALL.txt"):
check(f"{label}带了 {doc}", (base / doc).is_file())'''
OLD_TOOLS = ''' # 被控端目录里不该有 data / 说明残留
check("没有把 data 目录打进去",
not (agent_dir / "data").exists())'''
NEW_TOOLS = ''' # 被控端目录里不该有 data / 说明残留
check("没有把 data 目录打进去",
not (agent_dir / "data").exists())'''
def main() -> int:
text = TEST.read_text(encoding="utf-8")
if "AGENT_ZIP" in text:
print(" 已经改过")
return 0
ok = True
for old, new, label in ((OLD_HEAD, NEW_HEAD, "产物路径常量"),
(OLD_OPEN, NEW_OPEN, "解压与检查段")):
if old not in text:
print(f" [失败] {label} —— 锚点没找到")
# 打印实际内容帮助定位
key = old.splitlines()[0]
for i, line in enumerate(text.splitlines(), 1):
if line.strip() == key.strip():
print(f" 实际 {i}: {line}")
ok = False
continue
text = text.replace(old, new, 1)
print(f" {label}")
if not ok:
return 1
TEST.write_text(text, encoding="utf-8", newline="\n")
try:
ast.parse(text)
print(" test_package_remote.py 语法 OK")
except SyntaxError as exc:
print(f" 语法错误: 行 {exc.lineno}: {exc.msg}")
return 1
return 0
if __name__ == "__main__":
sys.exit(main())