跳转至

网络协议

网络协议(Network Protocol)是Minecraft基岩版客户端与服务端之间进行数据通信所遵循的规则和格式。协议定义了双方交换信息的数据包结构、字段编码方式和交互流程。

概述

基岩版使用自有的网络协议栈进行客户端与服务端之间的通信。协议的底层传输基于RakNet,一种面向游戏优化的UDP网络库,在其上封装了基岩版特有的数据包格式和交互逻辑。

每个基岩版版本都有一个对应的协议版本号(Protocol Version)。当客户端和服务端的协议版本不匹配时,连接将被拒绝。

协议层次

基岩版的网络通信可以分为以下层次:

传输层

基岩版使用RakNet作为传输层协议。RakNet在UDP之上提供了可靠性保证、数据包排序、分片重组和连接管理等功能。RakNet的握手过程包括:

  1. 客户端发送Unconnected Ping。
  2. 服务端回复Unconnected Pong(包含服务器信息,即MOTD)。
  3. 客户端发起Open Connection Request。
  4. 双方完成RakNet连接建立。

游戏层

在RakNet连接建立后,客户端和服务端开始交换游戏数据包。游戏层的数据包使用统一的包装格式,每个数据包由一个数据包ID和载荷组成。数据包ID是一个无符号整数,唯一标识数据包的类型。

登录流程

客户端加入服务器的登录流程大致如下:

  1. Login:客户端发送登录请求,包含玩家身份信息和客户端数据。
  2. Server To Client Handshake:服务端发送握手数据包,包含用于加密的公钥。
  3. Client To Server Handshake:客户端完成加密握手。
  4. Play Status:服务端确认登录成功。
  5. Resource Packs Info:服务端告知客户端所需的资源包列表。
  6. Resource Pack Stack:服务端发送资源栈信息。
  7. Start Game:服务端发送世界初始化数据,包括世界种子、游戏规则、玩家位置等。
  8. 客户端加载完成:客户端完成区块加载后通知服务端,进入游戏。

数据包类型

基岩版协议定义了数百种数据包类型,涵盖游戏的各个方面:

  • 移动类:玩家移动、实体移动、传送等。
  • 方块类:方块更新、方块实体数据等。
  • 物品栏类:背包操作、容器交互等。
  • 实体类:实体生成、属性更新、事件触发等。
  • 命令类:命令执行、自动补全等。
  • 世界类:区块数据、维度切换、天气变化等。
  • 界面类:窗口打开和关闭、表单数据等。

数据编码

协议中的数据字段使用多种编码方式:

  • VarInt/VarLong:可变长度整数编码,用于节省带宽。
  • ZigZag编码:对有符号整数进行编码,使小绝对值的负数也能高效编码。
  • Little Endian:基岩版协议中多数固定长度整数使用小端序。
  • 字符串:使用VarInt前缀长度 + UTF-8编码的字节序列。
  • NBT:部分数据包中的复合数据使用NBT格式编码(基岩版使用小端序NBT变体)。

加密

基岩版的网络通信在登录握手完成后启用AES-256-CFB8加密。加密密钥通过ECDH密钥交换协议在握手过程中协商。启用加密后,所有后续的数据包载荷均为加密状态。

压缩

游戏数据包在发送前会进行压缩。基岩版支持ZlibSnappy和不压缩三种模式,压缩模式在连接建立时由服务端指定。

协议文档

Mojang官方维护了一份基岩版协议的结构描述仓库,使用自定义的viz语言编写,描述了每种数据包的字段结构和类型层次关系。