技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

MajsoulMax:用中间人代理“解锁”雀魂——一次优雅的协议层旁路实验

项目背景与痛点

雀魂(Mahjong Soul)的资源分发模型很典型:角色立绘、皮肤、桌布、牌背、特效等美术资产在客户端安装包里是全量的,服务端只负责告诉客户端“你拥有哪些”。这意味着“未解锁”本质上是一个布尔标记,而不是资源缺失。

于是问题就变成了:能否在不改动客户端二进制、不触碰服务端的前提下,让客户端相信“我全都有”?MajsoulMax 给出的答案是——在客户端与服务器之间插一层 mitmproxy,拦下 WebSocket 下行包,把那些表示归属关系的字段改写掉。它不注入 DLL、不打补丁、不改 AssetBundle,只在协议层做文章。这种做法对网页版、桌面客户端、Steam 端一视同仁,因为它站在了所有实现共同的收敛点:网络协议。

核心技术揭秘

整个系统是一条“解密 → 解析 → 路由 → 改写 → 回注”的流水线:

graph TD A[雀魂客户端-网页/Steam] -->|"HTTPS / WSS"| B[mitmproxy 监听 8080] B --> C[证书注入与 TLS 解密] C --> D[WebSocket 帧级拦截] D --> E[协议路由-按 method 名分发] E --> F[动态 Protobuf 编解码] F --> G[解锁规则引擎-配置驱动] G --> H[响应字段改写] H -->|"伪造后的下行包"| A E -->|"未命中消息"| I[原样直通转发] I --> A

第一层:TLS 与 WebSocket。 雀魂全链路走 WSS,mitmproxy 以根证书做中间人,客户端只要信任了 mitmproxy-ca-cert 就不会报错。真正的抓手是 mitmproxy 的 websocket_message 钩子——它在帧级别暴露上下行数据,比传统 HTTP 代理粒度更细,也让“只改响应、不动请求”成为可能。

第二层:动态 Protobuf。 这是全项目技术含量最高的部分。雀魂的协议(社区常称 liqi 协议)用 Protobuf 序列化,但客户端并不携带 .proto 文件,字段编号与类型只能从逆向出的协议描述(如 liqi.json)中获得。因此实现上必须运行时构建 FileDescriptorProto 并注册进 DescriptorPool,再用动态 Message 完成 decode/encode——否则改一个字段就得重新编译代码,维护成本不可接受。

第三层:消息路由。 帧载荷并非裸 Protobuf,而是带包裹头的自定义结构(消息类型 + 请求序号 + payload)。程序需要先剥壳、依据 method 名判断这是哪一类响应(账号数据、角色列表、背包、装扮…),再决定是否进入改写分支。这里的设计取向应该是白名单式的:只处理明确理解的响应类型,其余一律直通,避免因误改写导致客户端解析崩溃。

第四层:规则引擎。 解锁逻辑被外置成配置,而不是硬编码在拦截器里。这一层决定了项目的可维护性——协议迭代时,往往只需更新字段映射,而不必改动代理核心。

功能亮点与差异

对比同类方案,MajsoulMax 的差异点集中在三处:

其一,零侵入。市面上不少“解锁工具”走的是修改本地资源或注入运行时的路子,风险高、跨端适配差。MajsoulMax 只在网络层动手,客户端完整性不受影响,网页版和 Steam 端用的是同一套逻辑。

其二,跨端统一。网页版是浏览器 WSS,客户端是 Unity 网络栈,两者在应用层协议上是一致的——这正是“选对抽象层”带来的红利。

其三,协议驱动的可扩展性。基于动态 Protobuf 的解析方式意味着新增一类可改写响应,成本接近于“加一条规则”,而不是“加一个分支代码块”。

需要泼一盆冷水的是:这类改写的效果是本地视觉级的。服务端并没有真的把角色判给你,其他玩家视角里你依然是原样。它更像“本地预览器”,而不是“账号修改器”。

应用场景与落地建议

适合的场景很明确:美术资产预览、离线/单机环境下的体验、以及作为 mitmproxy + Protobuf 动态解析的教学样本。

落地时请注意几点:

  • 环境隔离:务必使用独立测试账号,代理与证书装在可控的设备或虚拟机上,不要污染主力环境。
  • 证书信任是前提:桌面端需把 CA 装进系统信任区;浏览器端建议用独立 Profile,避免全局代理残留。
  • 性能:mitmproxy 是 Python 实现,高频小包场景下有可观开销,长时间对局可能出现延迟抖动,必要时用 --set connection_strategy=lazy 之类的参数缓解。
  • 协议脆弱性:客户端每次大版本更新都可能调整字段与消息名,升级后第一时间核对日志里的解码失败率,比盲目重试更有价值。
  • 合规边界:这类工具天然踩在服务条款的灰区,切勿用于排位、交易或多账号运营,后果自负。

综合评价

优点:架构选型精准——把问题抽象到“协议字段”这一层,绕开了客户端加固、资源加密、跨平台适配等一堆麻烦;动态 Protobuf 的工程实现有真正的技术门槛;配置化设计让它具备可持续维护的骨架。

缺点:强依赖逆向所得的协议描述,属于“跟着官方版本跑”的项目,长期维护成本不可低估;改写范围受限于本地渲染,实际价值天花板明确;作为 mitmproxy 插件,吞吐与稳定性都受制于 Python 宿主,不适合高并发或低延迟要求苛刻的场景。

一句话总结:它不是外挂,而是一把精准的手术刀,切在了“客户端信任服务端数据”这个最柔软的地方。 从工程审美看,这是一次干净利落的旁路设计;从实用主义看,它的价值在于理解协议,而非获得特权。

关于

简要分析

热度分
967
价值分
526
活跃状态
活跃

语言占比

Python

Release