作者:UpSGE

前言

本文研究了从启动游戏到加入服务器的验证过程(在线模式),并给出了相关的应用示例。

验证过程

服务端启动阶段

Velocity

Vanilla

启动器登入阶段

客户端启动阶段

加入服务器阶段

  1. 客户端生成 共享密钥,服务端生成随机 serverId
  2. 客户端与服务器交换 共享密钥、 Username、服务器公钥 和 serverId
  3. 客户端和服务端使用 serverId、共享密钥 和 服务器公钥 计算 服务器哈希
  4. 客户端将 AccessToken、UUID 和 服务器哈希 发送到 Join API ,若 AccessToken 和 UUID 验证通过,服务器返回 204 响应,否则客户端提示 无效会话
  5. 服务端将 Username、服务器哈希 发送到 hasJoined API ,若 Username 和 服务器哈希 验证通过,则返回 服务端UUID、服务端Username 和 签名材质,否则客户端提示 尚未登入至 Minecraft 账户(该提示可由服务端自定义)
  6. 服务端将 服务端UUID、服务端Username 发给客户端,客户端加入服务器,服务端将 签名材质 广播给所有玩家

后续

Vanilla 服务端验证玩家档案公钥签名

  1. 客户端发送 CHAT_SESSION_UPDATE 包
  2. 服务端使用 Mojang公钥 验证 玩家档案公钥签名
  3. 若验证不通过,服务端将玩家踢出服务器,客户端提示 无效的玩家档案公钥签名

客户端加载皮肤

  1. 客户端接收到 签名材质 广播
  2. 客户端使用 Mojang公钥 验证 签名材质 是否有效,并判断材质 URL 是否在白名单内
  3. 若验证不通过,客户端将不加载该玩家的皮肤

离线模式

客户端

服务端

应用分析

  1. 注意到 Join API 和 hasJoined API 是两个独立的 API,且是否允许进服最终取决于 hasJoined API 的验证结果。通过改变 hasJoined API 端点,API 可以控制玩家是否可以加入服务器。
  2. 服务器中的实际 服务端UUID 与客户端的 UUID 无关,仅从 hasJoined API 中获取。这可以用于实现玩家身份的映射。
  3. 玩家在服务器中显示的皮肤完全由服务端决定,服务端可以通过提供有效的 签名材质 来控制玩家的皮肤显示。
  4. 通过改变客户端与服务端的各种 API 端点,可以实现私有的玩家档案管理系统。

相关项目

参考