Featured image of post 关于 Forge 使用过的各种主机名标记

关于 Forge 使用过的各种主机名标记

编写 Minecraft 代理过程中难以绕过的细节,完全是一团糟。

Minecraft Forge 一直以来有一个特殊的行为,他们可能会修改 Minecraft 握手包中的主机名部分。 他们用这个标记来识别一个客户端是否安装了 Forge,因此 Forge 服务器可以在服务器列表上就能向非 Forge 客户端提供警告。这也许是他们想到的实现此功能的唯一方法。

然而,这样的行为实际上是自行约定的,因为 Mojang 没有定过相关标准。Forge 这样写是因为它能正常工作,且兼容官方服务器(因为官方实现也不对此项进行合法性检查),仅此而已。 由于 Forge 的热门度,所有服务器实现或代理都需要兼容这一协议方言。我知道在技术上讲这并不困难,但不影响它实际上是一团糟的事实。

截至公元2024年11月5日,wiki.vg 只在其页面介绍了 FML 协议的两个版本。实际上在 FML2 协议后,Forge 还因为各种包括技术层面和非技术层面的原因进行了版本迭代。 而每次迭代后,主机名末尾的标记都会变化。因此,我将记录这些变化。本文会在未来更新以跟进版本。

FML 标记迭代表

游戏版本 Forge 分支 FML 标记 代码路径
[1.7.x, 1.12.2] Official \0FML\0 patches/minecraft/net/minecraft/network/handshake/client/C00Handshake.java.patch
[1.13.x, 1.17.x] \0FML2\0 src/main/java/net/minecraftforge/fml/network/FMLNetworkConstants.java
或 src/main/java/net/minecraftforge/fmllegacy/network/FMLNetworkConstants.java
[1.18.x, 1.20.1] \0FML3\0 src/main/java/net/minecraftforge/network/NetworkConstants.java
[1.20.4, +∞) LexForge \0FORGE src/main/java/net/minecraftforge/network/NetworkContext.java
NeoForge - -

需要注意的是,NeoForge 正式版自游戏版本 1.20.4 开始重构,删除了主机名标记的机制。

由于 Forge 在 1.20.1 前后经历了分叉,可能为了显示与 FML 作者 cpw 的彻底切割,官方 Forge(或称 LexForge)换掉了 FML 标记,改为 FORGE,并且删去了末尾的一个 \0

简单的处理办法

由于这些标记均以 \0 开头,并且 \0 不会出现在合法的主机名中,所以可以直接通过寻找索引的方法分割字符串。

事实上,Forge 本身Velocity 也都使用这种方法。ZBProxy 因此也采用此方法实现。

其它现代加载器没有这样的标记

目前为止,Fabric 及其下游加载器没有引入这样的特殊标记。目前不清楚其他模组加载器(包括远古版本的 Forge 和其他加载器)是否引入了类似的标记。

Copyright © Plaxz 2021, all rights reserved.
使用 Hugo 构建
主题 StackJimmy 设计