网络协议¶
网络协议(Network Protocol)是Minecraft基岩版客户端与服务端之间进行数据通信所遵循的规则和格式。协议定义了双方交换信息的数据包结构、字段编码方式和交互流程。
概述¶
基岩版使用自有的网络协议栈进行客户端与服务端之间的通信。协议的底层传输基于RakNet,一种面向游戏优化的UDP网络库,在其上封装了基岩版特有的数据包格式和交互逻辑。
每个基岩版版本都有一个对应的协议版本号(Protocol Version)。当客户端和服务端的协议版本不匹配时,连接将被拒绝。
协议层次¶
基岩版的网络通信可以分为以下层次:
传输层¶
基岩版使用RakNet作为传输层协议。RakNet在UDP之上提供了可靠性保证、数据包排序、分片重组和连接管理等功能。RakNet的握手过程包括:
- 客户端发送Unconnected Ping。
- 服务端回复Unconnected Pong(包含服务器信息,即MOTD)。
- 客户端发起Open Connection Request。
- 双方完成RakNet连接建立。
游戏层¶
在RakNet连接建立后,客户端和服务端开始交换游戏数据包。游戏层的数据包使用统一的包装格式,每个数据包由一个数据包ID和载荷组成。数据包ID是一个无符号整数,唯一标识数据包的类型。
登录流程¶
客户端加入服务器的登录流程大致如下:
- Login:客户端发送登录请求,包含玩家身份信息和客户端数据。
- Server To Client Handshake:服务端发送握手数据包,包含用于加密的公钥。
- Client To Server Handshake:客户端完成加密握手。
- Play Status:服务端确认登录成功。
- Resource Packs Info:服务端告知客户端所需的资源包列表。
- Resource Pack Stack:服务端发送资源栈信息。
- Start Game:服务端发送世界初始化数据,包括世界种子、游戏规则、玩家位置等。
- 客户端加载完成:客户端完成区块加载后通知服务端,进入游戏。
数据包类型¶
基岩版协议定义了数百种数据包类型,涵盖游戏的各个方面:
- 移动类:玩家移动、实体移动、传送等。
- 方块类:方块更新、方块实体数据等。
- 物品栏类:背包操作、容器交互等。
- 实体类:实体生成、属性更新、事件触发等。
- 命令类:命令执行、自动补全等。
- 世界类:区块数据、维度切换、天气变化等。
- 界面类:窗口打开和关闭、表单数据等。
数据编码¶
协议中的数据字段使用多种编码方式:
- VarInt/VarLong:可变长度整数编码,用于节省带宽。
- ZigZag编码:对有符号整数进行编码,使小绝对值的负数也能高效编码。
- Little Endian:基岩版协议中多数固定长度整数使用小端序。
- 字符串:使用VarInt前缀长度 + UTF-8编码的字节序列。
- NBT:部分数据包中的复合数据使用NBT格式编码(基岩版使用小端序NBT变体)。
加密¶
基岩版的网络通信在登录握手完成后启用AES-256-CFB8加密。加密密钥通过ECDH密钥交换协议在握手过程中协商。启用加密后,所有后续的数据包载荷均为加密状态。
压缩¶
游戏数据包在发送前会进行压缩。基岩版支持Zlib、Snappy和不压缩三种模式,压缩模式在连接建立时由服务端指定。
协议文档¶
Mojang官方维护了一份基岩版协议的结构描述仓库,使用自定义的viz语言编写,描述了每种数据包的字段结构和类型层次关系。