Skip to content

协议数据包 ​

处理聊天消息 ​

proton.py 已经注册了 TextPacket(0x09) 的内核协议事件,解析后触发 OnTextPacket 用户事件,插件直接监听即可:

python
def on_text(args):
    data = args[0]                    # dict
    if data['type'] == 1:             # CHAT
        source = data['source_name']  # str(Unicode)
        msg = data['message']         # str(Unicode)
        print(f'<{source}> {msg}')    # Py3 f-string,中文直接打印

engine.register(on_text, "OnTextPacket")

Py3 下不要 decode

source_name / message 已经是 str,不要再调用 .decode('utf-8') (str 根本没有这个方法)。

data 的完整字段和 type 取值见事件系统 · OnTextPacket。

处理其他数据包 ​

用 engine.register_protocol_event(packet_id, cb, False) 注册;回调收到的 data 是原始二进制(bytes,包 ID 已去除):

python
import pkt

def on_move_player(data):
    runtime_id, off = pkt.read_varint(data, 0)
    x, y, z, off = pkt.unpack("fff", data, off)
    print(f'entity {runtime_id} moved to {x:.1f}, {y:.1f}, {z:.1f}')

# 第三个参数 False = 用户协议事件,重载时自动清除
engine.register_protocol_event(0x13, on_move_player, False)

第三个参数必须是 False

True 是内核协议事件,只有 proton.py 可以用。插件传 True 会破坏框架自己的注册。

不用手写解析器:结构化协议事件 ​

如果只是想拿字段,不必自己 pkt.unpack。以下包已经支持结构化解析, engine.register_structured_protocol_event(id, cb) 会直接给 dict:

MovePlayer、ContainerOpen、InventoryContent、BlockActorData、 PlayStatus、Text、CommandOutput、PlayerList

python
def on_packet(event):
    if event["parsed"]:
        print(event["packet_name"], event["data"])

engine.register_structured_protocol_event(56, on_packet)

字段说明见结构化协议事件。

该用哪个? ​

场景用
聊天 / 系统消息OnTextPacket(已解析好)
上表那 8 个包register_structured_protocol_event(拿 dict)
其他包 / 需要原始字节register_protocol_event + pkt 手工解析
指令返回on_command_output 事件(配合 engine.command_guid)

常用包 ID ​

包ID
TextPacket0x09
MovePlayer0x13
ContainerOpenPacket46
InventoryContentPacket49
BlockActorDataPacket56
CommandBlockUpdate78

下一步 ​

第三方库请参阅各自目录下的许可证文件