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
+223
View File
@@ -0,0 +1,223 @@
# -*- coding: utf-8 -*-
"""1) 布局核算补上「功能」分页(现在 7 页)
2) 新增功能注册表的测试
"""
from __future__ import annotations
import sys
from pathlib import Path
ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote")
LAYOUT = ROOT / "_tests" / "check_layout.py"
LAYOUT_OLD = ''' "系统": ["锁屏", "睡眠", "关机", "重启", "取消定时关机", "定时关机", "设备诊断"],
}'''
LAYOUT_NEW = ''' "系统": ["锁屏", "睡眠", "关机", "重启", "取消定时关机", "定时关机", "设备诊断"],
"功能": ["显示", "音量", "系统", "查看", "效率", "文件"],
}'''
TEST = '''# -*- coding: utf-8 -*-
"""验证电脑功能注册表。
功能是"电脑端声明、手表端调用"的结构,所以这里重点验证:
* 声明出来的功能都能被调用(名字和实现对得上)
* 读取类功能返回合理内容
* **安全边界**:文件操作不能越出用户自己的目录
* 边界是可配置的(这是给老师的实际需求留的口子)
"""
from __future__ import annotations
import shutil
import sys
import tempfile
import tkinter as tk
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "windows"))
PASSED = 0
FAILED = 0
def check(name, ok, detail=""):
global PASSED, FAILED
if ok:
PASSED += 1
print(f" [PASS] {name}")
else:
FAILED += 1
print(f" [FAIL] {name} {detail}")
def main() -> int:
from lanremote.actions import Actions
from lanremote.config import Store
from lanremote.features import Features
tmp = Path(tempfile.mkdtemp())
store = Store(tmp)
class FakeUI:
root = tk.Tk()
root.withdraw()
def ui_call(self, fn, timeout=5.0):
return fn()
def screen_size(self):
return (1920, 1080)
def notify(self, *a, **k):
pass
def log(self, *a, **k):
pass
def show_message(self, *a, **k):
pass
actions = Actions(FakeUI(), store)
features = Features(actions)
print("一、声明与实现是否对得上")
defs = features.defs()
check("功能数量够多", len(defs) >= 30, f"{len(defs)} 个")
print(f" 共 {len(defs)} 个功能")
groups = {}
for item in defs:
groups.setdefault(item.get("group", "?"), 0)
groups[item["group"]] += 1
for name, count in sorted(groups.items()):
print(f" {name}: {count} 个")
missing = []
for item in defs:
if not hasattr(features, f"_do_{item['name']}"):
missing.append(item["name"])
check("每个声明的功能都有实现", not missing, str(missing))
bad_kind = [i["name"] for i in defs
if i.get("kind") not in ("toggle", "action", "value", "input")]
check("kind 取值合法", not bad_kind, str(bad_kind))
need_input = [i for i in defs if i.get("kind") == "input"]
check("需要输入的功能都标了参数名",
all(i.get("key") for i in need_input),
str([i["name"] for i in need_input if not i.get("key")]))
print()
print("二、读取类功能")
reply_map = {
"uptime": {}, "perf": {}, "disk": {}, "battery": {},
"network_speed": {}, "recent_files": {}, "temperature": {},
}
for name in reply_map:
try:
text = features.run(name, {})
ok = isinstance(text, str) and len(text) > 0
except Exception as exc: # noqa: BLE001
text, ok = str(exc), False
print(f" {name}: {str(text)[:60]}")
check(f"{name} 能返回内容", ok)
print()
print("三、笔记 / 待办 / 收藏夹")
features.run("note_add", {"text": "第一节课要讲第三章"})
text = features.run("note_list", {})
check("笔记能记能读", "第三章" in text, text[:80])
features.run("todo_add", {"text": "批改作业"})
text = features.run("todo_list", {})
check("待办能加能读", "批改作业" in text, text[:80])
features.run("clip_fav_add", {})
features.run("clip_fav_list", {})
print()
print("四、安全边界(重点)")
escapes = [
r"C:\\Windows\\System32",
r"C:\\Windows\\System32\\drivers\\etc\\hosts",
r"..\\..\\Windows",
"/etc/passwd",
"C:\\\\",
]
for bad in escapes:
try:
resolved = features.resolve_in_roots(bad)
check(f"拒绝越权路径 {bad}", False, f"竟然解析成 {resolved}")
except ValueError:
check(f"拒绝越权路径 {bad}", True)
try:
features.resolve_in_roots("Downloads")
check("允许自己的目录(Downloads)", True)
except ValueError as exc:
check("允许自己的目录(Downloads)", False, str(exc))
# 删除功能只能删允许范围内的
try:
features.run("delete_file", {"path": r"C:\\Windows\\notepad.exe"})
check("删除功能也不能越界", False, "竟然允许了")
except ValueError:
check("删除功能也不能越界", True)
print()
print("五、边界可配置")
extra = tmp / "课件"
extra.mkdir(parents=True, exist_ok=True)
store.set("file_roots", str(extra))
roots = features.allowed_roots()
check("额外目录能被加进白名单",
any(str(extra) == str(r) for r in roots), str(roots[-3:]))
try:
resolved = features.resolve_in_roots(str(extra / "第一课.pptx"))
check("新加的目录内可以访问", str(extra) in str(resolved))
except ValueError as exc:
check("新加的目录内可以访问", False, str(exc))
store.set("extra_apps", "投影仪=C:\\\\Program Files\\\\App\\\\proj.exe")
apps = features.extra_apps()
check("自定义程序能配置", "投影仪" in apps, str(apps))
store.set("extra_commands", "重启投影=cmd /c restart-proj")
cmds = features.extra_commands()
check("自定义命令能配置", "重启投影" in cmds, str(cmds))
print()
print("六、不存在/非法功能名")
for bad in ("not_a_feature", "", "delete_everything"):
try:
features.run(bad, {})
check(f"拒绝未登记的功能 {bad!r}", False, "竟然执行了")
except ValueError:
check(f"拒绝未登记的功能 {bad!r}", True)
shutil.rmtree(tmp, ignore_errors=True)
print()
print("=" * 62)
print(f"通过 {PASSED} 项,失败 {FAILED} 项")
return 1 if FAILED else 0
if __name__ == "__main__":
sys.exit(main())
'''
def main() -> int:
text = LAYOUT.read_text(encoding="utf-8")
if LAYOUT_OLD not in text:
print(" [失败] check_layout 锚点未匹配")
return 1
text = text.replace(LAYOUT_OLD, LAYOUT_NEW, 1)
LAYOUT.write_text(text, encoding="utf-8")
print(" check_layout.py: 已加「功能」分页")
target = ROOT / "_tests" / "test_features.py"
target.write_text(TEST, encoding="utf-8")
print(f" 已写 {target.name}")
return 0
if __name__ == "__main__":
sys.exit(main())