全部发向网络的数据都遵守大端序,这意味着字节将按照高位到地位的顺序发送。大部分现在的计算机都是使用的小端序,所以有可能需要在发送信息前交换字节顺序。
除了字符串类型和元数据以外的类型,将会被使用一个自定义的方法解码,这些数据类型将会使用Java的DataInputStream和DataOutputStream
类型 | 大小(B) | 范围 | 备注 |
---|---|---|---|
bool | 1 | 0或者1 | 值只可能为true(0x01)或者false(0x00) |
byte | 1 | -128 到 127 | 有符号,补码存储 |
short | 2 | -32768 到 32767 | 有符号,补码存储 |
int | 4 | -2147483648 到 2147483647 | 有符号,补码存储 |
long | 8 | -9223372036854775808 到 9223372036854775807 | 有符号,补码存储 |
128位长整形 | 16 | 0 到 340282366920938463463374607431768211455 | 有符号,补码存储,在[0x2C](#Spawn Global Entity)。在原版服务端中其实是通过发送两个长整形实现的 |
float | 4 | 同Java中的float | 单精度32位IEEE754浮点类型 |
double | 8 | 同Java中的double | 双精度64位IEEE754浮点类型 |
string | 长于2,短于240 | --- | UTF-8编码的字符串,首位是字符串长度 |
VarInt | 可变 | https://developers.google.com/protocol-buffers/docs/encoding#varints | 中文解释:http://zlx19900228.iteye.com/blog/1058659 |
VarLong | 可变 | 除了变成长整形以外和VarInt一样 | |
metadata | 可变 | http://wiki.vg/Entities#Entity_Metadata_Format | 中文翻译TODO |
Slot Data | 可变 | http://wiki.vg/Slot_Data | 中文翻译TODO |
Position | 8 | 见下方解释 | |
UUID | 16 | 由两个长整形组成,this.writeLong(uuid.getMostSignificantBits()); this.writeLong(uuid.getLeastSignificantBits()); |
被分成三部分的64位长整形
x: 26位最高有效位
z: 26位最低有效位
y: 其中的12位
按照以下方式编码
((x & 0x3FFFFFF) << 38) | ((y & 0xFFF) << 26) | (z & 0x3FFFFFF)
可以按照以下方式解码
long val; // val是一个坐标
x = val >> 38;
y = (val >> 26) & 0xFFF
z = val << 38 >> 38
一些数据是以定点小数存储的, 前面几位数表示整数部分 (小数点左边的数字) 剩下的部分表示小数部分(小数点右边的)。相比之下浮点数(浮点和双精度)保存自身的数字(尾数)在一个区块中,小数点的位置 (幂)则存在它旁边。
基本上,定点小数比浮点数有更小的范围,它分数展示对更高的值有利。这使得他们很完美的全局用坐标表示minecraft实体的位置,在一个单独的方块(或meter)中,准确存储其整数部分比定位它们更重要。
坐标一般以一个32位整数显示,前面五位是分数部分,剩下存储的是整数部分。
Java缺乏对分数整数的支持,但你可以以整数形式显示它们。若要将双精浮点数转为整数形式,可以用以下公式:
abs_int = (int)double * 32;
也可以通过以下公式算回来:
double = (double)abs_int / 32;
请查看协议版本号来获取旧版本的信息。
Minecraft版本 | 协议版本 |
---|---|
1.8.1 | 47 |
1.8 | |
1.7.6 | 5 |
1.7.2 | 4 |
Term | 定义 |
---|---|
Player | 在单独使用时,玩家总是倾向客户端连接到服务器。 |
Entity | 实体课指代任何物品,玩家,生物,矿车,船等等。请参阅Minecraft Wiki的文章上的完整列表。 |
EID | 一个EID,或实体ID,是一个用来指定实体的四字节数列。每个实体的EID在整个服务器上是独立的。 |
XYZ | 在这个文档中,坐标轴显示的名称和在调试窗口(F3)中看到的相同,Y表示上,X表示东,Z表示南。 |
请参考:测量单位 |
Minecraft1.7的数据包,以及未启用压缩的Minecraft1.8服务器的数据包采用这种格式:
名称 | 类型 | 备注 |
---|---|---|
长度 | VarInt | 等于"数据包ID+数据"的总字节数 |
ID | VarInt | 决定数据包类型 |
数据 | 具体内容因数据包类型而定 |
启用了压缩的Minecraft1.8数据包格式如下:
名称 | 类型 | 备注 |
---|---|---|
包长度 | VarInt | 等于下方两者解压前的总字节数 |
解压后长度 | VarInt | 等于下者解压后的总字节数. 若为0则表示本包未被压缩(比如包长度小于压缩阀值). |
压缩数据 | 经Zlib压缩.开头是一个VarInt字段,代表数据包ID,然后是数据包数据. |
启用压缩时,压缩数据在解压完毕后长度必须大于或等于预先约定的压缩阀值,否则服务器/客户端会断开连接.
可以通过将阀值设为负数如-1来关闭压缩.
Ping和登陆都是先以一次握手开始,唯一的区别在于两者的"Next state"字段.
数据包ID | 字段名 | 类型 | 备注 |
---|---|---|---|
0x00 | Protocol Version | VarInt | 协议版本(在1.7.2下值为4) |
Server Address | String | 服务器地址,可以是主机名(如"localhost")也可以是IP. 一个String是由一个代表字符串字节数的VarInt和一个UTF-8字符串组成 | |
Server Port | Unsigned Short | 端口号,如25565. 以大端序编码和读取 | |
Next state | VarInt | 代表本次握手的目的,1为Ping请求,2为登陆请求 |
服务端将会不断发送包含了一个随机数字标识符的保持在线,客户端必须以相同的数据包回复。如果客户端超过30s没有回复,服务端将会踢出玩家。反之,如果服务端超过20s没有发送任何保持在线,那么客户端将会断开连接并产生一个“Timed out”(超时)异常。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x00 | 游戏 | 客户端 | Keep Alive | VarInt |
更多关于“登陆游戏”的信息请参照“协议加密”。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x01 | 游戏 | 客户端 | Entity ID | Int | 玩家的实体ID |
Gamemode | Unsigned Byte |
0: 生存模式 1: 创造模式 2: 冒险模式 第三位(0x08)是极限模式的标识符 |
|||
Dimension | Byte |
-1: 下界 0: 主世界 1: 末地 |
|||
Difficulty | Unsigned Byte | 从 0 ~ 3 分别对应了 和平,简单,普通和困难 | |||
Max Players | Unsigned Byte | 客户端会以此来绘制玩家列表 | |||
Level Type | String |
default: 普通世界 flat: 超平坦 largeBiomes: 巨大生物群系 amlified: 放大世界 default_1_1: 老算法的普通世界 |
|||
Reduced Debug Info | Boolean |
非法的维度(Dimension)将使客户端崩溃!
区分聊天消息和系统消息对于尊重(实现)使用者的聊天可见设置是十分重要的,2号位置可以同时接受Json格式或是老的格式。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x02 | 聊天 | 客户端 | Json Data | String | 聊天消息 |
Position | Byte |
0: 聊天消息(聊天窗) 1: 系统消息(聊天窗) 2: 浮动栏 |
非法的Json数据将使客户端崩溃!
时间是基于tick(刻)的,1s = 20 ticks,游戏中一天共24000刻,大约相当于现实中的20分钟。
时间是通过总tick数对24000去模得到的,0是日出。6000是正午,1200是日落,1800是午夜。
服务器默认每秒将tick数增加20
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x03 | 游戏 | 客户端 | Age of world | Long | 不会被服务器命令影响 |
Time of day | Long |
世界(或地区)时间,以tick计 如果为负数,太阳的位置(时间)将停留在它的绝对值的位置 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x04 | 游戏 | 客户端 | EntityID | VarInt | 实体的ID |
Slot | Short |
装备的类型 0: 手持 1-4: 分别对应 鞋子 裤衩 胸甲 头盔 |
|||
Item | Slot | Slot格式的装备(物品) |
服务器在客户端登陆后发送的指定玩家出生点(包括出生位置和指南针指向),它也可以在任何时候被发送,不过那只会影响指南针的指向。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x05 | 游戏 | 客户端 | Location | Position | 出生点 |
服务器发送给玩家以设置或更新他们的生命值
饱食度是作为食品值的过饱和度,食品值在饱食度大于0时不会降低,登陆的玩家会自动获得5.0的饱食度,进食将同时增加饱食度和食品值。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x06 | 游戏 | 客户端 | Health | Float | 20 = 满生命值, 0即以下为死亡 |
食品值 | VarInt | 0-20 | |||
饱食度 | Float | 从0.0到5.0的整数增量变化 |
要更改玩家的维度(dimension=[主世界/下界/末地]),需要发送一个包含了合适的维度的重生数据包,紧跟着新维度的区块数据,最后是一个“坐标视点“包,你不需要卸载区块,客户端会自动处理这些问题。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x07 | 游戏 | 客户端 | Dimension | Byte |
-1: 下界 0: 主世界 1: 末地 |
Difficulty | Unsigned Byte | 从 0 ~ 3 分别对应了 和平,简单,普通和困难 | |||
Gamemode | Unsigned Byte |
0: 生存模式 1: 创造模式 2: 冒险模式 不包含极限模式的标识符 |
|||
Level Type | String | 同 加入游戏 |
非法的维度(Dimension)客户端崩溃
避免更改玩家的维度到他们原来所在的维度,将会出现奇怪的错误:比如这些玩家将无法攻击其他的玩家(在死亡重生后恢复)
更新玩家在服务器上的坐标。如果服务器上次已知的玩家坐标和最新发送的数据包的数据的坐标位置相差超过100单位的话,将导致玩家因“移动速度太快 :( (使用作弊器?)”而提出服务器。一般来说如果定点小数的X轴或Z轴的值大于3.2E7D将导致客户端被踢出并显示“无效的坐标”。
偏航(yaw)以角度计算,而且会遵循经典三角规则。偏航的圆单位是在XZ平面上以(0,1)为原点绕逆时针旋转,90度为(-1,0),180度时为(0,-1),270度时为(1,0)。
另外,偏航的数值不一定要在0到360之间;任意数字都是有效的,包括负数和大于360的数字。 仰角(pitch)是以角度计算,0代表直视前方,-90表示看正上方,而90表示看正下方。 玩家的偏航(以角度计),站在点(x0,y0)并看点(x,z)可以通过以下方式计算:
l = x-x0
w = z-z0
c = sqrt( l*l + w*w )
alpha1 = -arcsin(l/c)/PI*180
alpha2 = arccos(w/c)/PI*180
if alpha2 > 90 then
yaw = 180 - alpha1
else
yaw = alpha1
你可以从以下方式通过所给的仰角/偏航而得到向量值:
x = -cos(pitch) * sin(yaw)
y = -sin(pitch)
z = cos(pitch) * cos(yaw)
关于标记字段:
<Dinnerbone> It's a bitfield, X/Y/Z/Y_ROT/X_ROT. If X is set, the x value is relative and not absolute.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | Notes | |
---|---|---|---|---|---|---|
0x08 | 游戏 | 客户端 | X | Double | 绝对/相对坐标 | |
Y | Double | 绝对/相对坐标 | ||||
Z | Double | 绝对/相对坐标 | ||||
Yaw | Float | X轴上的绝对/相对方向,角度计 | ||||
Pitch | Float | Y轴上的绝对/相对方向,角度计 | ||||
Flags | Byte | X | 0x01 | |||
Y | 0x02 | |||||
Z | 0x04 | |||||
Y_ROT | 0x08 | |||||
X_ROT | 0x10 |
发送数据包来改变玩家所选择的物品槽
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
0x09 | 游戏 | 客户端 | Slot | Byte | 玩家所选择的物品槽(0-8) |
这个数据包将告诉玩家上床了。 有匹配的实体ID的客户端将会进入床模式。 这个数据包将发送给所有附近的玩家(包括已经在床上的玩家)
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0A | 游戏 | 客户端 | Entity ID | VarInt | 玩家ID |
Location | Position | 床头部分的方块的所在位置 |
发送任何一个实体都将改变动作。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
0x0B | 游戏 | 客户端 | Entity ID | VarInt | 玩家ID |
Animation | Unsigned Byte | 动作ID | |||
动作ID可以为以下值:
ID | 动作 |
0 | 挥手 |
1 | 伤害动作 |
2 | 离开床 |
3 | 吃食物 |
4 | Critical effect |
5 | Magic critical effect |
102 | (未知) |
104 | 蹲下 |
105 | 起立 |
这个包会在玩家到达可见区域发送,不是在玩家加入时发送。 服务器可以,然而,安全的不在可见范围内生成玩家实体。 客户端将会正确控制它。 当服务器的online-mode(正版模式),UUID必须有效而且要有有效的皮肤,在离线模式下需要UUID v3。
<+Grum> i will never confirm this as a feature you know that :)
在这个示例UUID,xxxxxxxx-xxxx-Yxxx-xxxx-xxxxxxxxxxxx中,UUID版本是通过Y来指定的。所以对于UUID v3来说,Y的值一直都为3;对UUID v2来说,Y的值一直为2。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0C | 游戏 | 客户端 | Entity ID | VarInt | 玩家的实体ID |
Player UUID | UUID | 玩家的UUID | |||
X | Int | Player X as a Fixed-Point number | |||
Y | Int | Player X as a Fixed-Point number | |||
Z | Int | Player X as a Fixed-Point number | |||
Yaw | Byte | 玩家的方向的压缩字节 | |||
Pitch | Byte | 玩家的方向的压缩字节 | |||
Current Item | Short | 玩家当前所拿的物体。注意这个当为0意为“没有物体”,不像在其他包中所用的-1那样。负数值将导致客户端崩溃。 | |||
Metadata | Metadata | 如果没有元数据发送客户端将崩溃 |
如果没有元数据发送客户端将崩溃
服务器将在玩家捡起一个落在地上的物品时发出这个包。 -这个包的意义是向你展示这个东西飞向你。它不会摧毁客户端实体占用的的内存。 而且它不会加到你的背包中。服务器只会在每次客户端发送的玩家位置坐标[以及玩家的位置和所看的方向]发生改变后检查物品是否捡起。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0D | 游戏 | 客户端 | Collected Entity ID | VarInt | |
Collector Entity ID | VarInt |
当服务端生成一个实体/交通工具时发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0E | Play | Client | Entity ID | VarInt | 对象的实体ID |
Type | Byte | 对象的类型(详情见对象) | |||
X | Int | X坐标值的定点小数 | |||
Y | Int | Y坐标值的定点小数 | |||
Z | Int | Z坐标值的定点小数 | |||
Pitch | Byte | 偏航值以2p/256记 | |||
Yaw | Byte | 仰角值以2p/256记 | |||
Data | Object Data |
当服务端生成一个生物实体的时候发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0F | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Type | Unsigned Byte | 生物类型,具体查看生物 | |||
X | Int | X坐标值的定点小数 | |||
Y | Int | Y坐标值的定点小数 | |||
Z | Int | Z坐标值的定点小数 | |||
Yaw | Byte | 偏航值以2p/256记 | |||
Pitch | Byte | 仰角值以2p/256记 | |||
Head Pitch | Byte | 仰角值以2p/256记 | |||
Velocity X | Short | ||||
Velocity Y | Short | ||||
Velocity Z | Short | ||||
Metadata | Metadata |
这个包含有坐标,名称,以及画的类型。 计算一个画框的中心可以这样:指定一个(宽x高)的格子,以(0,0)点作为左上角,中心则为(max(0, 宽 / 2 - 1), 高 / 2)。例如:2x1 (1, 0) 4x4 (1, 2)
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x10 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Title | String | 画框名,最大为13 | |||
Location | Position | 坐标中心 | |||
Direction | Unsigned Byte | 画框面向的方向(0 -z, 1 -x, 2 +z, 3 +x) |
生成一个或多个经验球。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x11 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
X | Int | X坐标值的定点小数 | |||
Y | Int | Y坐标值的定点小数 | |||
Z | Int | Z坐标值的定点小数 | |||
Count | Short | 一次收集到将获得的经验数量 |
速度是以1/8000方块每刻(tick,1tick=50ms);例如,-1343将会移动(-1343 / 8000) = −0.167875每刻(或-3,3575方块每秒)
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 说明 |
---|---|---|---|---|---|
0x12 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Velocity X | Short | X轴上的速度 | |||
Velocity Y | Short | Y轴上的速度 | |||
Velocity Z | Short | Z轴上的速度 |
服务端在一列实体被客户端破坏时发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x13 | 游戏 | 客户端 | Count | VarInt | 列表长度 |
Entity IDs | Array of VarInt | 破坏的实体的列表 |
大多数与实体相关的数据包是这个包的一个小类别。当从服务器发送到客户端时,它将初始化实体。 对玩家实体而言,这个包或其他任何移动/改变视点包都是每一刻(tick)会发送的。 所以这个包存在的基本意义是服务器收到实体的包后才会移动/改变视点。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x14 | 游戏 | 客户都uan | Entity ID | VarInt | 实体ID |
服务器将会在实体移动距离小于4个方块时发送;如果一个实体移动距离大于4个方块,服务器将会发送实体传送而不是实体相对移动。 这个数据包允许任意方向不超过四个方向的移动,因为字节的范围是从-128到127。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x15 | Play | Client | Entity ID | VarInt | 实体ID |
DX | Byte | X方向移动的定点小数值 | |||
DY | Byte | Y方向移动的定点小数值 | |||
DZ | Byte | Z方向移动的定点小数值 | |||
On Ground | Boolean |
这个数据包服务器在实体转向时发送。例如:偏航(yaw)字段值为64意为转90度。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x16 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Yaw | Byte | X轴旋转角度在360度中的比例 | |||
Pitch | Byte | Y轴旋转角度在360度中的比例 | |||
On Ground | Boolean |
这个数据包服务器在实体旋转且移动的时候发送。由于字节的范围限制在-128到127, 偏移量为定点小数,这个数据包允许任意方向最多四个方块距离的移动 (-128/32 == -4)。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x17 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
DX | Byte | X方向移动的定点小数值 | |||
DY | Byte | Y方向移动的定点小数值 | |||
DZ | Byte | Z方向移动的定点小数值 | |||
Yaw | Byte | X轴旋转角度在360度中的比例 | |||
Pitch | Byte | Y轴旋转角度在360度中的比例 | |||
On Ground | Boolean |
这个数据包服务器在实体移动距离超过四个方块时发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x18 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
X | Int | X坐标值的定点小数 | |||
Y | Int | Y坐标值的定点小数 | |||
Z | Int | Z坐标值的定点小数 | |||
Yaw | Byte | X轴旋转角度在360度中的比例 | |||
Pitch | Byte | Y轴旋转角度在360度中的比例 | |||
On Ground | Boolean |
改变实体面朝方向。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x19 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Head Yaw | Byte | 头偏航值以2p/256记 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x1A | 游戏 | 客户端 | Entity ID | Int | 实体ID |
Entity Status | Byte | 见下表 |
实体状态 | 意义 |
---|---|
0 | 是否有东西与活动实体有联系? |
1 | 是否有东西与玩家实体有联系? |
2 | 活动实体受伤害 |
3 | 活动实体死亡 |
4 | 铁傀儡挥手 |
6 | 狼/豹猫/马交配 - 生成“心形”颗粒 |
7 | 狼/豹猫/马被驯服 - 生成 "烟雾" 颗粒 |
8 | 狼抖去水 - 触发摇头动画 |
9 | (对自己)吃的动作被服务器接受 |
10 | 羊吃草 |
10 | 播放TNT矿车点燃的声音 |
11 | 铁傀儡拿着玫瑰花 |
12 | 村民交配 - 生成“心形”颗粒 |
13 | 显示颗粒来表示村民很愤怒而且准备复仇 |
14 | 在村民附近显示“高兴”颗粒 |
15 | 女巫动作 - 生成 "魔法" 颗粒 |
16 | 播放僵尸变成村民的声音 |
17 | 烟花爆炸 |
18 | 动物相爱 (准备交配) - 生成“心形”颗粒 |
19 | 重置鱿鱼方向 |
20 | 生成爆炸粒子 - 一部分活动实体才有此效果 |
21 | 播放“守护的”声音 - 对所有实体都有效 |
22 | 启用玩家的调试屏幕 |
23 | 禁用玩家的调试屏幕 |
这个数据包在玩家衣服于一个实体时发送。(例如矿车)
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x1B | 游戏 | 客户端 | Entity ID | Int | 实体ID |
Vehicle ID | Int | 交通工具的实体ID | |||
Leash | Boolean | 如果为true将绑定实体于交通工具上 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x1C | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Metadata | Metadata |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x1D | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Effect ID | Byte | 看这张表 | |||
Amplifier | Byte | Notchian client显示药水效果等级为 Amplifier + 1 | |||
Duration | VarInt | 秒 | |||
Hide Particles | Boolean |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x1E | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Effect ID | Byte |
服务器在客户端应该更改经验等级的时候发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x1F | 游戏 | 客户端 | Experience bar | Float | 0到1之间 |
Level | VarInt | ||||
Total Experience | VarInt |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x20 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Count | Int | 后面的数组的长度 | |||
Properties | Array of Property Data |
字段名 | 字段类型 | 备注 |
---|---|---|
Key | String | |
Value | Double | |
List Length | VarInt | Number of list elements that follow. |
Modifiers | Array of Modifier Data | http://www.minecraftwiki.net/wiki/Attribute#Modifiers |
已知键值:
键 | 默认 | 最小 | 最大 | 标签 |
---|---|---|---|---|
generic.maxHealth | 20 | 0 | Double.MaxValue | Max Health |
generic.followRange | 32 | 0 | 2048 | Follow Range |
generic.knockbackResistance | 0 | 0 | 1 | Knockback Resistance |
generic.movementSpeed | 0.699999988 | 0 | Double.MaxValue | Movement Speed |
generic.attackDamage | 2 | 0 | Double.MaxValue | |
horse.jumpStrength | 0.7 | 0 | 2 | Jump Strength |
zombie.spawnReinforcements | 0 | 0 | 1 | Spawn Reinforcements Chance |
字段名 | 字段结构 | 备注 |
---|---|---|
UUID | 128-bit integer | |
Amount | Double | |
Operation | Byte |
区块不会由客户端自动卸载。如需卸载区块,发送含有 ground-up continuous=true 并且没有 16^3 区块的数据包(如primary bit mask=0)。服务器不会发送下界地图区块的光照信息,这使得客户端知道玩家正处于下界。你也可以通过主位掩码和发送的未压缩的字节数的数量来推断这些信息。 请参阅:SMP地图格式
在1.8版本中的改变:
- 移除了数据值部分
- 移除了扩展ID部分
- 现在每个方块的id选择变成了一个无符号短整数(从小到大)
- 方块id现在相当于 (id << 4) | data
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x21 | 游戏 | 客户端 | Chunk X | Int | 区块的X坐标 |
Chunk Z | Int | 区块的Z坐标 | |||
Ground-Up continuous | Boolean | This is True if the packet represents all sections in this vertical column, where the primary bit map specifies exactly which sections are included, and which are air | |||
Primary bit map | Unsigned Short | Bitmask为1时每个16x16x16选择区域的方块信息将以压缩后的信息呈现 | |||
Size | VarInt | 区块数据的大小 | |||
Data | Byte array | 区块数据在14w28a版本后不会压缩 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x22 | 游戏 | 客户端 | Chunk X | Int | 区块的X坐标 |
Chunk Z | Int | 区块的Z坐标 | |||
Record count | VarInt | 所影响的方块数量 | |||
Records | Array of Records |
记录值
位掩码 | 宽度 | 意义 |
---|---|---|
00 FF | 8 bits | Y坐标 |
0F 00 | 4 bits | Z坐标,与区块有关 |
F0 00 | 4 bits | X坐标,与区块有关 |
? | VarInt | 方块ID |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x23 | 游戏 | 客户端 | Location | Position | 方块坐标 |
Block ID | VarInt | 新方块的ID id << 4 | data |
这个数据包将会用于以下情况:
- 箱子的大开恶化关闭
- 活塞的推拉
- 音符盒播放音乐
- 信标的更新
请参阅:方块表现
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x24 | Play | Client | Location | Position | 方块坐标 |
Byte 1 | Unsigned Byte | 不同方块都不相同 - 见方块表现 | |||
Byte 2 | Unsigned Byte | 不同方块都不相同 - 见方块表现 | |||
Block Type | VarInt | 方块的类型 |
0-9将显示方块的破坏程度,其他数字意为这个坐标上没有动画。. 你也可以对空气方块设置动画!破坏动画仍然可见! 如果你想同时显示多个破坏动画的话,你需要给它们每个独立的实体ID。 当然如果你设置坐标为水之类的方块的话。它将不会显示真实的破坏动画而是其他一些很有意思的东西。(比如水方块将失去它的透明度)
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x25 | 游戏 | 客户端 | Entity ID | VarInt | 实体ID |
Location | Position | 方块的位置 | |||
Destroy Stage | Byte | 0 - 9 或其他任意值来移除方块 |
请参阅:SMP地图格式
1.8版的改变在:区块数据
降低数据包的字节数用于将区块一起发送以获得更好的压缩效果。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x26 | 游戏 | 客户端 | Sky light sent | Bool | 无论这个区块是否有光照值信息。在主世界为true,在下界和末地为false |
Chunk column count | VarInt | 这个数据包所含有的区块数量 | |||
Meta information | Meta | 见下表 | |||
Data | Byte Array | 区块信息在14w28a后不再被压缩 |
Meta
字段名 | 字段类型 | 备注 |
---|---|---|
Chunk X | Int | 区块的X坐标 |
Chunk Z | Int | 区块的Z坐标 |
Primary bitmap | Unsigned Short | 一个会注明这个区块里的哪部分不是空的位图 |
当爆炸发生的时候发送(爬行者,TNT,恶魂的火球) 每个方块的记录都将被设置为空气。每个轴上的坐标信息将会以 int(X) + record.x 来记录
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x27 | 游戏 | 客户端 | X | Float | |
Y | Float | ||||
Z | Float | ||||
Radius | Float | 目前未在客户端中使用 | |||
Record count | Int | 这是总数,不是大小,大小是这个值的3倍 | |||
Records | (Byte, Byte, Byte) × count | 每个记录都为3符号字节长,每个受影响的方块的偏移量都是由独立的XYZ字节来控制 | |||
Player Motion X | Float | 玩家在爆炸后将会被推向的X坐标 | |||
Player Motion Y | Float | 玩家在爆炸后将会被推向的Y坐标 | |||
Player Motion Z | Float | 玩家在爆炸后将会被推向的Z坐标 |
在客户端产生声音或者药水效果的时候发出。
默认,minecraft客户端通过距离来调整声音效果的音量。最终由布尔值来禁用它后,声音将会由你当前方向前两个方块发出。现在这个只能用于影响1013(mob.wither.spawn),而且会被客户端的其他任意值忽略。
ID | Name |
---|---|
声音 | |
1000 | random.click |
1001 | random.click |
1002 | random.bow |
1003 | random.door_open or random.door_close (50/50 chance) |
1004 | random.fizz |
1005 | 播放音乐碟。 Data Record ID |
(1006 未分配) | |
1007 | mob.ghast.charge |
1008 | mob.ghast.fireball |
1009 | mob.ghast.fireball, but with a lower volume. |
1010 | mob.zombie.wood |
1011 | mob.zombie.metal |
1012 | mob.zombie.woodbreak |
1013 | mob.wither.spawn |
1014 | mob.wither.shoot |
1015 | mob.bat.takeoff |
1016 | mob.zombie.infect |
1017 | mob.zombie.unfect |
1018 | mob.enderdragon.end |
1020 | random.anvil_break |
1021 | random.anvil_use |
1022 | random.anvil_land |
颗粒 | |
2000 | 生成10个烟雾效果,例如从火种。 数据方向见下表。 |
2001 | 方块破坏 Data 方块ID |
2002 | Splash potion. Particle effect + glass break sound. Data Potion ID |
2003 | Eye of ender entity break animation - particles and sound |
2004 | Mob spawn particle effect: smoke + flames |
2005 | Spawn "happy villager" effect (green crosses), used for bonemealing vegetation. |
ID | Direction |
---|---|
0 | 东南 |
1 | 南 |
2 | 西南 |
3 | 西 |
4 | (上或中间?) |
5 | 东 |
6 | 东北 |
7 | 北 |
8 | 西北 |
用来播放客户端中的音效
所有已知的音效名可以在这里查到。
资源包中可能会加入自定义声音。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x29 | 游戏 | 客户端 | Sound name | String | |
Effect position X | Int | 影响的X坐标乘以8 | |||
Effect position Y | Int | 影响的Y坐标乘以8 | |||
Effect position Z | Int | 影响的Z坐标乘以8 | |||
Volume | Float | 1代表100%,可以更大 | |||
Pitch | Unsigned Byte | 63代表100%,可以更大 |
显示已命名的颗粒
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x2A | 游戏 | 客户端 | Particle Id | Int | |
Long Distance | Boolean | 如为true, 颗粒距离将会从256增加到65536. | |||
X | Float | 颗粒的X坐标 | |||
Y | Float | 颗粒的Y坐标 | |||
Z | Float | 颗粒的Z坐标 | |||
Offset X | Float | 这是添加到被random.nextGaussian()乘以后的X的位置 | |||
Offset Y | Float | 这是添加到被random.nextGaussian()乘以后的Y的位置 | |||
Offset Z | Float | 这是添加到被random.nextGaussian()乘以后的Z的位置 | |||
Particle data | Float | The data of each particle | |||
Number of particles | Int | 所生产的颗粒的数量 | |||
Data | Array of VarInt | 长度基于颗粒类型. ICON_CRACK, BLOCK_CRACK, 和 BLOCK_DUST 长度为2, 其他的长度为0。 |
颗粒ID表
颗粒名 | 颗粒Id |
---|---|
explode | 0 |
largeexplosion | 1 |
hugeexplosion | 2 |
fireworksSpark | 3 |
bubble | 4 |
wake | 5 |
splash | 6 |
suspended | 7 |
townaura | 8 |
crit | 9 |
magicCrit | 10 |
smoke | 11 |
largesmoke | 12 |
mobSpell? | 13 |
instantSpell | 14 |
spell | 15 |
witchMagic | 17 |
dripWater | 18 |
dripLava | 19 |
angryVillager | 20 |
happyVillager | 21 |
depthsuspend | 22 |
note | 23 |
portal | 24 |
enchantmenttable | 25 |
flame | 26 |
lava | 27 |
footstep | 28 |
cloud | 29 |
reddust | 30 |
snowballpoof | 31 |
snowshovel | 32 |
slime | 33 |
heart | 34 |
barrier | 35 |
这将在床不可作为出生点或下雨状态改变的时候使用。
这个键值有连接到原因代码的字段 0, 1, 2, and 3 但是代码1,2是无效的.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x2B | 游戏 | 客户端 | Reason | Unsigned Byte | |
Value | Float | 依原因而定 |
通过这个包,服务端可以通知客户端玩家半径512范围内有雷。坐标会指定雷击中的具体坐标。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x2C | 游戏 | 客户端 | Entity ID | VarInt | 雷的实体ID |
Type | Byte | 全局实体类型,当前一直都是1来表示雷电 | |||
X | Int | 雷电X坐标的定点小数 | |||
Y | Int | 雷电Y坐标的定点小数 | |||
Z | Int | 雷电Z坐标的定点小数 |
这个包会在打开背包的时候发送给客户端,比如打开箱子、工作台或熔炉。这个信息在任何时候都发送使客户端打开玩家自己的背包的包。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x2D | 游戏 | 客户端 | Window id | Unsigned Byte | 显示的窗口的唯一ID。 Notchian server 实例是一个从1开始的计数器。 |
Inventory Type | String | 用于显示的窗口类型,详情见下文 | |||
Window title | Chat | 窗口标题 | |||
Number of Slots | Unsigned Byte | 窗口中的栏位数量(玩家背包的栏位除外) | |||
Entity ID | Int | 马的实体ID,只有当窗口类型等于"EntityHorse"时适用。 |
当窗口被强制关闭时,这个包会由服务端发送给客户端,比如打开着的箱子被破坏。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x2E | 游戏 | 客户端 | Window ID | Unsigned Byte | 被关闭的窗口ID,0表示背包。 |
服务端在一个栏位的东西被增加/移除的时候发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x2F | 游戏 | 客户端 | Window ID | Byte | 被更新的窗口的窗口ID,0表示玩家背包。注意包括玩家背包的所有已知背包,即使会影响玩家的背包,这个数据包只会在玩家打开着窗口并且进行操作的时候发送。当窗口关闭后,大量这类包将发送来更新玩家的背包窗口(0)。 |
Slot | Short | 所更新的栏位 | |||
Slot data | Slot |
服务端在窗口中的一个栏位的物品被增加/移除的时候发送。这包括主背包,携带装备以及合成栏位。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x30 | 游戏 | 客户端 | Unsigned Byte | 被更改的物品所对应的窗口ID。0表示玩家背包。 | |
Short | 栏位数(见下图) | ||||
Array ofSlots |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x31 | 游戏 | 客户端 | Window ID | Unsigned Byte | 窗口的ID |
Property | Short | 将会被更新的状态类型 | |||
Value | Short | 新状态值 |
- 0:进展箭头
- 1:火图标(燃料) 值:
- 0-200表示进展箭头
- 0-200表示燃料指示 范围大约是游戏里的刻(tick) 附魔台 属性:0,1,2基于所给的“附魔栏位“(enchantment slot)。 值:附魔等级。 信标
- 0:能量等级
- 1:药水效果1
- 2:药水效果2 铁砧
- 0:最大消耗 酿造台
- 0:酿造时间 酿造时间值大小范围为0到400,400表示空箭头,0表示满箭头
服务端发这个包来确认请求是否被客户端所接受,或是否存在冲突(因为服务器卡顿造成的)
这个包也可以被客户端发送到服务端来回应服务端拒绝事物包。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x32 | 游戏 | 客户端 | Window ID | Byte | 行为发生的窗口的窗口ID |
Action number | Short | 每一个可被接受的动作都有一个独有的数字。这个字段即对应着这些数字 | |||
Accepted | Bool | 行为是否被接受。 |
这个信息服务端在牌子被覆盖或创建的时候发送给客户端。这信息不会再牌子被损坏或者卸载的时候发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x33 | 游戏 | 客户端 | Location | Position | 方块坐标 |
Line 1 | Chat | 牌子第一行的内容 | |||
Line 2 | Chat | 牌子第二行的内容 | |||
Line 3 | Chat | 牌子第三行的内容 | |||
Line 4 | Chat | 牌子第四行的内容 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x34 | 游戏 | 客户端 | Item Damage | VarInt | 地图正在更改部分的伤害值 |
Scale | Byte | ||||
Length | VarInt | ||||
Icons | 3 * length bytes | 第一字节, 0xF0 = Direction, 0x0F = Type. 第二字节, X. 第三字节, Y | |||
Columns | Byte | ||||
Rows | Byte | 只有列超过0时才可以 | |||
X | Byte | 只有列超过0时才可以 | |||
Y | Byte | 只有列超过0时才可以 | |||
Length | VarInt | 只有列超过0时才可以 | |||
Data | Length bytes | 只有列超过0时才可以 |
从本质上来说一个方块的更新是一个方块实体的更新。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x35 | 游戏 | 客户端 | Location | Position | |
Action | Unsigned Byte | 执行的更新类型 | |||
NBT Data | Byte Array | 如果不呈现则为 TAG_END (0) |
行为
- 1:设置刷怪笼的刷怪概率
- 2:设置命令方块文本(命令和最后执行的状态)
- 3:设置信标的等级,第一效果和第二效果
- 4:设置生物的头的方向和皮肤
- 5:设置花盆上的花类型
- 6:设置气质的基本颜色和样式
在放置牌子的时候发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x36 | 游戏 | 客户端 | Location | Position | 方块坐标 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 | |
---|---|---|---|---|---|---|
0x37 | 游戏 | 客户端 | Count | VarInt | 实体数量 | |
Entry | Statistic's name | String | https://gist.github.com/thinkofdeath/a1842c21a0cf2e1fb5e0https://gist.github.com/thinkofdeath/a1842c21a0cf2e1fb5e0 | |||
Value | VarInt | 发送的数量 |
notchian服务器在用户列表更新的时候发送(客户端的键列表)
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 | ||
---|---|---|---|---|---|---|---|
0x38 | 游戏 | 客户端 | Action | VarInt | |||
Length | VarInt | The following fields are repeatedlength times | |||||
UUID | UUID | 玩家的UUID | |||||
Action | |||||||
0 (ADD_PLAYER) | Name | String | |||||
Number of properties | VarInt | ||||||
Properties | Name | String | |||||
Value | String | ||||||
Is Signed | Boolean | ||||||
Signature | String | 只有已签名的时候为true | |||||
Gamemode | VarInt | ||||||
Ping | VarInt | ||||||
Has Display Name | Boolean | ||||||
Display Name | Chat | 只有当Has Display Name为true的时候发送 | |||||
1 (UPDATE_GAMEMODE) | Gamemode | VarInt | |||||
2 (UPDATE_LATENCY) | Ping | VarInt | |||||
3 (UPDATE_DISPLAY_NAME) | Has Display Name | Boolean | |||||
Display Name | Chat | 只有当Has Display Name为true的时候发送 | |||||
4 (REMOVE_PLAYER) |
后面的两个浮点数是用来分别表示玩家走路/飞行速度的, 第一个字节用来表示四个布尔值。
这些标记有玩家是否可以受到伤害 (god mode, 8, bit 3), 玩家是否可以飞行 (4, bit 2), 玩家是否在飞 (2, bit 1),以及玩家是否处于创造模式 (1, bit 0).
如需获得这些布尔值的信息, simply AND (&) the byte with 1,2,4 and 8 respectively, to get the 0 or 1 bitwise value. To set them OR (|) them with their repspective masks.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x39 | 游戏 | 客户端 | Flags | Byte | |
Flying speed | Float | previous integer value divided by 250 | |||
Walking speed | Float | previous integer value divided by 250 |
服务端会根据最后发送的单词来回应给客户端一个自动完成列表。在平常聊天时,这个列表是玩家的用户名。同时它也支持命令和参数。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x3A | 游戏 | 客户端 | Count | VarInt | 接下来发送的字符串数量 |
Match | String | 一个合适的命令,注意因为计数(Count)需求,每一个命令都是以单字符串单独发送的。 |
服务端在新建或删除一个计分板的时候发送给客户端。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x3B | 游戏 | 客户端 | Objective name | String | 容器独有的名称 |
Mode | Byte | 0表示新建计分板,1表示移除计分板,2表示更新显示文字 | |||
Objective value | String | 只有当Mode为0或2时才会显示分数 | |||
Type | String | 只有Mode为0或2时才可用。"integer"或"hearts" |
当计分板内容更新的时候发送给客户端。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x3C | Play | Client | Score name | String | 需要更新或删除的计分板名 |
Update/Remove | Byte | 0表示创建/更新一个项目,1表示删除项目 | |||
Objective Name | String | 分数所属的容器的容器名 | |||
Value | VarInt | 显示的分数值,只有在更新/删除的时候这个值不等于1. |
在客户端需要显示计分板的时候发给客户端。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x3D | 游戏 | 客户端 | Position | Byte | 计分板所处位置,0 = list, 1 = sidebar, 2 = belowName. |
Score Name | String | 计分板所显示的独有的名称 |
创建和更新队伍。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x3E | 游戏 | 客户端 | Team Name | String | 队伍独有的名称(和计分板共享) |
Mode | Byte | 0表示队伍已创建 | |||
1表示队伍已删除 | |||||
2表示队伍信息已更新 | |||||
3表示有新的玩家加入队伍 | |||||
4表示有玩家从队中除名 | |||||
Team Display Name | String | 只有当Mode=0或2时有效 | |||
Team Prefix | String | 只有当Mode=0或2时有效。显示在玩家名前面的是队伍名 | |||
Team Suffix | String | 只有当Mode=0或2时有效。显示在玩家名后面的是队伍名 | |||
Friendly fire | Byte | 只有当Mode=0或2时有效;0表示关闭,1表示大开,3表示隐藏队友的 | |||
Name Tag Visibility | String | 只有当Mode=0或2时有效;always, hideForOtherTeams, hideForOwnTeam, never. | |||
Color | Byte | 只有当Mode=0或2时有效。与聊天颜色相同 | |||
Player count | VarInt | 只有当Mode=0或3或4时有效,玩家数量在键值中 | |||
Players | Array of strings | 只有当Mode=0或3或4时有效,内容为添加或移除的玩家。最长40字所以以后可能会支持UUID。 |
Mod和插件可以用它来发送它们自己的数据。Minecraft自身使用一系列plugin channels。这些内部频道都前置于MC|. 更多信息可见此:http://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x3F | Play | Client | Channel | String | 所需要用于发送数据的“频道” |
Data | Byte Array | 任意数据 |
服务端在断开客户端的连接时发送。服务端假设发送者在收到这个包后已经关闭连接。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x40 | 游戏 | 客户端 | Reason | String | 在客户端释放连接的时候显示。一定要为有效的JSON格式。 |
在客户端的设置菜单中改变游戏难度。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x41 | 游戏 | 客户端 | Difficulty | Unsigned Byte | 0:和平, 1:简单, 2:一般, 3: 困难 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x42 | 游戏 | 客户端 | Event | VarInt | 0 ENTER_COMBAT, 1 END_COMBAT, 2 ENTITY_DEAD |
Duration | VarInt | 只用于 END_COMBAT | |||
Entity ID | Int | 只用于 END_COMBAT | |||
Player ID | VarInt | 只用于 ENTITY_DEAD | |||
Entity ID | Int | 只用于 ENTITY_DEAD | |||
Message | String | 只用于 ENTITY_DEAD |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x43 | Play | Client | Camera ID | VarInt |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 | |
---|---|---|---|---|---|---|
0x44 | 游戏 | 客户端 | Action | VarInt | ||
操作 | 名称 | |||||
0 (SET_SIZE) | Radius | Double | ||||
1 (LERP_SIZE) | Old radius | Double | ||||
New radius | Double | |||||
Speed | VarLong | |||||
2 (SET_CENTER) | X | Double | ||||
Z | Double | |||||
3 (INITIALIZE) | X | Double | ||||
Z | Double | |||||
Old radius | Double | |||||
New radius | Double | |||||
Speed | VarLong | |||||
Portal Teleport Boundary | VarInt | Resulting coordinates from a portal teleport are limited to +-value. Usually 29999984. | ||||
Warning time | VarInt | |||||
Warning blocks | VarInt | |||||
4 (SET_WARNING_TIME) | Warning time | VarInt | ||||
5 (SET_WARNING_BLOCKS) | Warning blocks | VarInt |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 | |
---|---|---|---|---|---|---|
0x45 | 游戏 | 客户端 | Action | VarInt | ||
Action | Name | |||||
0 (TITLE) | Text | Chat | ||||
1 (SUBTITLE) | Text | Chat | ||||
2 (TIMES) | Fade In | Int | ||||
Stay | Int | |||||
Fade Out | Int | |||||
3 (CLEAR) | ||||||
4 (RESET) |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x46 | 游戏 | 客户端 | Threshold | VarInt | Threshold是数据包压缩前最大的大小 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x47 | 游戏 | 客户端 | Header | Chat | |
Footer | Chat |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x48 | 游戏 | 客户端 | URL | String | 资源包的URL地址 |
Hash | String | 资源包的一个40位的16进制以及小写字母SHA-1散列 (必须小写字母才能保证它工作) | |||
如果不是40位长的16进制字段,客户端将不会用它来hash有效性而且很容易消耗带宽,但是仍然会以一个独有ID来对待 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x49 | 游戏 | 客户端 | Entity ID | VarInt | |
Tag | NBT Tag |
服务器会频繁向客户端发送保持在线数据包。每一个包都包含着一个随机的ID。客户端必须将数据包原封不动的发送回来。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x00 | 游戏 | 服务器端 | 随机数值 | VarInt |
默认的服务器会检查消息是否以‘/’开头。若不是,则将发送者的名字添加到消息前并将它发送给所有客户端端(包括发送者自己)。如果是以‘/’开头,服务器将认为它是一个指令并尝试处理它。如果一条消息长度超过100个字符将导致服务器将客户端踢出。这个改动起初是通过允许客户端不切分超过119个字符的消息(以前的限制),但在服务端上并未做改变。因此,原版服务器端保留了在119个字符的位置切分字符串的代码,不过这并不是协议的限制而且这个限制可以被忽略。
更多信息请参阅聊天。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x01 | 游戏 | 服务器端 | 消息 | String |
客户端会在玩家攻击或右键一个实体(比如玩家,马,矿车...)时发送此数据包给服务器.
原版服务器只会在实体距离玩家不超过4单位长度,并且两者之间视线不受阻碍时,才会处理此数据包.
(译注:在1.8中的规则是:若两者之间没有视线,则距离不能超过3. 若视线通畅,则距离不能超过6.)
注意在创造模式中,鼠标中间选取是在客户端进行,但它也会发送给服务器一个创造模式物品栏动作数据包.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x02 | 游戏 | 服务器 | Target | VarInt | 目标实体的EID |
Type | VarInt | 0 = 右键, 1 = 攻击, 2 = 右键_精确位置 (译注:"右键_精确位置"是1.8新引入的,目前仅用于装甲架. 任何在func_174825_a方法中返回true的实体,在被右键时都会发送"右键_精确位置"而不是"右键".) |
|||
Target X | Float | 只有类型为"右键_精确位置"时存在此字段 | |||
Target Y | Float | 只有类型为"右键_精确位置"时才存在此字段 | |||
Target Z | Float | 只有类型为"右键_精确位置"时存在此字段 |
这个数据包是用来表示玩家是在地上(包括游泳),还是在空中(包括跳起和下落).
当从一定高度落下时,跌落伤害会在此项从False变为True时施加在玩家身上. 伤害程度是根据上次此项由True变False时,玩家站立的地点的高度来决定. 注意:并非只有此数据包会引起跌落伤害计算,其他的几种跟移动相关的数据包也能引发跌落伤害.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x03 | 游戏 | 服务器 | On Ground | Bool | True为在地上或者在游泳,False为其他情况 |
更新服务器中玩家的XYZ位置. 如果头部Y减去脚底Y小于0.1或大于1.65,服务器会以“Illegal Stance”为理由踢出玩家. 如果新位置到旧位置(以服务器数据为准)的距离超过100个单位长度的话,玩家会被以"You moved too quickly :( (Hacking?)"为理由踢出. 此外,如果X或Z的定点数(即浮点数的尾数部分)大于3.2E7D的话,服务器也会以"Illegal position"为理由踢出玩家.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x04 | 游戏 | 服务器 | X | Double | 绝对坐标(即相对世界原点位置)X |
FeetY | Double | 玩家脚底的绝对坐标Y. 通常为头部Y坐标减1.62,用来修正玩家的碰撞盒 | |||
Z | Double | 绝对坐标Z | |||
On Ground | Bool | True为在地上或者在游泳,False为其他情况 |
更新玩家正在观察的方向.
Yaw(偏航,或叫偏角)代表物体围绕三维坐标中的Y轴旋转的角度(即左转右转),使用角度制,并且并不遵从传统的三角学规律. Yaw在XZ平面投影上的单位圆起始于(0,1),即0度时指向Z轴负方向. 绕Y轴逆时针旋转,即(-1,0)为90度,(0,-1)为180度,(1,0)为270度. 此外,Yaw不必被限制在0到360度,任何数,包括负数和大于360度的数,都是允许的.
Pitch(俯仰,或叫俯角)代表物体围绕三维坐标中的X轴旋转的角度(即上仰下伏),使用角度制,0代表向正前方看,-90代表朝正上方仰视裙底风光,90代表正在低头文明看腿.
对于一个站在点(x0,z0),观察点(x,z)的玩家的Yaw可以按如下伪代码的方法计算:
l = x-x0;
w = z-z0;
c = sqrt( l*l + w*w );
alpha1 = -arcsin(l/c)/PI*180
alpha2 = arccos(w/c)/PI*180
if alpha2 > 90 then
yaw = 180 - alpha1
else
yaw = alpha1
一组Yaw和Pitch可以被转化为单位向量:
x = -cos(pitch) * sin(yaw)
y = -sin(pitch)
z = cos(pitch) * cos(yaw)
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x05 | 游戏 | 服务器 | Yaw | Float | 围绕X轴的绝对旋转,角度制 |
Pitch | Float | 围绕Y轴的绝对旋转,角度制 | |||
On Ground | Bool | True为在地上或者在游泳,False为其他情况 |
同时结合了玩家位置和观察的数据包.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x06 | 游戏 | 服务器 | X | Double | 绝对坐标(即相对世界原点位置)X |
FeetY | Double | 玩家脚底的绝对坐标Y. 通常为头部Y坐标减1.62,用来修正玩家的碰撞盒 | |||
Z | Double | 绝对坐标Z | |||
Yaw | Float | 围绕X轴的绝对旋转,角度制 | |||
Pitch | Float | 围绕Y轴的绝对旋转,角度制 | |||
On Ground | Bool | True为在地上或者在游泳,False为其他情况 |
当玩家试图采集一个砖块时发送. 原版服务器只接受距离玩家6个单位距离以内的挖掘.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x07 | 游戏 | 服务器 | Status | Byte | 玩家当期挖掘的进度(见下表) |
Location | Position | 砖块坐标 | |||
Face | byte | 挖掘的面(见下表) |
目前Status有如下6种:
含义 | 值 |
---|---|
开始挖掘 | 0 |
取消挖掘 | 1 |
完成挖掘 | 2 |
丢下物品栈 | 3 |
丢下物品 | 4 |
射箭/完成进食 | 5 |
原版客户端会在开始敲一个砖块时发送0(开始挖掘),敲碎后发送2(完成挖掘). 如果挖掘中止,服务器会发送1(取消挖掘).
状态码4(丢下物品)是一个特例. 在游戏中,当你使用丢下物品指令(快捷键'q'),一个状态为4的挖掘数据包将发送向服务器,它的其余字段值均为0. 状态码3也类似,只不过丢下的是一整个物品栈.
状态码5(射箭/完成进食)也是个特例. X,Y,Z字段值均为0,face字段值为255.
Face代表敲击的砖块面,有如下6种值:
值 | 0 | 1 | 2 | 3 | 4 | 5 |
偏移 | -Y(下) | +y(上) | -Z(南) | +Z(北) | -X(西) | +x(东) |
在1.7.3中,如果玩家使用左键开门的话,服务器会收到一个0xE打开窗户和0x7玩家挖掘(状态值为"开始挖掘").
包标识符 | 类别 | 绑定到 | 字段名 | 字段类型 | 备注 |
---|---|---|---|---|---|
0x08 | 游戏 | 服务器 | Location | Position | 砖块坐标 |
Direction | Byte | 放置前,光标指向的砖块的面 | |||
Held item | Slot | 手上拿的物品 | |||
Cursor position X | Byte | 放置前,光标指在砖块上的相对位置(范围0.0~1.0,下同) | |||
Cursor position Y | Byte | ||||
Cursor position Z | Byte |
在普通操作中(比如放置砖块),这个数据包只发送一次,字段值也没有特殊变化.
但在特殊情况下,这个包的X,Y,Z值为-1,Direction为255,Cursor position都为0.0f. (如果你把Y当成无符号数的话,那它就是255.)这种包用来指明需要更新玩家手上的物品的状态,比如吃食物,拉弓,使用水桶等.
在原版的Beta客户端中,砖块或物品ID等于客户端中玩家拿着的物品,并且客户端会在每次玩家对着砖块表面按右键时都发送一次这个数据包,因此对于ID的安全性没有保证. 然而,原版的服务器端似乎会忽略客户端发来的ID,只采用服务器的数据. 在1.2.5和1.3.2中,客户端在一次回话中会发送真实物品ID和一个字段值为-1的数据包. (译注:在1.7.2中,服务器确实会在大多数情况下忽略客户端发来的ID,唯一一种用到客户端发来的物品ID的情况是在检查物品是否耗尽的时候. 至于那个字段值为-1的情况,还没有被观测到...)
另外,在使用水桶时,原版客户端可能会发送两个数据包:一个正常的放置砖块数据包,然后是一个特殊情况的放置砖块数据包. 它们会在你使用水桶的时候依次发送. 第一个不会起任何作用,真正执行舀水动作的是第二个数据包,取水的位置是在服务器端根据玩家的位置和朝向来测算的.
当玩家所持物品栏位发生改变时发送
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x09 | 游戏 | 服务器 | Slot | Short | 玩家选择的栏位(0-8) |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0A | 游戏 | 服务器 |
在蹲着,离开床或者跑的时候发送。客户端用0x28来发送动作。客户端将发送自己的动作ID = 3 when "Leave Bed"已点击。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0B | 游戏 | 服务器 | Entity ID | VarInt | 玩家ID |
Action ID | VarInt | 动作ID,见下表 | |||
Jump Boost | VarInt | 马跳加速,范围从0到100 |
动作ID可以为下列值:
ID | Action |
---|---|
0 | 蹲下 |
1 | 起立 |
2 | 离开床 |
3 | 开始冲刺 |
4 | 停止冲刺 |
5 | 骑马跳 |
6 | Open inventory |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0C | 游戏 | 服务器 | Sideways | Float | Positive to the left of the player |
Forward | Float | Positive forward | |||
Flags | Unsigned Byte | 0x1 上交通工具, 0x2 下交通工具 |
这个包会在客户端关闭一个窗口的时候发送。
注意,notchian客户端即使没有打开背包的信息时仍然发送一个关闭0号窗口的信息来关闭背包。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0D | 游戏 | 服务器 | Window id | byte | 要关闭的窗口的ID,0表示背包 |
这个包会在玩家点击窗口中的栏位时发送
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0E | 游戏 | 服务器 | Window ID | Byte | 所点击的窗口ID,0表示玩家背包 |
Slot | Short | 点击的栏位,见下文 | |||
Button | Byte | 所用来点击的键,见下文 | |||
Action number | Short | 这个动作的唯一数字,用来控制事物(见事物包) | |||
Mode | Byte | 背包操作模式,见下文 | |||
Clicked item | Slot |
请参阅背包窗口来获取更多关于栏位索引的信息 当右键点击一组物品时,一半将拿出另一半留在栏位中。如果这个栏位的物品数量为奇数,稍微少的那一部分将留在栏位中。
Action number实际上是一个计数器,从1开始计数,这个数字被服务端用来当作一个事物ID来回发事物包 客户端是通过”模式“和”按键“这两个字段来区分点击事件。
模式 | 按键 | 栏位 | 触发方式 |
---|---|---|---|
0 | 0 | Normal | 鼠标左键点击 |
1 | Normal | 鼠标右键点击 | |
1 | 0 | Normal | Shift+鼠标左键点击 |
1 | Normal | Shift+鼠标右键点击 | |
2 | 0 | Normal | 数字键1 |
1 | Normal | 数字键2 | |
2 | Normal | 数字键3 | |
... | ... | ... | |
8 | Normal | 数字键9 | |
3 | 2 | Normal | 鼠标中键 |
4 | 0 | Normal | 丢弃物品(Q) |
1 | Normal | Ctrl+丢弃物品(Q) | |
0 | -999 | 左键什么都不拿点击背包外(No-op) | |
1 | -999 | 右键什么都不拿点击背包外(No-op) | |
5 | 0 | -999 | 开始鼠标左键(或中键)拖拽 |
4 | -999 | 开始鼠标右键拖拽 | |
1 | Normal | 鼠标左键拖拽来增加栏位 | |
5 | Normal | 鼠标右键拖拽来增加栏位 | |
2 | -999 | 结束鼠标左键拖拽 | |
6 | -999 | 结束鼠标右键拖拽 | |
6 | 0 | Normal | 双击 |
从1.5版开始,”触屏模式“开始在背包窗口试用。它可以完成拿出一组物品(多于1),然后按住鼠标按键(左/右/中键)并且拖拽到空栏位(或和使用右键一样的方式)。在这情况下客户端会在松开鼠标后发出以下数据包(省略掉第一次拿出的包,它和平常拿出一样)
- 数据包模式 5, 栏位 -999 , 按键 (0 for left | 4 for right);
- 每个经过的栏位的数据包, 模式仍然为5, 按键 (1 | 5);
- 数据包模式 5, 栏位 -999, 按键 (2 | 6);
如果其他任何除了"progress"painting数据包发送一旦导致顺序混乱(例如, 一个开始, 几个栏位, 然后另一个开始; 或者左键点中间) the painting 状态将会被重置.
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x0F | 游戏 | 服务器 | Window ID | Byte | 发生操作的窗口ID |
Action number | Short | 每一个操作都有一个唯一数字,这个字段与这个数字有关 | |||
Accepted | Bool | 操作是否被接受 |
当处于创造模式的玩家在普通背包窗口(举例,不是工作台)的时候,服务端将会发送以下包:
- 是否有物品掉落到快速物品栏里
- 是否有物品从快速物品栏中捡起(物品ID为-1)
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x10 | 游戏 | 服务器 | Slot | Short | 背包栏位 |
Clicked item | Slot |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x11 | 游戏 | 服务器 | Window ID | Byte | 通过打开窗口发送 |
Enchantment | Byte | 附魔物品在附魔台窗口的位置,从0开始作为最高的一个 |
这消息客户端将在玩家点击木牌窗口内的”完成“按钮后发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x12 | 游戏 | 服务器 | Location | Position | 方块坐标 |
Line 1 | Chat | 牌子的第一行 | |||
Line 2 | Chat | 牌子的第二行 | |||
Line 3 | Chat | 牌子的第三行 | |||
Line 4 | Chat | 牌子的第四行 |
后面的两个浮点数是用来分别表示玩家走路/飞行速度的, 第一个字节用来表示四个布尔值。
这些标记有玩家是否可以受到伤害 (god mode, 8, bit 3), 玩家是否可以飞行 (4, bit 2), 玩家是否在飞 (2, bit 1),以及玩家是否处于创造模式 (1, bit 0).
如需计算这些布尔值, simply AND (&) the byte with 1,2,4 and 8 respectively, to get the 0 or 1 bitwise value. To set them OR (|) them with their repspective masks. 原版服务端会在玩家开始/停止飞行并且第二个参数也跟着改变。所有其他参数会被原版服务端无视。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x13 | 游戏 | 服务器 | Flags | Byte | |
Flying speed | Float | 过去的整数值除以250 | |||
Walking speed | Float | 过去的整数值除以250 |
当用户在输入文本时按下[tab]键时发送。有效负载包括光标后所有的文本。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x14 | 游戏 | 服务器 | Text | String | |
Has Position | Boolean | ||||
Looked at block | Position | 所看的方块,只会在上一项为true时发送 |
当游戏连接或者更改游戏设置时发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x15 | 游戏 | 服务器 | Locale | String | en_GB |
View distance | Byte | 客户端渲染距离(区块) | |||
Chat flags | Byte | 聊天设置,见下文 | |||
Chat colours | Bool | 多人设置中“颜色”设置 | |||
Displayed skin parts | Unsigned Byte | 皮肤部分,见下文 |
聊天标记有许多值标记为一个字节。 开启聊天: 字节0-1.00:开启,01:仅命令,10:隐藏。 皮肤显示也同样将许多值标记为一个字节。 Bit 0: 披风开启 Bit 1: 衣物开启 Bit 2: 左袖开启 Bit 3: 右袖开启 Bit 4: 左裤腿开启 Bit 5: 右裤腿开启 Bit 6: 帽子开启 最显著的字节(bit 7)未被使用。
在客户端已经完成连接以及死亡准备复活时发送。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x16 | 游戏 | 服务器 | Action ID | VarInt | 见下文 |
动作ID值:
动作ID | 名称 |
---|---|
0 | 执行复活 |
1 | 请求状态 |
2 | 打开背包成就 |
Mod和插件可以用它来发送它们自己的数据。Minecraft自身使用一系列plugin channels。这些内部频道都前置于MC|.
更多信息可见此:http://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/
请注意数据长度是由数据包长度的值得,所以没必要发送长度件。
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x17 | 游戏 | 服务器 | Channel | String | 所需要用于发送数据的“频道” |
Data | Byte Array | 任意数据 |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x18 | 游戏 | 服务器 | Target Player | UUID |
包标识符 | 类别 | 绑定到 | 字段名 | 字段类别 | 备注 |
---|---|---|---|---|---|
0x19 | 游戏 | 服务器 |
Hash | String | 资源包发送包发送的哈希值 |
Result | VarInt | 成功载入: 0, 拒绝: 1, 下载失败: 2, 接受: 3 |
客户端向服务器进行ping的流程如下:
(C:客户端 S:服务器)
C->S : 握手,"Next state"值为1
C->S : 请求
S->C : 响应
C->S : Ping
S->C : Ping
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x00 | 状态 | 客户端 | JSON Response | String |
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x01 | 状态 | 客户端 | Time | Long | 应当和客户端发往服务器的Ping的Time数值相同 |
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x00 | 状态 | 服务器 |
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x01 | 状态 | 服务器 | Time | Long | 客户端发送Ping数据包时的时间戳 |
登陆流程如下:
(C:客户端 S:服务器)
C->S : 握手,"Next state"值为2
C->S : 登录开始
S->C : 请求加密
(客户端认证)
C->S : 响应加密
(服务器认证, 双方开始启用数据包加密)
S->C : 登陆成功
对于不启用认证的服务器,或客户端连接来自本地的话,服务器会放弃使用数据包加密,登录流程也会跳过请求和响应加密这两个步骤.
(不启用认证的服务器有两种:在游戏内开的局域网服务器;online-mode为false的独立服务器.)
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x00 | 登录 | 客户端 | JSON Data | String |
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x01 | 登录 | 客户端 | Server ID | String | 从1.7开始已废除,内容为空. |
Length | VarInt | 公钥的长度 | |||
Public Key | Byte array | 公钥,公钥在每次服务器启动时生成一个. | |||
Length | VarInt | 令牌的长度 | |||
Verify Token | Byte array | 认证令牌,令牌可以被视为一个4字节的随机整形数.每次握手完毕后都会为本次连接随机生成一个. |
关于协议加密的详细信息可以见此.
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x02 | 登录 | 客户端 | UUID | String | |
Username | String |
数据包压缩是Minecraft1.8开始引入的东西.
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x03 | 登录 | 客户端 | Threshold | VarInt | 阀值. 数据包的总字节数(数据包ID+数据,不包括数据包长度)小于此阀值的数据包将不被压缩.
|
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x00 | 登陆 | 服务器 | Name | String | 玩家姓名 |
数据包ID | 类别 | 接收者 | 字段名 | 类型 | 备注 |
---|---|---|---|---|---|
0x01 | 登录 | 服务器 | Length | VarInt | 密钥的长度 |
Shared Secret | Byte array | 密钥,此处的密钥已被公钥加密. | |||
Length | VarInt | 令牌的长度 | |||
Verify Token | Byte array | 认证令牌,此处的认领令牌由之前客户端收到的令牌和公钥加密而成. |
关于协议加密的详细信息可以见此.