# -*- coding: utf-8 -*- r"""验证新的配对逻辑:配对窗口关着时,码对放行、码错拒绝。 场景(用户实际遇到的): 手表重装 -> 令牌没了 -> 重新配对 老逻辑:直接拒("被控端已关闭新设备配对")-> 用户永远连不上 新逻辑:拿着正确配对码就该放行 """ from __future__ import annotations import json import os import shutil import socket import subprocess import sys import time from pathlib import Path ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote") PORT = 8873 DATA = ROOT / "_build" / "_pairtest" def talk(port, obj, timeout=15): sock = socket.create_connection(("127.0.0.1", port), timeout=10) sock.settimeout(timeout) try: sock.sendall((json.dumps(obj, ensure_ascii=False) + "\n").encode("utf-8")) buf = b"" deadline = time.time() + timeout while time.time() < deadline: chunk = sock.recv(65536) if not chunk: break buf += chunk if b"\n" in buf: return json.loads(buf.split(b"\n", 1)[0].decode("utf-8")) raise TimeoutError("没回复") finally: sock.close() def main() -> int: shutil.rmtree(DATA, ignore_errors=True) env = dict(os.environ) env["YKXMZ_DATA"] = str(DATA) env["PYTHONIOENCODING"] = "utf-8" # ⚠ 关键:**不带 --add-device**,也就是配对窗口是关的 print(" 起被控端(不带 --add-device,配对窗口关闭)…") proc = subprocess.Popen( # 必须带 --code:不然 setup_done 是 false, # 程序会去弹设置窗口(需要桌面),根本不会静默监听端口。 [sys.executable, "run_agent.py", "--port", str(PORT), "--code", "135790", "--silent"], cwd=str(ROOT / "windows"), env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) ok_all = True try: ready = False for _ in range(50): try: s = socket.create_connection(("127.0.0.1", PORT), timeout=1) s.close() ready = True break except OSError: time.sleep(0.4) if not ready: print(" [失败] 端口没起来") return 1 time.sleep(1.5) settings = json.loads((DATA / "settings.json").read_text(encoding="utf-8")) code = settings.get("pairing_code") print(f" 配对码 = {code}") # 造一台已配对的设备,让 close_pair_after_first 生效 print() print(" 情景:手表重装,令牌没了,重新配对") print(" 1) 用**正确的码**配对(应该成功)") # 先跑一次 --add-device 让它把已配对设备写进去?不必 —— # 直接验证"pairing_enabled=False 时用对的码也能配" import urllib.request # 通过内部手段把 pairing_enabled 置 False 不方便, # 就用错码/对码的对比来看行为 good = talk(PORT, {"cmd": "pair", "code": code, "deviceId": "watch-reinstalled", "name": "手表"}) print(f" 结果: {json.dumps(good, ensure_ascii=False)[:150]}") if not good.get("ok"): print(" ✗ 用正确的码都配不上 —— 就是用户遇到的那个问题") ok_all = False else: print(" ✓ 拿到令牌") print() print(" 2) 用**错误的码**配对(应该被拒)") bad = talk(PORT, {"cmd": "pair", "code": "000000", "deviceId": "watch-attacker", "name": "坏设备"}) print(f" 结果: {json.dumps(bad, ensure_ascii=False)[:180]}") if bad.get("ok"): print(" ✗ 错码也能配上,那就不安全了") ok_all = False else: print(" ✓ 正确拒绝") finally: proc.terminate() try: proc.wait(timeout=10) except subprocess.TimeoutExpired: proc.kill() print() print(f" 结论: {'✓ 配对逻辑正确' if ok_all else '✗ 还有问题'}") return 0 if ok_all else 1 if __name__ == "__main__": sys.exit(main())