这是有关Minecraft Classic创造服务器使用的服务器协议的文档。
Minecraft.net交流[]
心跳[]
为了能从服务器列表连接到Minecraft Classic中的服务器,服务器必须每隔几分钟向minecraft.net广播一个所谓的“心跳”。
库存服务器会每隔45秒广播一次心跳。
“心跳”使用了对https://minecraft.net/heartbeat.jsp发送HTTP请求的形式。发送心跳后,将返回服务器的URL。
成功心跳的关键是你应该在HTTP请求中省略“www”,因为你要将它定位为URI,而不是URL。
它可以是GET或POST请求。下面表格是所需要的参数:
Name | Details |
---|---|
port | 服务器的端口号,通常为25565 |
max | 服务器上的最大玩家数量 |
name | 服务器的名称 |
public | 该服务器是否为公有(即出现在游戏大厅中)。可以为True(是)或False(否),大小写敏感 |
version | Minecraft的版本,应该是7 |
salt | 以Base-62编码的16个字符的随机盐 |
users | 连接到服务器的用户数量 |
简单的方式是发送一个心跳到minecraft.net上端口为80的TCP接口,会发送以下的内容(注意修改对应的内容):
GET /heartbeat.jsp?port=25565&max=32&name=My%20Server&public=True&version=7&salt=wo6kVAHjxoJcInKx&users=0加上回车换行符。
确保字符串,如名称,是已经转义的。
如果一切顺利,在回应里你会收到一个发送给服务器的URL。否则你会收到一个很棒的HTML错误信息。 不需要处理HTML头部,由于未指定版本因此使用缺省的 HTTP/0.9 协议,而该协议不含头部。
用户认证[]
可以将用户加入服务器时提供的“密钥”与服务器的MD5校验以及用户名进行比较,以验证用户是否使用该用户名登录了minecraft.net。 这对于建立足够信任的名称以按名称禁止玩家加入或赋予玩家管理员权限很有用。
if( player.key == md5( server.salt + player.name ) ) { // 玩家通过minecraft.net登录 } else { // 玩家伪造用户名 }
这也是Notch避免“破解版”或是盗版客户端进入在线服务器的原理。当破解版客户端尝试连接至在线服务器时,连接屏幕上会出现一个错误:“Failed to Connect: User Not Premium”(未能连接:用户未购买)
注意:这意味着你应当确保你的“盐”是私密的,且仅与heartbeat.jsp共享。如果你的服务器的“盐”对其他用户可见,那么其他用户能很容易地在不登入minecraft.net的情况下制造看上去有效的“密钥”。
数据包协议[]
每个包都以表示其ID的字节开始。
协议数据类型[]
类型 | 大小(字节) | 描述 |
---|---|---|
字节(Byte) | 1 | 单字节整型 (0 - 255) |
带符号字节(SByte) | 1 | 单字节有符号整型 (-128 - 127) |
短整型(Short) | 2 | 以网络字节序表示的有符号整型 (-32768 - 32767) |
字符串(String) | 64 | 按US-ASCII/ISO646-US标准编码的以空格(0x20)填充的字符串 |
字节数组(Byte array) | 1024 | 以空字节(0x00)填充的二进制数据 |
客户端→服务端数据包[]
包ID | 目的 | 域描述 | 域类型 | 备注 |
---|---|---|---|---|
0x00 | 玩家认证 | 包ID | 字节 | 由加入服务器的玩家发送,带有相关信息。协议版本为0x07。 |
协议版本 | 字节 | |||
用户名 | 字符串 | |||
验证密钥 | 字符串 | |||
未使用 | 字节 | |||
0x05 | 设置方块 | 包ID | 字节 | 发送于玩家改变某个方块时。“模式”域表明玩家是创造(0x01)还是摧毁(0x00)方块。
“方块类型”域总是玩家手持的方块,即使是摧毁方块时。 客户端假定这种命令包总是成功,因此会立刻绘制新方块。欲阻止创造方块,服务端必须向客户端发送带有旧方块类型的“设置方块”包。 XYZ坐标是代表方块坐标的整数,而非代表玩家坐标的定点数(其低五位为小数坐标)。 |
X | 短整型 | |||
Y | 短整型 | |||
Z | 短整型 | |||
模式 | 字节 | |||
方块类型 | 字节 | |||
0x08 | 位置与朝向 | 包ID | 字节 | 由玩家频繁发送(即使并未移动),包含玩家当前的位置及朝向。“玩家ID”域总是255,表示玩家自己。玩家坐标是一个定点数,其低五位表示小数坐标(即除以32才能得到等效于方块坐标的实际坐标)。角参数按360度等比例缩小为256单位。 |
玩家ID | 字节 | |||
X | 短整型 | |||
Y | 短整型 | |||
Z | 短整型 | |||
偏航角(朝向) | 字节 | |||
俯仰角 | 字节 | |||
0x0d | 消息 | 包ID | 字节 | 包含由玩家发送的消息 |
未使用,可能为消息颜色 | 字节(总是0xFF) | |||
消息 | 字符串 |
服务端→客户端数据包[]
包ID | 目的 | 域描述 | 域类型 | 备注 |
---|---|---|---|---|
0x00 | 服务端认证 | 包ID | 字节 | 回应加入的玩家。用户类型表明玩家是服务器管理员(0x64)或是普通玩家(0x00)。当前的协议版本为0x07。 |
协议版本 | 字节 | |||
服务器名 | 字符串 | |||
服务器每日消息 | 字符串 | |||
用户类型 | 字节 | |||
0x01 | 连通测试 | 包ID | 字节 | 周期性地发送至客户端。此时客户端唯一断开连接的方式就是强制其关闭,这种方式不会通知服务器。这种包用于判断连接是否正常。 |
0x02 | 关卡初始化 | 包ID | 字节 | 通知玩家服务器将发送关卡数据。 |
0x03 | 关卡数据块 | 包ID | 字节 | 包含通过Gzip算法压缩的地图数据块(并非level.dat文件)解压缩后,该地图包含一个四字节整数和原始地图数组。整数代表所含方块数目。(单个数据块最多含有1024字节,如果数据不足,则由0x00填充) |
数据块长度 | 短整型 | |||
数据块 | 字节数组 | |||
完成百分数 | 字节 | |||
0x04 | 关卡完成 | 包ID | 字节 | 关卡数据传输完成后发送,同时给出地图的长宽高。Y坐标为地图高度。 |
X轴大小 | 短整型 | |||
Y轴大小 | 短整型 | |||
Z轴大小 | 短整型 | |||
0x06 | 设置方块 | 包ID | 字节 | 方块因游戏物理或玩家而改变时发送。如果是因玩家而改变,服务器也会将方块变动发送回导致改变的玩家。 |
X | 短整型 | |||
Y | 短整型 | |||
Z | 短整型 | |||
方块类型 | 字节 | |||
0x07 | 生成玩家 | 包ID | 字节 | 用于指定新玩家生成于世界中的位置。位置和朝向的编码方式同下述包0x08。 |
玩家ID | 带符号字节 | |||
玩家名 | 字符串 | |||
X | 短整型 | |||
Y | 短整型 | |||
Z | 短整型 | |||
偏航角(朝向) | 字节 | |||
俯仰角 | 字节 | |||
0x08 | 位置与朝向(玩家传送) | 包ID | 字节 | 带有玩家位置与朝向改变的信息。如果玩家ID<0,则将玩家传送至指定位置。(用于设定地图中的初始位置,或是使用/tp命令) |
玩家ID | 带符号字节 | |||
X | 短整型 | |||
Y | 短整型 | |||
Z | 短整型 | |||
偏航角(朝向) | 字节 | |||
俯仰角 | 字节 | |||
0x09 | 位置与朝向更新 | 包ID | 字节 | 发送于玩家位置与朝向改变时。仅当玩家的位置与朝向同时变化时才发送。
对服务器运行并非必要。 |
玩家ID | 带符号字节 | |||
X变化量 | 带符号字节 | |||
Y变化量 | 带符号字节 | |||
Z变化量 | 带符号字节 | |||
偏航角(朝向) | 字节 | |||
俯仰角 | 字节 | |||
0x0a | 位置更新 | 包ID | 字节 | 带有玩家位置变化的信息。
对服务器运行并非必要。 |
玩家ID | 带符号字节 | |||
X变化量 | 带符号字节 | |||
Y变化量 | 带符号字节 | |||
Z变化量 | 带符号字节 | |||
0x0b | 朝向更新 | 包ID | 字节 | 带有玩家朝向更新的信息。
对服务器运行并非必要。 |
玩家ID | 带符号字节 | |||
偏航角(朝向) | 字节 | |||
俯仰角 | 字节 | |||
0x0c | 玩家清除 | 包ID | 字节 | 玩家断开连接时发送。 |
玩家ID | 带符号字节 | |||
0x0d | 消息 | 包ID | 字节 | 由聊天或控制台发送的消息。 |
玩家ID | 带符号字节 | |||
消息 | 字符串 | |||
0x0e | 玩家断开连接 | 包ID | 字节 | 发送至被服务器断开连接的玩家。
|
断开连接原因 | 字符串 | |||
0x0f | 更新用户类型 | 包ID | 字节 | 发送于玩家被设置或取消管理员身份时。
赋予或撤销玩家破坏基岩方块的能力。
|
玩家类型 | 字节 |
玩家位置[]
固定点[]
玩家的位置通过X、Y和Z定点坐标来表示。小数部分是5位,所以将位置更新包中接收到的短整数除以32,你将得到玩家的浮点坐标。该位置对应于客户端视口的中心。
站在东西上[]
玩家的脚底位于其视点下方1.59375(转换为数据包使用的定点小数为51)单位处,因此,为了让玩家站在某个方块之上,应当发送Y坐标指定为Y×32 + 51的传送(0x08)数据包。
朝向[]
偏航角为0表明玩家面向Z-(负Z轴)方向。从上向下看,该数值向顺时针方向增大。如果将负Z轴方向称为北方,那么偏航角为64为东方,128为南方,192为西方。
俯仰角0表示水平,且该数值向下增大。64为正下方,192为正上。65至191之间的数字不应当出现,因为玩家不可能在64 → 0和255 → 192范围之外继续向上或是向下看。然而,Minecraft Classic客户端并不会忽略无效的数值,因此有可能让玩家的头“上下颠倒”。
颜色代码[]
从客户端发送的消息可以包含颜色代码,这使得文字可以染色以用于多种用途。
消息中的与符号(&)和其后的一位十六进制数字告知客户端显示该消息的颜色。当前版本的游戏使用小节符(§),而0.30版本使用和符号。关于现在游戏版本中的样式代码,请参见样式代码。
以颜色代码开头的信息只会在玩家ID字节数小于127时生效。如果是玩家ID字节数是127或更高,游戏会自动的在信息前面加 &e ,让信息变成黄色。 然而,在第一个字符后面的颜色代码仍然可用。 如果你使用的ID字节数低于127,不会添加一个颜色代码,所以,如果你使用这些颜色代码中的一个,它们仍然有效。
示例 | 代码 | 通用名 | 别称 | 前景色 | 背景色 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
R | G | B | HEX | R | G | B | HEX | ||||
&0 | 黑色 | 黑色 | 0 | 0 | 0 | #000 | 0 | 0 | 0 | #000000 | |
&1 | 深蓝色 | 海军蓝 | 0 | 0 | 170 | #00A | 0 | 0 | 42 | #00002A | |
&2 | 深绿色 | 绿色 | 0 | 170 | 0 | #0A0 | 0 | 42 | 0 | #002A00 | |
&3 | 蓝绿色 | 蓝绿色 | 0 | 170 | 170 | #0AA | 0 | 42 | 42 | #002A2A | |
&4 | 深红色 | 褐红色 | 170 | 0 | 0 | #A00 | 42 | 0 | 0 | #2A0000 | |
&5 | 紫色 | 紫色 | 170 | 0 | 170 | #A0A | 42 | 0 | 42 | #2A002A | |
&6 | 深黄色 | 金黄色 | 170 | 170 | 0 | #AA0 | 42 | 42 | 0 | #2A2A00 | |
&7 | 灰色 | 银色 | 170 | 170 | 170 | #AAA | 42 | 42 | 42 | #2A2A2A | |
&8 | 深灰色 | 灰色 | 85 | 85 | 85 | #555 | 21 | 21 | 21 | #151515 | |
&9 | 靛青色 | 蓝色 | 85 | 85 | 255 | #55F | 21 | 21 | 63 | #15153F | |
&a | 浅绿色 | 柠檬色 | 85 | 255 | 85 | #5F5 | 21 | 63 | 21 | #153F15 | |
&b | 青色 | 水蓝色 | 85 | 255 | 255 | #5FF | 21 | 63 | 63 | #153F3F | |
&c | 红色 | 红色 | 255 | 85 | 85 | #F55 | 63 | 21 | 21 | #3F1515 | |
&d | 粉色 | 粉色 | 255 | 85 | 255 | #F5F | 63 | 21 | 63 | #3F153F | |
&e | 黄色 | 黄色 | 255 | 255 | 85 | #FF5 | 63 | 63 | 21 | #3F3F15 | |
&f | 白色 | 白色 | 255 | 255 | 255 | #FFF | 63 | 63 | 63 | #3F3F3F |
版本 | |||||||
---|---|---|---|---|---|---|---|
开发周期 |
| ||||||
技术 |
| ||||||
多人游戏 | |||||||
游戏订制 |
语言