ykxmz 1.5.0:修复手表端 TLS 证书校验 + MTU 修复网络稳定性

被控端
- 修复 MTU 问题:夹 MSS + 路径 MTU 探测(公网可用率 48% -> 100%)
- 复用 HTTP 连接(免掉每次新建 TLS 的 30% 握手失败)
- 每分钟回头找局域网,自动切回快 400 倍的路径
- 画面心跳帧:静止时省流量,客户端仍知道流是活的
- 锁屏时给出可操作的提示

手表端
- 内置 GTS Root R4 / GlobalSign Root CA,修 SSLHandshakeException
- 连接错误翻译成人话(证书/时间/解析/超时分别提示)
- 经中转连上后用服务器报的地址刷新已配对记录
- 新增局域网连接页面、服务器延迟检测

服务器端
- 支持 chunked 请求体(修每 16 秒一次的连接错乱与大面积 502)
- 网络调优脚本 net-tune.sh(开机自动应用)
- 管理页:批量删除、网络体检、下载区
- 隧道改 HTTP/2 + 双连接

文档
- 许可协议 / 安装前必读 / 安装后须知(作者:小麦子)
This commit is contained in:
xmz7891
2026-10-06 19:01:05 +08:00
commit b62ac865ea
3195 changed files with 203292 additions and 0 deletions
+157
View File
@@ -0,0 +1,157 @@
# -*- coding: utf-8 -*-
"""验证回退(撤销)系统。
要点:
* 可回退的操作执行后会自动进回退列表
* 回退能把状态真的改回去
* **不可回退的操作(关机、删文件、杀进程)不该被记录** ——
记了会给用户"还能退回去"的错觉,反而危险
"""
import sys
import tempfile
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "windows"))
from lanremote.actions import Actions # noqa: E402
from lanremote.config import Store # noqa: E402
from lanremote.features import Features # noqa: E402
from lanremote.headless import HeadlessUI # noqa: E402
passed = 0
failed = 0
def check(name, ok, detail=""):
global passed, failed
if ok:
passed += 1
print(" [PASS] " + name)
else:
failed += 1
print(" [FAIL] " + name + " " + str(detail))
def main() -> int:
store = Store(Path(tempfile.mkdtemp()))
ui = HeadlessUI(store)
features = Features(Actions(ui, store))
ui.root
print("一、三个回退功能都在")
defs = features.defs()
names = {d["name"] for d in defs}
for required in ("undo_last", "undo_all", "undo_list"):
check("声明了 " + required, required in names)
check("功能总数 > 200", len(defs) > 200, len(defs))
print()
print("二、初始没有可回退的")
check("undo_list 说没有",
"没有" in features.run("undo_list", {}),
features.run("undo_list", {}))
check("undo_last 说没有",
"没有" in features.run("undo_last", {}),
features.run("undo_last", {}))
print()
print("三、做几个可回退的操作")
features.run("shuffle_play", {"on": True})
check("开关被记为可回退", len(features._undo_stack()) == 1,
len(features._undo_stack()))
features.run("loop_play", {"on": True})
features.run("big_text", {"text": "回退测试"})
check("三步都记上了", len(features._undo_stack()) == 3,
len(features._undo_stack()))
listing = features.run("undo_list", {})
check("undo_list 列了三步", "3 步" in listing, listing)
check("看得到操作描述",
"回退测试" in listing or "随机播放" in listing, listing)
print()
print("四、开关的状态确实是开着的,回退要能关掉")
check("shuffle_play 现在是开的", store.get("shuffle_play") is True,
store.get("shuffle_play"))
check("loop_play 现在是开的", store.get("loop_play") is True,
store.get("loop_play"))
# 最近一步是 big_text,先退它
result = features.run("undo_last", {})
check("回退上一步成功", "已回退" in result, result)
check("回退后列表少一条", len(features._undo_stack()) == 2,
len(features._undo_stack()))
# 再退两步,应该把两个开关关掉
features.run("undo_last", {})
features.run("undo_last", {})
check("shuffle_play 被关回去了", store.get("shuffle_play") is False,
store.get("shuffle_play"))
check("loop_play 被关回去了", store.get("loop_play") is False,
store.get("loop_play"))
check("列表清空了", len(features._undo_stack()) == 0,
len(features._undo_stack()))
print()
print("五、undo_all 批量回退")
features.run("shuffle_play", {"on": True})
features.run("loop_play", {"on": True})
features.run("big_text", {"text": "批量测试"})
check("攒了 3 步", len(features._undo_stack()) == 3,
len(features._undo_stack()))
result = features.run("undo_all", {})
check("undo_all 说回退了 3 步", "3 步" in result, result)
check("开关都回去了", store.get("shuffle_play") is False
and store.get("loop_play") is False,
f"{store.get('shuffle_play')}/{store.get('loop_play')}")
check("列表空了", len(features._undo_stack()) == 0,
len(features._undo_stack()))
print()
print("六、撤不回来的操作不该被记录")
# 这些都是破坏性的 / 不可逆的
for name in ("kill_games", "clean_temp", "lock_now", "net_reset"):
try:
features.run(name, {})
except Exception: # noqa: BLE001
pass
check("破坏性操作没有进回退列表",
len(features._undo_stack()) == 0, len(features._undo_stack()))
check("IRREVERSIBLE 里有 kill_games",
"kill_games" in Features.IRREVERSIBLE)
check("IRREVERSIBLE 里有 delete_file",
"delete_file" in Features.IRREVERSIBLE)
check("IRREVERSIBLE 里有 shutdown",
"shutdown" in Features.IRREVERSIBLE)
print()
print("七、回退不会来回横跳")
features.run("shuffle_play", {"on": True})
stack_before = len(features._undo_stack())
features.run("undo_last", {})
check("回退后不会又记一条新的",
len(features._undo_stack()) == stack_before - 1,
f"{stack_before} -> {len(features._undo_stack())}")
print()
print("八、全部 toggle 都能记录回退")
toggles = [d for d in defs if d.get("kind") == "toggle"]
# 别写死数量 —— 加功能时这里会假失败(relay_saver 就踩过一次)。
# 真正要保证的是:开关数量合理,且**每一个**都能回退。
check("开关数量合理(>= 15)", len(toggles) >= 15, len(toggles))
check("开关类都算可回退",
all(d["name"] not in Features.IRREVERSIBLE for d in toggles),
str([d["name"] for d in toggles
if d["name"] in Features.IRREVERSIBLE]))
ui.stop()
print()
print("=" * 60)
print(f"通过 {passed} 项,失败 {failed} 项")
return 0 if failed == 0 else 1
if __name__ == "__main__":
sys.exit(main())