RPC 与反作弊校验
服务器通过 PyRpc 包下发 on_rpc 事件,框架(source/init.py)负责响应。 这条链必须完整,否则会被判定为「违规游戏行为」并踢下线。
三种 RPC
| 服务器请求 | 框架响应 | 说明 |
|---|---|---|
S2CHeartBeat | ClientLoadAddonsFinishedFromGac | 心跳 |
GetStartType | SetStartType | 用 utility 解密 / 加密 |
GetMCPCheckNum | SetMCPCheckNum | 反作弊校验值计算 |
MCP 校验链
GetMCPCheckNum 的处理是整条链里最脆弱的部分,Py2 → Py3 迁移时全是坑:
text
_mcp_rotor_decrypt ← rotor.decrypt + zlib + _mcp_reverse_data
↓
_get_calc_check_num ← RC4 解密 + md5
↓
SetMCPCheckNum ← 回给服务器三个必须同时成立的条件
umsgpack.compatibility = True—— 否则长度 > 31 字节的字符串会被打成str8而不是raw16,字节流与服务器期望的不一致,校验必然失败。- RC4 /
_mcp_reverse_data/_get_calc_check_num必须是 Py3 版本 (bytes / int 操作)—— 迁移时这三处都重写过。 on_rpc事件必须以 bytes 传递 —— C++ 侧必须走triggerBytes, 用普通trigger会被当 UTF-8 文本解码,msgpack 数据当场损坏。
失败的表现
服务器判定「违规游戏行为,您的账号被禁止进入游戏」并踢下线, 记录在 dis.log。
这不是协议错误、也不是登录失败 —— 登录是成功的(PlayStatus 0), 是校验值算错了。
排查清单
怀疑校验链有问题时,按顺序查:
on_rpc事件真的触发了吗?(triggerBytesvstrigger,见 事件系统)umsgpack.compatibility是否在打包前设成了True?python312/Lib/site-packages/umsgpack.py是不是 Py3 版本?rotor/ RC4 的处理路径有没有被改动?(这几处对字节序和整数行为很敏感)- 是否改动了
PythonRuntime.cpp的初始化顺序?必须是SetPythonHome()→Py_Initialize()→initModules()。
上线前必须实测一次
当前解释器是动态链接的:python312.dll 与 python312/ 随包提供, PythonRuntime.cpp 的 SetPythonHome() 把 PYTHONHOME 指向 <exe目录>\python312。 初始化路径与早期形态不同,所以上线前必须实测一次真实连服,确认 PlayStatus value: 3(PlayerSpawn 正常进服)且未被踢。 2026-09-26 已实测通过,见 Python 运行时与扩展。
