工作原理
本页面向希望了解实现细节的读者。日常使用无需阅读。
多人联机
整体结构
一次游戏连接依次经过以下环节:
- 好友的游戏 从局域网世界列表进入房间,连接到本机的
127.0.0.1端口; - 好友的联机组件 将连接送入加密虚拟网络,以直连或中转的方式抵达房主;
- 房主的连接网关 识别加入者身份,决定放行或拒绝;
- 房主的局域网世界 接受连接,游戏开始。
此外,双方的联机组件都会连接联机节点,但节点仅用于互相发现;房主一侧的房间服务负责同步玩家列表。
邀请码与虚拟网络
每个房间对应一个独立的加密虚拟网络。邀请码的 16 个字符同时编码了该网络的名称与密钥:前半部分决定网络名称,后半部分决定密钥。因此,仅凭邀请码即可进入对应的网络,而不持有邀请码的人既无法发现、也无法加入该房间。邀请码带有校验,输入错误时会被立即识别。
网络由一个开源的联机组件承载。它在首次使用时按需下载,每个文件都与内置的 SHA-256 值逐一比对,任何镜像都无法替换成经过修改的程序。联机组件以独立进程运行,并被放入一个 Windows 作业对象中:Campfire 一旦退出,即使是意外崩溃,组件进程也会随之结束,不会在后台残留。
发现房主的世界
房主无需手动填写端口。Campfire 读取系统中正在监听的 TCP 端口表,筛选出属于 Java 进程的端口,并逐个在本机发送 Minecraft 状态查询,从而识别出局域网世界。这种方式不需要监听网络广播,因此不会触发 Windows 防火墙的询问;在本机运行的专用服务器也能以同样方式被发现。
让房间出现在局域网列表中
好友一侧,Campfire 在本机打开一个端口,经虚拟网络转发到房主的世界,并以 Minecraft 原生的“对局域网开放”广播格式在本机发布该世界。于是房间会直接出现在多人游戏页面底部的局域网世界列表中。
从列表进入不仅更加方便,也是离线账号能够加入的前提:房主以正版账号开放局域网时,游戏会校验每位加入者的身份,而只有从局域网列表选中的世界才会在校验失败时继续连接。
房间服务
房主一侧运行一个轻量的房间服务。加入者通过它确认已到达正确的房间、获取游戏端口,并同步玩家列表、名称与头像信息。所有消息都在虚拟网络内部传输。
连接网关
房主的世界并不直接暴露给虚拟网络。访客的连接首先到达房主本机的连接网关,网关解析 Minecraft 登录阶段的数据包,以识别加入者的身份。被拉黑的玩家会在登录时被拒绝,被移出的玩家会收到断开连接的数据包。
游戏内房间信息
正常的局域网连接在登录后即被加密,外部程序无法向其中插入内容。为了在聊天栏与 Tab 列表中显示房间信息,Campfire 会将一个小型 Java 组件附加到房主的游戏进程中,由游戏服务端自己发送欢迎消息与页眉页脚。该组件不关闭正版验证,也不读取任何登录凭据。附加失败时,Campfire 会自动退回仅在局域网列表中显示信息。
读取游戏账号
每款启动器都会通过命令行把玩家名称、UUID 与账号类型传给游戏。Campfire 从运行中游戏的命令行读取这三项信息,因此与所用的启动器无关,也不会接触任何登录凭据。
启动器修复
定位修改点
Campfire 使用 .NET 程序集读写库解析启动器,依据方法名称与代码特征定位需要修改的方法,而非依赖固定的文件偏移。这使得启动器的后续小版本在结构不变时通常仍可修复;一旦特征无法匹配,Campfire 会判定为“暂不支持”,不做任何修改。
| 修复项 | 修改的方法 | 修改方式 |
|---|---|---|
| Minecraft 版本列表 | PageDownloadInstall.LoaderInit | 让下载页重新绑定版本列表加载器 |
| 手动安装整合包 | ModModpack.ModpackInstall() | 恢复文件选择,并在后台线程中安装 |
| 整合包安装 | ModModpack.ModpackInstall(File, …) | 按识别出的整合包格式调用对应的安装方法 |
| 停用自动更新 | ModSecret.UpdateStart | 更新入口直接返回 |
| 地区限制 | RegionAssessment.get_IsRestricted | 判定方法直接返回 false;下载、安装、补全等入口均读取这一属性 |
单文件包的原地改写
部分启动器以 .NET 单文件包的形式发布。Campfire 会先在包内定位目标程序集,再将相关方法的方法体原地改写。文件大小与打包布局都保持不变,无需重新打包。
写入流程
- 读取启动器并定位全部修改点;
- 在内存中生成修复后的文件;
- 重新加载生成结果,逐项确认每个修改点均已生效;
- 将原文件备份为
.bak; - 写入修复后的文件。
任一步骤失败,原文件都保持不变。再次检测同一启动器时,Campfire 能够识别其已修复的状态。
更新签名
正式版的每个更新包都使用 ECDSA P-256 私钥签名,对应的公钥内置在程序中。Campfire 只安装签名校验通过的更新包;即使下载渠道被篡改,未经签名的程序也无法被安装。
