From fc9f20fa93feda926a5d12a4f2aa9eb9c6017f3a Mon Sep 17 00:00:00 2001 From: extremeheat Date: Mon, 9 Aug 2021 00:39:07 +0000 Subject: [PATCH 1/3] update bedrock protocol data --- data/bedrock/1.17.10/protocol.json | 2 +- data/bedrock/latest/proto.yml | 3171 ++++++++++++++++++++++++++++ data/bedrock/latest/types.yml | 1703 +++++++++++++++ tools/js/compileProtocol.js | 60 + tools/js/package.json | 6 +- 5 files changed, 4939 insertions(+), 3 deletions(-) create mode 100644 data/bedrock/latest/proto.yml create mode 100644 data/bedrock/latest/types.yml create mode 100644 tools/js/compileProtocol.js diff --git a/data/bedrock/1.17.10/protocol.json b/data/bedrock/1.17.10/protocol.json index c9949421f..21d4facae 100644 --- a/data/bedrock/1.17.10/protocol.json +++ b/data/bedrock/1.17.10/protocol.json @@ -8752,7 +8752,7 @@ "type": [ "mapper", { - "type": "li32", + "type": "varint", "mappings": { "0": "open", "1": "close" diff --git a/data/bedrock/latest/proto.yml b/data/bedrock/latest/proto.yml new file mode 100644 index 000000000..d2998d140 --- /dev/null +++ b/data/bedrock/latest/proto.yml @@ -0,0 +1,3171 @@ +# Created from MiNET and gophertunnel docs +# The version below is the latest version this protocol schema was updated for. +# The output protocol.json will be in the folder for the version +!version: 1.17.10 + +# Some ProtoDef aliases +string: ["pstring",{"countType":"varint"}] # String / array types +ByteArray: ["buffer",{"countType":"varint"}] +SignedByteArray: ["buffer",{"countType":"zigzag32"}] +LittleString: ["pstring",{"countType":"li32"}] +ShortArray: ["buffer",{"countType":"li16"}] +varint64: native # Some primitives +zigzag32: native +zigzag64: native +uuid: native # Data types & special handling +byterot: native +bitflags: native +restBuffer: native +encapsulated: native +nbt: native # NBT +lnbt: native +nbtLoop: native +enum_size_based_on_values_len: native # Packet-specific custom logic +MapInfo: native + +# load the packet map file (auto-generated) +!import: packet_map.yml + +!StartDocs: Packets + +# # Login Sequence +# The login process is as follows: +# +# * C→S: [Login](#packet_login) +# * S→C: [Server To Client Handshake](#packet_server_to_client_handshake) +# * C→S: [Client To Server Handshake](#packet_client_to_server_handshake) +# * S→C: [Play Status (Login success)](#packet_play_status) +# * To spawn, the following packets should be sent, in order, after the ones above: +# * S→C: [Resource Packs Info](#packet_resource_packs_info) +# * C→S: [Resource Pack Client Response](#packet_resource_pack_client_response) +# * S→C: [Resource Pack Stack](#packet_resource_pack_stack) +# * C→S: [Resource Pack Client Response](#packet_resource_pack_client_response) +# * S→C: [Start Game](#packet_start_game) +# * S→C: [Creative Content](#packet_creative_content) +# * S→C: [Biome Definition List](#packet_biome_definition_list) +# * S→C: [Chunks](#packet_level_chunk) +# * S→C: [Play Status (Player spawn)](#packet_play_status) +# +# If there are no resource packs being sent, a Resource Pack Stack can be sent directly +# after Resource Packs Info to avoid the client responses. +# +# === + +packet_login: + !id: 0x01 + !bound: server + # Protocol version (Big Endian!) + protocol_version: i32 + tokens: '["encapsulated", { "lengthType": "varint", "type": "LoginTokens" }]' + +LoginTokens: + # JSON array of JWT data: contains the display name, UUID and XUID + # It should be signed by the Mojang public key + identity: LittleString + # Skin related data + client: LittleString + +packet_play_status: + !id: 0x02 + !bound: client + status: i32 => + # Sent after Login has been successfully decoded and the player has logged in + 0: login_success + # Displays "Could not connect: Outdated client!" + 1: failed_client + # Displays "Could not connect: Outdated server!" + 2: failed_spawn + # Sent after world data to spawn the player + 3: player_spawn + # Displays "Unable to connect to world. Your school does not have access to this server." + 4: failed_invalid_tenant + # Displays "The server is not running Minecraft: Education Edition. Failed to connect." + 5: failed_vanilla_edu + # Displays "The server is running an incompatible edition of Minecraft. Failed to connect." + 6: failed_edu_vanilla + # Displays "Wow this server is popular! Check back later to see if space opens up. Server Full" + 7: failed_server_full + + +packet_server_to_client_handshake: + !id: 0x03 + !bound: client + # Contains the salt to complete the Diffie-Hellman key exchange + token: string + + +# Sent by the client in response to a Server To Client Handshake packet +# sent by the server. It is the first encrypted packet in the login handshake +# and serves as a confirmation that encryption is correctly initialized client side. +# It has no fields. +packet_client_to_server_handshake: + !id: 0x04 + !bound: server + +# Sent by the server to disconnect a client. +packet_disconnect: + !id: 0x05 + !bound: client + # Specifies if the disconnection screen should be hidden when the client is disconnected, + # meaning it will be sent directly to the main menu. + hide_disconnect_reason: bool + # An optional message to show when disconnected. + message: string + + +packet_resource_packs_info: + !id: 0x06 + !bound: client + # If the resource pack requires the client accept it. + must_accept: bool + # If scripting is enabled. + has_scripts: bool + # ForcingServerPacks is currently an unclear field. + force_server_packs: bool + # A list of behaviour packs that the client needs to download before joining the server. + # All of these behaviour packs will be applied together. + behaviour_packs: BehaviourPackInfos + # A list of resource packs that the client needs to download before joining the server. + # The order of these resource packs is not relevant in this packet. It is however important in the Resource Pack Stack packet. + texture_packs: TexturePackInfos + +packet_resource_pack_stack: + !id: 0x07 + !bound: client + # If the resource pack must be accepted for the player to join the server. + must_accept: bool + # [inline] + behavior_packs: ResourcePackIdVersions + # [inline] + resource_packs: ResourcePackIdVersions + game_version: string + experiments: Experiments # ??? such random fields + experiments_previously_used: bool + +packet_resource_pack_client_response: + !id: 0x08 + !bound: server + response_status: u8 => + 0: none + 1: refused + 2: send_packs + 3: have_all_packs + 4: completed + # All of the pack IDs. + resourcepackids: ResourcePackIds + +# Sent by the client to the server to send chat messages, and by the server to the client +# to forward or send messages, which may be chat, popups, tips etc. +## https://github.com/pmmp/PocketMine-MP/blob/a43b46a93cb127f037c879b5d8c29cda251dd60c/src/pocketmine/network/mcpe/protocol/TextPacket.php +## https://github.com/Sandertv/gophertunnel/blob/05ac3f843dd60d48b9ca0ab275cda8d9e85d8c43/minecraft/protocol/packet/text.go +packet_text: + !id: 0x09 + !bound: both + # TextType is the type of the text sent. When a client sends this to the server, it should always be + # TextTypeChat. If the server sends it, it may be one of the other text types above. + type: u8 => + 0: raw + 1: chat + 2: translation + 3: popup + 4: jukebox_popup + 5: tip + 6: system + 7: whisper + 8: announcement + 9: json_whisper + 10: json + # NeedsTranslation specifies if any of the messages need to be translated. It seems that where % is found + # in translatable text types, these are translated regardless of this bool. Translatable text types + # include TextTypeTip, TextTypePopup and TextTypeJukeboxPopup. + needs_translation: bool + _: type? + if chat or whisper or announcement: + source_name: string + message: string + if raw or tip or system or json_whisper or json: + message: string + if translation or popup or jukebox_popup: + message: string + paramaters: string[]varint + # The XUID of the player who sent this message. + xuid: string + # PlatformChatID is an identifier only set for particular platforms when chatting (presumably only for + # Nintendo Switch). It is otherwise an empty string, and is used to decide which players are able to + # chat with each other. + platform_chat_id: string +# For additional information and examples of all the chat types above, see here: https://imgur.com/a/KhcFscg + + +# Sent by the server to update the current time client-side. The client actually advances time +# client-side by itself, so this packet does not need to be sent each tick. It is merely a means +# of synchronizing time between server and client. +packet_set_time: + !id: 0x0a + !bound: client + # Time is the current time. The time is not limited to 24000 (time of day), but continues + # progressing after that. + time: zigzag32 + +# Sent by the server to send information about the world the player will be spawned in. +packet_start_game: + !id: 0x0b + !bound: client + # The unique ID of the player. The unique ID is a value that remains consistent across + # different sessions of the same world, but most unofficial servers simply fill the + # runtime ID of the entity out for this field. + entity_id: zigzag64 + # The runtime ID of the player. The runtime ID is unique for each world session, + # and entities are generally identified in packets using this runtime ID. + runtime_entity_id: varint64 + # PlayerGameMode is the game mode the player currently has. It is a value from 0-4, with 0 being + # survival mode, 1 being creative mode, 2 being adventure mode, 3 being survival spectator and 4 being + # creative spectator. + # This field may be set to 5 to make the client fall back to the game mode set in the WorldGameMode + # field. + player_gamemode: GameMode + # The spawn position of the player in the world. In servers this is often the same as the + # world's spawn position found below. + player_position: vec3f + # The pitch and yaw of the player + rotation: vec2f + # The seed used to generate the world. Unlike in Java edition, the seed is a 32bit Integer here. + seed: zigzag32 + biome_type: li16 + biome_name: string + # Dimension is the ID of the dimension that the player spawns in. It is a value from 0-2, + # with 0 being the overworld, 1 being the nether and 2 being the end. + dimension: zigzag32 + # Generator is the generator used for the world. It is a value from 0-4, with 0 being old + # limited worlds, 1 being infinite worlds, 2 being flat worlds, 3 being nether worlds and + # 4 being end worlds. A value of 0 will actually make the client stop rendering chunks you + # send beyond the world limit. + generator: zigzag32 + # The world game mode that a player gets when it first spawns in the world. It is shown in the + # settings and is used if the Player Gamemode is set to 5. + world_gamemode: GameMode + # Difficulty is the difficulty of the world. It is a value from 0-3, with 0 being peaceful, + # 1 being easy, 2 being normal and 3 being hard. + difficulty: zigzag32 + # The block on which the world spawn of the world. This coordinate has no effect on the place + # that the client spawns, but it does have an effect on the direction that a compass poInts. + spawn_position: BlockCoordinates + # Defines if achievements are disabled in the world. The client crashes if this value is set + # to true while the player's or the world's game mode is creative, and it's recommended to simply + # always set this to false as a server. + achievements_disabled: bool + # The time at which the day cycle was locked if the day cycle is disabled using the respective + # game rule. The client will maIntain this time as Boolean as the day cycle is disabled. + day_cycle_stop_time: zigzag32 + # Some Minecraft: Education Edition field that specifies what 'region' the world was from, + # with 0 being None, 1 being RestOfWorld, and 2 being China. The actual use of this field is unknown. + edu_offer: zigzag32 + # Specifies if the world has education edition features enabled, such as the blocks or entities + # specific to education edition. + edu_features_enabled: bool + edu_product_uuid: string + # The level specifying the Intensity of the rain falling. When set to 0, no rain falls at all. + rain_level: lf32 + lightning_level: lf32 + # The level specifying the Intensity of the thunder. This may actually be set independently + # from the rain level, meaning dark clouds can be produced without rain. + has_confirmed_platform_locked_content: bool + # Specifies if the world is a multi-player game. This should always be set to true for servers. + is_multiplayer: bool + # Specifies if LAN broadcast was Intended to be enabled for the world. + broadcast_to_lan: bool + # The mode used to broadcast the joined game across XBOX Live. + xbox_live_broadcast_mode: varint + # The mode used to broadcast the joined game across the platform. + platform_broadcast_mode: varint + # If commands are enabled for the player. It is recommended to always set this to true on the + # server, as setting it to false means the player cannot, under any circumstance, use a command. + enable_commands: bool + # Specifies if the texture pack the world might hold is required, meaning the client was + # forced to download it before joining. + is_texturepacks_required: bool + # Defines game rules currently active with their respective values. The value of these game + # rules may be either 'bool', 'Int32' or 'Float32'. Some game rules are server side only, + # and don't necessarily need to be sent to the client. + gamerules: GameRules + experiments: Experiments + experiments_previously_used: bool + # Specifies if the world had the bonus map setting enabled when generating it. + # It does not have any effect client-side. + bonus_chest: bool + # Specifies if the world has the start with map setting enabled, meaning each + # joining player obtains a map. This should always be set to false, because the + # client obtains a map all on its own accord if this is set to true. + map_enabled: bool + # The permission level of the player. It is a value from 0-3, with 0 being visitor, + # 1 being member, 2 being operator and 3 being custom. + permission_level: zigzag32 + # The radius around the player in which chunks are ticked. Most servers set this value + # to a fixed number, as it does not necessarily affect anything client-side. + server_chunk_tick_range: li32 + # Specifies if the texture pack of the world is locked, meaning it cannot be disabled + # from the world. This is typically set for worlds on the marketplace that have a dedicated + # texture pack. + has_locked_behavior_pack: bool + # Specifies if the texture pack of the world is locked, meaning it cannot be disabled from the + # world. This is typically set for worlds on the marketplace that have a dedicated texture pack. + has_locked_resource_pack: bool + # Specifies if the world from the server was from a locked world template. + # For servers this should always be set to false. + is_from_locked_world_template: bool + msa_gamertags_only: bool + # Specifies if the world from the server was from a locked world template. + # For servers this should always be set to false. + is_from_world_template: bool + # Specifies if the world was a template that locks all settings that change properties + # above in the settings GUI. It is recommended to set this to true for servers that + # do not allow things such as setting game rules through the GUI. + is_world_template_option_locked: bool + # A hack that Mojang put in place to preserve backwards compatibility with old villagers. + # The his never actually read though, so it has no functionality. + only_spawn_v1_villagers: bool + # The version of the game from which Vanilla features will be used. + # The exact function of this field isn't clear. + game_version: string + limited_world_width: li32 + limited_world_length: li32 + is_new_nether: bool + experimental_gameplay_override: bool + # A base64 encoded world ID that is used to identify the world. + level_id: string + # The name of the world that the player is joining. Note that this field shows up + # above the player list for the rest of the game session, and cannot be changed. + # Setting the server name to this field is recommended. + world_name: string + # A UUID specific to the premium world template that might have been used to + # generate the world. Servers should always fill out an empty String for this. + premium_world_template_id: string + # Specifies if the world was a trial world, meaning features are limited and there + # is a time limit on the world. + is_trial: bool + + # MovementType specifies the way the server handles player movement. Available options are + # packet.AuthoritativeMovementModeClient, packet.AuthoritativeMovementModeServer and + # packet.AuthoritativeMovementModeServerWithRewind, where server the server authoritative types result + # in the client sending PlayerAuthInput packets instead of MovePlayer packets and the rewind mode + # requires sending the tick of movement and several actions. + # + # Specifies if the client or server is authoritative over the movement of the player, + # meaning it controls the movement of it. + ## https://github.com/pmmp/PocketMine-MP/blob/a43b46a93cb127f037c879b5d8c29cda251dd60c/src/pocketmine/network/mcpe/protocol/types/PlayerMovementType.php#L26 + movement_authority: zigzag32 => + 0: client + 1: server + # PlayerAuthInputPacket + a bunch of junk that solves a nonexisting problem + 2: server_with_rewind + # RewindHistorySize is the amount of history to keep at maximum if MovementType is + # packet.AuthoritativeMovementModeServerWithRewind. + rewind_history_size: zigzag32 + # ServerAuthoritativeBlockBreaking specifies if block breaking should be sent through + # packet.PlayerAuthInput or not. This field is somewhat redundant as it is always enabled if + # MovementType is packet.AuthoritativeMovementModeServer or + # packet.AuthoritativeMovementModeServerWithRewind + server_authoritative_block_breaking: bool + + # The total time in ticks that has elapsed since the start of the world. + current_tick: li64 + # The seed used to seed the random used to produce enchantments in the enchantment table. + # Note that the exact correct random implementation must be used to produce the correct + # results both client- and server-side. + enchantment_seed: zigzag32 + + # BlockProperties is a list of all the custom blocks registered on the server. + block_properties: BlockProperties + # A list of all items with their legacy IDs which are available in the game. + # Failing to send any of the items that are in the game will crash mobile clients. + itemstates: Itemstates + # A unique ID specifying the multi-player session of the player. + # A random UUID should be filled out for this field. + multiplayer_correlation_id: string + # ServerAuthoritativeInventory specifies if the server authoritative inventory system is enabled. This + # is a new system introduced in 1.16. Backwards compatibility with the inventory transactions has to + # some extent been preserved, but will eventually be removed. + server_authoritative_inventory: bool + # The server's engine version, used for telemetry + engine: string + +packet_add_player: + !id: 0x0c + !bound: client + # UUID is the UUID of the player. It is the same UUID that the client sent in the + # Login packet at the start of the session. A player with this UUID must exist + # in the player list (built up using the Player List packet) for it to show up in-game. + uuid: uuid + # Username is the name of the player. This username is the username that will be + # set as the initial name tag of the player. + username: string + # The unique ID of the player. The unique ID is a value that remains consistent + # across different sessions of the same world, but most unoffical servers simply + # fill the runtime ID of the player out for this field. + entity_id_self: zigzag64 + # The runtime ID of the player. The runtime ID is unique for each world session, + # and entities are generally identified in packets using this runtime ID. + runtime_entity_id: varint64 + # An identifier only set for particular platforms when chatting (presumably only for + # Nintendo Switch). It is otherwise an empty string, and is used to decide which players + # are able to chat with each other. + platform_chat_id: string + position: vec3f + velocity: vec3f + pitch: lf32 + yaw: lf32 + head_yaw: lf32 + held_item: Item + metadata: MetadataDictionary + flags: varint + command_permission: varint + action_permissions: varint + permission_level: varint + custom_stored_permissions: varint + user_id: li64 + links: Links + device_id: string + device_os: li32 + +packet_add_entity: + !id: 0x0d + !bound: client + entity_id_self: zigzag64 + runtime_entity_id: varint64 + entity_type: string + position: vec3f + velocity: vec3f + pitch: lf32 + yaw: lf32 + head_yaw: lf32 + attributes: EntityAttributes + metadata: MetadataDictionary + links: Links + +packet_remove_entity: + !id: 0x0e + !bound: client + entity_id_self: zigzag64 + +packet_add_item_entity: + !id: 0x0f + !bound: client + entity_id_self: zigzag64 + runtime_entity_id: varint64 + item: Item + position: vec3f + velocity: vec3f + metadata: MetadataDictionary + is_from_fishing: bool + +packet_take_item_entity: + !id: 0x11 + !bound: client + runtime_entity_id: varint64 + target: varint + +# MoveActorAbsolute is sent by the server to move an entity to an absolute position. It is typically used +# for movements where high accuracy isn't needed, such as for long range teleporting. +packet_move_entity: + !id: 0x12 + !bound: both + # EntityRuntimeID is the runtime ID of the entity. The runtime ID is unique for each world session, and + # entities are generally identified in packets using this runtime ID. + runtime_entity_id: varint64 + # Flags is a combination of flags that specify details of the movement. It is a combination of the flags + # above. + flags: u8 + # Position is the position to spawn the entity on. If the entity is on a distance that the player cannot + # see it, the entity will still show up if the player moves closer. + position: vec3f + # Rotation is a Vec3 holding the X, Y and Z rotation of the entity after the movement. This is a Vec3 for + # the reason that projectiles like arrows don't have yaw/pitch, but do have roll. + rotation: Rotation + +# MovePlayer is sent by players to send their movement to the server, and by the server to update the +# movement of player entities to other players. +packet_move_player: + !id: 0x13 + !bound: both + # EntityRuntimeID is the runtime ID of the player. The runtime ID is unique for each world session, and + # entities are generally identified in packets using this runtime ID. + runtime_id: varint + # Position is the position to spawn the player on. If the player is on a distance that the viewer cannot + # see it, the player will still show up if the viewer moves closer. + position: vec3f + # Pitch is the vertical rotation of the player. Facing straight forward yields a pitch of 0. Pitch is + # measured in degrees. + pitch: lf32 + # Yaw is the horizontal rotation of the player. Yaw is also measured in degrees + yaw: lf32 + # HeadYaw is the same as Yaw, except that it applies specifically to the head of the player. A different + # value for HeadYaw than Yaw means that the player will have its head turned + head_yaw: lf32 + # Mode is the mode of the movement. It specifies the way the player's movement should be shown to other + # players. It is one of the constants below. + mode: u8 => + 0: normal + 1: reset + 2: teleport + 3: rotation + # OnGround specifies if the player is considered on the ground. Note that proxies or hacked clients could + # fake this to always be true, so it should not be taken for granted. + on_ground: bool + # RiddenEntityRuntimeID is the runtime ID of the entity that the player might currently be riding. If not + # riding, this should be left 0. + ridden_runtime_id: varint + teleport: mode ? + if teleport: + # TeleportCause is written only if Mode is MoveModeTeleport. It specifies the cause of the teleportation, + # which is one of the constants above. + cause: li32 => + 0: unknown + 1: projectile + 2: chorus_fruit + 3: command + 4: behavior + # TeleportSourceEntityType is the entity type that caused the teleportation, for example an ender pearl. + # TODO: is this still a integer and not a string? + source_entity_type: LegacyEntityType + tick: varint64 + +packet_rider_jump: + !id: 0x14 + !bound: both + jump_strength: zigzag32 + +# UpdateBlock is sent by the server to update a block client-side, without resending the entire chunk that +# the block is located in. It is particularly useful for small modifications like block breaking/placing. +packet_update_block: + !id: 0x15 + !bound: client + # Position is the block position at which a block is updated. + position: BlockCoordinates + # NewBlockRuntimeID is the runtime ID of the block that is placed at Position after sending the packet + # to the client. + block_runtime_id: varint + # Flags is a combination of flags that specify the way the block is updated client-side. It is a + # combination of the flags above, but typically sending only the BlockUpdateNetwork flag is sufficient. + flags: UpdateBlockFlags + # Layer is the world layer on which the block is updated. For most blocks, this is the first layer, as + # that layer is the default layer to place blocks on, but for blocks inside of each other, this differs. + layer: varint + + +UpdateBlockFlags: [ "bitflags", + { + "type": "varint", + "flags": { + "neighbors": 1, + "network": 2, + "no_graphic": 0b100, + "unused": 0b1000, + "priority": 0b10000, + } + } +] + +packet_add_painting: + !id: 0x16 + !bound: client + entity_id_self: zigzag64 + runtime_entity_id: varint64 + coordinates: vec3f + direction: zigzag32 + title: string + +# TickSync is sent by the client and the server to maintain a synchronized, server-authoritative tick between +# the client and the server. The client sends this packet first, and the server should reply with another one +# of these packets, including the response time. +packet_tick_sync: + !id: 0x17 + !bound: both + # ClientRequestTimestamp is the timestamp on which the client sent this packet to the server. The server + # should fill out that same value when replying. + # The ClientRequestTimestamp is always 0 + request_time: li64 + # ServerReceptionTimestamp is the timestamp on which the server received the packet sent by the client. + # When the packet is sent by the client, this value is 0. + # ServerReceptionTimestamp is generally the current tick of the server. It isn't an actual timestamp, as + # the field implies + response_time: li64 + +packet_level_sound_event_old: + !id: 0x18 + !bound: both + sound_id: u8 + position: vec3f + block_id: zigzag32 + entity_type: zigzag32 + is_baby_mob: bool + is_global: bool + +packet_level_event: + !id: 0x19 + !bound: client + event: zigzag32 => + 1000: sound_click + 1001: sound_click_fail + 1002: sound_shoot + 1003: sound_door + 1004: sound_fizz + 1005: sound_ignite + 1007: sound_ghast + 1008: sound_ghast_shoot + 1009: sound_blaze_shoot + 1010: sound_door_bump + 1012: sound_door_crash + 1018: sound_enderman_teleport + 1020: sound_anvil_break + 1021: sound_anvil_use + 1022: sound_anvil_fall + 1030: sound_pop + 1032: sound_portal + 1040: sound_itemframe_add_item + 1041: sound_itemframe_remove + 1042: sound_itemframe_place + 1043: sound_itemframe_remove_item + 1044: sound_itemframe_rotate_item + 1050: sound_camera + 1051: sound_orb + 1052: sound_totem + 1060: sound_armor_stand_break + 1061: sound_armor_stand_hit + 1062: sound_armor_stand_fall + 1063: sound_armor_stand_place + 1064: pointed_dripstone_land + 1065: dye_used + 1066: ink_sack_used + 2000: particle_shoot #TODO: check 2000-2017 + 2001: particle_destroy + 2002: particle_splash + 2003: particle_eye_despawn + 2004: particle_spawn + 2005: particle_crop_growth + 2006: particle_guardian_curse + 2007: particle_death_smoke + 2008: particle_block_force_field + 2009: particle_projectile_hit + 2010: particle_dragon_egg_teleport + 2011: particle_crop_eaten + 2012: particle_critical + 2013: particle_enderman_teleport + 2014: particle_punch_block + 2015: particle_bubble + 2016: particle_evaporate + 2017: particle_destroy_armor_stand + 2018: particle_breaking_egg + 2019: particle_destroy_egg + 2020: particle_evaporate_water + 2021: particle_destroy_block_no_sound + 2022: particle_knockback_roar + 2023: particle_teleport_trail + 2024: particle_point_cloud + 2025: particle_explosion + 2026: particle_block_explosion + 2027: particle_vibration_signal + 2028: particle_dripstone_drip + 2029: particle_fizz_effect + 2030: particle_wax_on + 2031: particle_wax_off + 2032: particle_scrape + 2033: particle_electric_spark + + 3001: start_rain + 3002: start_thunder + 3003: stop_rain + 3004: stop_thunder + 3005: pause_game #data: 1 to pause, 0 to resume + 3006: pause_game_no_screen #data: 1 to pause, 0 to resume - same effect as normal pause but without screen + 3007: set_game_speed #x coordinate of pos = scale factor (default 1.0) + 3500: redstone_trigger + 3501: cauldron_explode + 3502: cauldron_dye_armor + 3503: cauldron_clean_armor + 3504: cauldron_fill_potion + 3505: cauldron_take_potion + 3506: cauldron_fill_water + 3507: cauldron_take_water + 3508: cauldron_add_dye + 3509: cauldron_clean_banner + 3600: block_start_break + 3601: block_stop_break + 4000: set_data + 9800: players_sleeping + 0x4000: add_particle_mask + # 0x4000 | + particle ID + 16385: particle_bubble # 1 + 16386: particle_bubble_manual # 2 + 16387: particle_critical # 3 + 16388: particle_block_force_field # 4 + 16389: particle_smoke # 5 + 16390: particle_explode # 6 + 16391: particle_evaporation # 7 + 16392: particle_flame # 8 + 16393: particle_candle_flame # 9 + 16394: particle_lava # 10 + 16395: particle_large_smoke # 11 + 16396: particle_redstone # 12 + 16397: particle_rising_red_dust # 13 + 16398: particle_item_break # 14 + 16399: particle_snowball_poof # 15 + 16400: particle_huge_explode # 16 + 16401: particle_huge_explode_seed # 17 + 16402: particle_mob_flame # 18 + 16403: particle_heart # 19 + 16404: particle_terrain # 20 + 16405: particle_town_aura # 21 + 16406: particle_portal # 22 + 16408: particle_water_splash # 24 + 16409: particle_water_splash_manual # 25 + 16410: particle_water_wake # 26 + 16411: particle_drip_water # 27 + 16412: particle_drip_lava # 28 + 16413: particle_drip_honey # 29 + 16414: particle_stalactite_drip_water # 30 + 16415: particle_stalactite_drip_lava # 31 + 16416: particle_falling_dust # 32 + 16417: particle_mob_spell # 33 + 16418: particle_mob_spell_ambient # 34 + 16419: particle_mob_spell_instantaneous # 35 + 16420: particle_ink # 36 + 16421: particle_slime # 37 + 16422: particle_rain_splash # 38 + 16423: particle_villager_angry # 39 + 16424: particle_villager_happy # 40 + 16425: particle_enchantment_table # 41 + 16426: particle_tracking_emitter # 42 + 16427: particle_note # 43 + 16428: particle_witch_spell # 44 + 16429: particle_carrot # 45 + 16430: particle_mob_appearance # 46 + 16431: particle_end_rod # 47 + 16432: particle_dragons_breath # 48 + 16433: particle_spit # 49 + 16434: particle_totem # 50 + 16435: particle_food # 51 + 16436: particle_fireworks_starter # 52 + 16437: particle_fireworks_spark # 53 + 16438: particle_fireworks_overlay # 54 + 16439: particle_balloon_gas # 55 + 16440: particle_colored_flame # 56 + 16441: particle_sparkler # 57 + 16442: particle_conduit # 58 + 16443: particle_bubble_column_up # 59 + 16444: particle_bubble_column_down # 60 + 16445: particle_sneeze # 61 + 16446: particle_shulker_bullet # 62 + 16447: particle_bleach # 63 + 16448: particle_dragon_destroy_block # 64 + 16449: particle_mycelium_dust # 65 + 16450: particle_falling_red_dust # 66 + 16451: particle_campfire_smoke # 67 + 16452: particle_tall_campfire_smoke # 68 + 16453: particle_dragon_breath_fire # 69 + 16454: particle_dragon_breath_trail # 70 + 16455: particle_blue_flame # 71 + 16456: particle_soul # 72 + 16457: particle_obsidian_tear # 73 + 16458: particle_portal_reverse # 74 + 16459: particle_snowflake # 75 + 16460: particle_vibration_signal # 76 + 16461: particle_sculk_sensor_redstone # 77 + 16462: particle_spore_blossom_shower # 78 + 16463: particle_spore_blossom_ambient # 79 + 16464: particle_wax # 80 + 16465: particle_electric_spark # 81 + position: vec3f + data: zigzag32 + +packet_block_event: + !id: 0x1a + !bound: client + # Position is the position of the block that an event occurred at. + position: BlockCoordinates + # EventType is the type of the block event. + # The event type decides the way the event data that follows is used + type: zigzag32 => + 0: sound + 1: change_state + # EventData holds event type specific data. For chests for example, + # opening the chest means the data must be 1 + data: zigzag32 + +packet_entity_event: + !id: 0x1b + !bound: both + runtime_entity_id: varint64 + event_id: u8 => + 1: jump + 2: hurt_animation + 3: death_animation + 4: arm_swing + 5: stop_attack + 6: tame_fail + 7: tame_success + 8: shake_wet + 9: use_item + 10: eat_grass_animation + 11: fish_hook_bubble + 12: fish_hook_position + 13: fish_hook_hook + 14: fish_hook_tease + 15: squid_ink_cloud + 16: zombie_villager_cure + 18: respawn + 19: iron_golem_offer_flower + 20: iron_golem_withdraw_flower + 21: love_particles #breeding + 22: villager_angry + 23: villager_happy + 24: witch_spell_particles + 25: firework_particles + 26: in_love_particles + 27: silverfish_spawn_animation + 28: guardian_attack + 29: witch_drink_potion + 30: witch_throw_potion + 31: minecart_tnt_prime_fuse + 32: creeper_prime_fuse + 33: air_supply_expired + 34: player_add_xp_levels + 35: elder_guardian_curse + 36: agent_arm_swing + 37: ender_dragon_death + 38: dust_particles #not sure what this is + 39: arrow_shake + + 57: eating_item + + 60: baby_animal_feed #green particles, like bonemeal on crops + 61: death_smoke_cloud + 62: complete_trade + 63: remove_leash #data 1 = cut leash + + 65: consume_totem + 66: player_check_treasure_hunter_achievement #mojang... + 67: entity_spawn #used for MinecraftEventing stuff, not needed + 68: dragon_puke #they call this puke particles + 69: item_entity_merge + 70: start_swim + 71: balloon_pop + 72: treasure_hunt + 73: agent_summon + 74: charged_crossbow + 75: fall + data: zigzag32 + +packet_mob_effect: + !id: 0x1c + !bound: client + runtime_entity_id: varint64 + event_id: u8 + effect_id: zigzag32 + amplifier: zigzag32 + particles: bool + duration: zigzag32 + +packet_update_attributes: + !id: 0x1d + !bound: client + runtime_entity_id: varint64 + attributes: PlayerAttributes + tick: varint64 + +# InventoryTransaction is a packet sent by the client. It essentially exists out of multiple sub-packets, +# each of which have something to do with the inventory in one way or another. Some of these sub-packets +# directly relate to the inventory, others relate to interaction with the world, that could potentially +# result in a change in the inventory. +packet_inventory_transaction: + !id: 0x1e + !bound: both + transaction: Transaction + +packet_mob_equipment: + !id: 0x1f + !bound: both + runtime_entity_id: varint64 + item: Item + slot: u8 + selected_slot: u8 + window_id: WindowID + +packet_mob_armor_equipment: + !id: 0x20 + !bound: both + runtime_entity_id: varint64 + helmet: Item + chestplate: Item + leggings: Item + boots: Item + +# Interact is sent by the client when it interacts with another entity in some way. It used to be used for +# normal entity and block interaction, but this is no longer the case now. +packet_interact: + !id: 0x21 + !bound: both + # Action type is the ID of the action that was executed by the player. It is one of the constants that + # may be found above. + action_id: u8 => + 3: leave_vehicle + 4: mouse_over_entity + 6: open_inventory + # TargetEntityRuntimeID is the runtime ID of the entity that the player interacted with. This is empty + # for the InteractActionOpenInventory action type. + target_entity_id: varint64 + # Position associated with the ActionType above. For the InteractActionMouseOverEntity, this is the + # position relative to the entity moused over over which the player hovered with its mouse/touch. For the + # InteractActionLeaveVehicle, this is the position that the player spawns at after leaving the vehicle. + position: action_id ? + if mouse_over_entity or leave_vehicle: vec3f + +packet_block_pick_request: + !id: 0x22 + !bound: server + x: zigzag32 + y: zigzag32 + z: zigzag32 + add_user_data: bool + selected_slot: u8 + +packet_entity_pick_request: + !id: 0x23 + !bound: server + runtime_entity_id: lu64 + selected_slot: u8 + +# PlayerAction is sent by the client when it executes any action, for example starting to sprint, swim, +# starting the breaking of a block, dropping an item, etc. +packet_player_action: + !id: 0x24 + !bound: server + # EntityRuntimeID is the runtime ID of the player. The runtime ID is unique for each world session, and + # entities are generally identified in packets using this runtime ID. + runtime_entity_id: varint64 + # ActionType is the ID of the action that was executed by the player. It is one of the constants that may + # be found above. + action: Action + # BlockPosition is the position of the target block, if the action with the ActionType set concerned a + # block. If that is not the case, the block position will be zero. + position: BlockCoordinates + # BlockFace is the face of the target block that was touched. If the action with the ActionType set + # concerned a block. If not, the face is always 0. + face: zigzag32 + +packet_hurt_armor: + !id: 0x26 + !bound: client + health: zigzag32 + +packet_set_entity_data: + !id: 0x27 + !bound: both + runtime_entity_id: varint64 + metadata: MetadataDictionary + tick: varint + +# SetActorMotion is sent by the server to change the client-side velocity of an entity. It is usually used +# in combination with server-side movement calculation. +packet_set_entity_motion: + !id: 0x28 + !bound: both + # EntityRuntimeID is the runtime ID of the entity. The runtime ID is unique for each world session, and + # entities are generally identified in packets using this runtime ID. + runtime_entity_id: varint64 + # Velocity is the new velocity the entity gets. This velocity will initiate the client-side movement of + # the entity. + velocity: vec3f + +# SetActorLink is sent by the server to initiate an entity link client-side, meaning one entity will start +# riding another. +packet_set_entity_link: + !id: 0x29 + !bound: client + link: Link + +packet_set_health: + !id: 0x2a + !bound: client + health: zigzag32 + +packet_set_spawn_position: + !id: 0x2b + !bound: client + spawn_type: zigzag32 => + 0: player + 1: world + player_position: BlockCoordinates + dimension: zigzag32 + world_position: BlockCoordinates + +packet_animate: + !id: 0x2c + !bound: both + action_id: zigzag32 => + 0: none + 1: swing_arm + 2: unknown + 3: wake_up + 4: critical_hit + 5: magic_critical_hit + 6: row_right + 7: row_left + runtime_entity_id: varint64 + +packet_respawn: + !id: 0x2d + !bound: both + position: vec3f + state: u8 + runtime_entity_id: varint64 + +# ContainerOpen is sent by the server to open a container client-side. This container must be physically +# present in the world, for the packet to have any effect. Unlike Java Edition, Bedrock Edition requires that +# chests for example must be present and in range to open its inventory. +packet_container_open: + !id: 0x2e + !bound: client + # WindowID is the ID representing the window that is being opened. It may be used later to close the + # container using a ContainerClose packet. + window_id: WindowID + # ContainerType is the type ID of the container that is being opened when opening the container at the + # position of the packet. It depends on the block/entity, and could, for example, be the window type of + # a chest or a hopper, but also a horse inventory. + window_type: WindowType + # ContainerPosition is the position of the container opened. The position must point to a block entity + # that actually has a container. If that is not the case, the window will not be opened and the packet + # will be ignored, if a valid ContainerEntityUniqueID has not also been provided. + coordinates: BlockCoordinates + # ContainerEntityUniqueID is the unique ID of the entity container that was opened. It is only used if + # the ContainerType is one that points to an entity, for example a horse. + runtime_entity_id: zigzag64 + +# ContainerClose is sent by the server to close a container the player currently has opened, which was opened +# using the ContainerOpen packet, or by the client to tell the server it closed a particular container, such +# as the crafting grid. +packet_container_close: + !id: 0x2f + !bound: both + # WindowID is the ID representing the window of the container that should be closed. It must be equal to + # the one sent in the ContainerOpen packet to close the designated window. + window_id: WindowID + # ServerSide determines whether or not the container was force-closed by the server. If this value is + # not set correctly, the client may ignore the packet and respond with a PacketViolationWarning. + server: bool + +# PlayerHotBar is sent by the server to the client. It used to be used to link hot bar slots of the player to +# actual slots in the inventory, but as of 1.2, this was changed and hot bar slots are no longer a free +# floating part of the inventory. +# Since 1.2, the packet has been re-purposed, but its new functionality is not clear. +packet_player_hotbar: + !id: 0x30 + !bound: both + selected_slot: varint + window_id: WindowID + select_slot: bool + +# InventoryContent is sent by the server to update the full content of a particular inventory. It is usually +# sent for the main inventory of the player, but also works for other inventories that are currently opened +# by the player. +packet_inventory_content: + !id: 0x31 + !bound: both + # WindowID is the ID that identifies one of the windows that the client currently has opened, or one of + # the consistent windows such as the main inventory. + window_id: WindowIDVarint + # Content is the new content of the inventory. The length of this slice must be equal to the full size of + # the inventory window updated. + input: ItemStacks + +# InventorySlot is sent by the server to update a single slot in one of the inventory windows that the client +# currently has opened. Usually this is the main inventory, but it may also be the off hand or, for example, +# a chest inventory. +packet_inventory_slot: + !id: 0x32 + !bound: both + # WindowID is the ID of the window that the packet modifies. It must point to one of the windows that the + # client currently has opened. + window_id: WindowIDVarint + # Slot is the index of the slot that the packet modifies. The new item will be set to the slot at this + # index. + slot: varint + # NewItem is the item to be put in the slot at Slot. It will overwrite any item that may currently + # be present in that slot. + item: Item + +# ContainerSetData is sent by the server to update specific data of a single container, meaning a block such +# as a furnace or a brewing stand. This data is usually used by the client to display certain features +# client-side. +packet_container_set_data: + !id: 0x33 + !bound: client + # WindowID is the ID of the window that should have its data set. The player must have a window open with + # the window ID passed, or nothing will happen. + window_id: WindowID + # Key is the key of the property. It is one of the constants that can be found above. Multiple properties + # share the same key, but the functionality depends on the type of the container that the data is set to. + # IF FURNACE: + # 0: furnace_tick_count + # 1: furnace_lit_time + # 2: furnace_lit_duration + # 3: furnace_stored_xp + # 4: furnace_fuel_aux + # IF BREWING STAND: + # 0: brew_time + # 1: brew_fuel_amount + # 2: brew_fuel_total + property: zigzag32 + # Value is the value of the property. Its use differs per property. + value: zigzag32 + +packet_crafting_data: + !id: 0x34 + !bound: client + recipes: Recipes + potion_type_recipes: PotionTypeRecipes + potion_container_recipes: PotionContainerChangeRecipes + is_clean: bool + +# CraftingEvent is sent by the client when it crafts a particular item. Note that this packet may be fully +# ignored, as the InventoryTransaction packet provides all the information required. +packet_crafting_event: + !id: 0x35 + !bound: both + # WindowID is the ID representing the window that the player crafted in. + window_id: WindowID + # CraftingType is a type that indicates the way the crafting was done, for example if a crafting table + # was used. + recipe_type: zigzag32 => + 0: inventory + 1: crafting + 2: workbench + # RecipeUUID is the UUID of the recipe that was crafted. It points to the UUID of the recipe that was + # sent earlier in the CraftingData packet. + recipe_id: uuid + # Input is a list of items that the player put into the recipe so that it could create the Output items. + # These items are consumed in the process. + input: Item[]varint + # Output is a list of items that were obtained as a result of crafting the recipe. + result: Item[]varint + +# GUIDataPickItem is sent by the server to make the client 'select' a hot bar slot. It currently appears to +# be broken however, and does not actually set the selected slot to the hot bar slot set in the packet. +packet_gui_data_pick_item: + !id: 0x36 + !bound: client + # ItemName is the name of the item that shows up in the top part of the popup that shows up when + # selecting an item. It is shown as if an item was selected by the player itself. + item_name: string + # ItemEffects is the line under the ItemName, where the effects of the item are usually situated. + item_effects: string + # HotBarSlot is the hot bar slot to be selected/picked. This does not currently work, so it does not + # matter what number this is. + hotbar_slot: li32 + +# AdventureSettings is sent by the server to update game-play related features, in particular permissions to +# access these features for the client. It includes allowing the player to fly, build and mine, and attack +# entities. Most of these flags should be checked server-side instead of using this packet only. +# The client may also send this packet to the server when it updates one of these settings through the +# in-game settings interface. The server should verify if the player actually has permission to update those +# settings. +packet_adventure_settings: + !id: 0x37 + !bound: both + # Flags is a set of flags that specify certain properties of the player, such as whether or not it can + # fly and/or move through blocks. It is one of the AdventureFlag constants above. + flags: AdventureFlags + # CommandPermissionLevel is a permission level that specifies the kind of commands that the player is + # allowed to use. + command_permission: varint => + 0: normal + 1: operator + 2: host + 3: automation + 4: admin + # ActionPermissions is, much like Flags, a set of flags that specify actions that the player is allowed + # to undertake, such as whether it is allowed to edit blocks, open doors etc. It is a combination of the + # ActionPermission constants above. + action_permissions: ActionPermissions + # PermissionLevel is the permission level of the player as it shows up in the player list built up using + # the PlayerList packet. It is one of the PermissionLevel constants above. + permission_level: varint => + 0: visitor + 1: member + 2: operator + 3: custom + # Custom permissions + custom_stored_permissions: varint + # PlayerUniqueID is a unique identifier of the player. It appears it is not required to fill this field + # out with a correct value. Simply writing 0 seems to work. + user_id: li64 + +AdventureFlags: [ "bitflags", + { + "type": "varint", + "flags": { + "world_immutable": 1, + "no_pvp": 2, + "auto_jump": 0x20, + "allow_flight": 0x40, + "no_clip": 0x80, + "world_builder": 0x100, + "flying": 0x200, + "muted": 0x400 + } + } +] + +ActionPermissions: [ "bitflags", + { + "type": "varint", + "flags": { + "mine": 0x10001, + "doors_and_switches": 0x10002, + "open_containers": 0x10004, + "attack_players": 0x10008, + "attack_mobs": 0x10010, + "operator": 0x10020, + "teleport": 0x10080, + "build": 0x10100, + "default": 0x10200 + } + } +] + +packet_block_entity_data: + !id: 0x38 + !bound: both + position: BlockCoordinates + nbt: nbt + +packet_player_input: + !id: 0x39 + !bound: server + motion_x: lf32 + motion_z: lf32 + jumping: bool + sneaking: bool + +# LevelChunk is sent by the server to provide the client with a chunk of a world data (16xYx16 blocks). +# Typically a certain amount of chunks is sent to the client before sending it the spawn PlayStatus packet, +# so that the client spawns in a loaded world. +packet_level_chunk: + !id: 0x3a + !bound: client + # ChunkX is the X coordinate of the chunk sent. (To translate a block's X to a chunk's X: x >> 4) + x: zigzag32 + # ChunkZ is the Z coordinate of the chunk sent. (To translate a block's Z to a chunk's Z: z >> 4) + z: zigzag32 + # SubChunkCount is the amount of sub chunks that are part of the chunk sent. Depending on if the cache + # is enabled, a list of blob hashes will be sent, or, if disabled, the sub chunk data. + sub_chunk_count: varint + # CacheEnabled specifies if the client blob cache should be enabled. This system is based on hashes of + # blobs which are consistent and saved by the client in combination with that blob, so that the server + # does not have to send the same chunk multiple times. If the client does not yet have a blob with the hash sent, + # it will send a ClientCacheBlobStatus packet containing the hashes is does not have the data of. + cache_enabled: bool + blobs: cache_enabled? + if true: + # BlobHashes is a list of all blob hashes used in the chunk. It is composed of SubChunkCount + 1 hashes, + # with the first SubChunkCount hashes being those of the sub chunks and the last one that of the biome + # of the chunk. + # If CacheEnabled is set to false, BlobHashes can be left empty. + hashes: lu64[]varint + # RawPayload is a serialised string of chunk data. The data held depends on if CacheEnabled is set to + # true. If set to false, the payload is composed of multiple sub-chunks, each of which carry a version + # which indicates the way they are serialised, followed by biomes, border blocks and tile entities. If + # CacheEnabled is true, the payload consists out of the border blocks and tile entities only. + payload: ByteArray + +packet_set_commands_enabled: + !id: 0x3b + !bound: client + enabled: bool + +packet_set_difficulty: + !id: 0x3c + !bound: client + difficulty: varint + +packet_change_dimension: + !id: 0x3d + !bound: client + dimension: zigzag32 + position: vec3f + respawn: bool + +# SetPlayerGameType is sent by the server to update the game type (game mode) of the player +packet_set_player_game_type: + !id: 0x3e + !bound: both + # The new gamemode for the player. + # Some of these game types require additional flags to be set in an AdventureSettings packet for + # the game mode to obtain its full functionality. + gamemode: GameMode + +packet_player_list: + !id: 0x3f + !bound: client + records: PlayerRecords + +packet_simple_event: + !id: 0x40 + !bound: client + event_type: lu16 + +# Event is sent by the server to send an event with additional data. It is typically sent to the client for +# telemetry reasons, much like the SimpleEvent packet. +packet_event: + !id: 0x41 + !bound: client + runtime_id: varint64 + event_type: zigzag32 => + 0: achievement_awarded + 1: entity_interact + 2: portal_built + 3: portal_used + 4: mob_killed + 5: cauldron_used + 6: player_death + 7: boss_killed + 8: agent_command + 9: agent_created + 10: banner_pattern_removed + 11: commaned_executed + 12: fish_bucketed + 13: mob_born + 14: pet_died + 15: cauldron_block_used + 16: composter_block_used + 17: bell_block_used + 18: actor_definition + 19: raid_update + 20: player_movement_anomaly + 21: player_moement_corrected + 22: honey_harvested + 23: target_block_hit + 24: piglin_barter + 25: waxed_or_unwaxed_copper + use_player_id: u8 + event_data: restBuffer # Unknown data, TODO: add + +packet_spawn_experience_orb: + !id: 0x42 + !bound: client + position: vec3f + count: zigzag32 + +UpdateMapFlags: [ "bitflags", { + "type": "varint", + "flags": [ + "void", + "texture", + "decoration", + "initialisation" + ] +}] + +# ClientBoundMapItemData is sent by the server to the client to update the data of a map shown to the client. +# It is sent with a combination of flags that specify what data is updated. +# The ClientBoundMapItemData packet may be used to update specific parts of the map only. It is not required +# to send the entire map each time when updating one part. +packet_clientbound_map_item_data: + !id: 0x43 + !bound: client + # MapID is the unique identifier that represents the map that is updated over network. It remains + # consistent across sessions. + map_id: zigzag64 + # UpdateFlags is a combination of flags found above that indicate what parts of the map should be updated + # client-side. + update_flags: UpdateMapFlags + # Dimension is the dimension of the map that should be updated, for example the overworld (0), the nether + # (1) or the end (2). + dimension: u8 + # LockedMap specifies if the map that was updated was a locked map, which may be done using a cartography + # table. + locked: bool + # The following fields apply only for the MapUpdateFlagInitialisation. + # MapsIncludedIn holds an array of map IDs that the map updated is included in. This has to do with the + # scale of the map: Each map holds its own map ID and all map IDs of maps that include this map and have + # a bigger scale. This means that a scale 0 map will have 5 map IDs in this slice, whereas a scale 4 map + # will have only 1 (its own). + # The actual use of this field remains unknown. + included_in: update_flags.initialisation ? + if true: zigzag64[]varint + # Scale is the scale of the map as it is shown in-game. It is written when any of the MapUpdateFlags are + # set to the UpdateFlags field. + scale: update_flags.initialisation || update_flags.decoration || update_flags.texture ? + if true: u8 + # The following fields apply only for the MapUpdateFlagDecoration. + # TrackedObjects is a list of tracked objects on the map, which may either be entities or blocks. The + # client makes sure these tracked objects are actually tracked. (position updated etc.) + tracked: update_flags.decoration ? + if true: + objects: TrackedObject[]varint + decorations: MapDecoration[]varint + # Updates to the map contents itself (texture) + texture: update_flags.texture ? + if true: + # Width is the width of the texture area that was updated. The width may be a subset of the total width + # of the map. + width: zigzag32 + # Height is the height of the texture area that was updated. The height may be a subset of the total + # height of the map + height: zigzag32 + # XOffset is the X offset in pixels at which the updated texture area starts. From this X, the updated + # texture will extend exactly Width pixels to the right. + x_offset: zigzag32 + # YOffset is the Y offset in pixels at which the updated texture area starts. From this Y, the updated + # texture will extend exactly Height pixels up. + y_offset: zigzag32 + # Pixels is a list of pixel colours for the new texture of the map. It is indexed as Pixels[y][x], with + # the length of the outer slice having to be exactly Height long and the inner slices exactly Width long. + # To access this array, use $width * y + x + pixels: varint[]varint + + +packet_map_info_request: + !id: 0x44 + !bound: both + map_id: zigzag64 + +# RequestChunkRadius is sent by the client to the server to update the server on the chunk view radius that +# it has set in the settings. The server may respond with a ChunkRadiusUpdated packet with either the chunk +# radius requested, or a different chunk radius if the server chooses so. +packet_request_chunk_radius: + !id: 0x45 + !bound: both + # ChunkRadius is the requested chunk radius. This value is always the value set in the settings of the + # player. + chunk_radius: zigzag32 + +# ChunkRadiusUpdated is sent by the server in response to a RequestChunkRadius packet. It defines the chunk +# radius that the server allows the client to have. This may be lower than the chunk radius requested by the +# client in the RequestChunkRadius packet. +packet_chunk_radius_update: + !id: 0x46 + !bound: client + # ChunkRadius is the final chunk radius that the client will adapt when it receives the packet. It does + # not have to be the same as the requested chunk radius. + chunk_radius: zigzag32 + +packet_item_frame_drop_item: + !id: 0x47 + !bound: both + coordinates: BlockCoordinates + +packet_game_rules_changed: + !id: 0x48 + !bound: client + rules: GameRules + +# Camera is sent by the server to use an Education Edition camera on a player. It produces an image +# client-side. +packet_camera: + !id: 0x49 + !bound: client + # CameraEntityUniqueID is the unique ID of the camera entity from which the picture was taken. + camera_entity_unique_id: zigzag64 + # TargetPlayerUniqueID is the unique ID of the target player. The unique ID is a value that remains + # consistent across different sessions of the same world, but most servers simply fill the runtime ID of + # the player out for this field. + target_player_unique_id: zigzag64 + +packet_boss_event: + !id: 0x4a + !bound: both + boss_entity_id: zigzag64 + type: varint => + # S2C: Shows the boss-bar to the player. + 0: show_bar + # C2S: Registers a player to a boss fight. + 1: register_player + # S2C: Removes the boss-bar from the client. + 2: hide_bar + # C2S: Unregisters a player from a boss fight. + 3: unregister_player + # S2C: Sets the bar percentage. + 4: set_bar_progress + # S2C: Sets title of the bar. + 5: set_bar_title + # S2C: darkens the sky + 6: update_properties + # S2C: Not implemented :( Intended to alter bar appearance, but these currently produce no effect on client-side whatsoever. + 7: texture + _: type? + if show_bar: + # BossBarTitle is the title shown above the boss bar. It currently does not function, and instead uses + # the name tag of the boss entity at all times. It is only set if the EventType is BossEventShow or + # BossEventTitle. + title: string + # HealthPercentage is the percentage of health that is shown in the boss bar. It currently does not + # function, and instead uses the health percentage of the boss entity at all times. It is only set if the + # EventType is BossEventShow or BossEventHealthPercentage. + progress: lf32 + # ScreenDarkening currently seems not to do anything. + screen_darkening: li16 + # Colour is the colour of the boss bar that is shown when a player is subscribed. It currently does not + # function. It is only set if the EventType is BossEventShow, BossEventAppearanceProperties or + # BossEventTexture. + # Format is ARGB + color: varint + # Overlay is the overlay of the boss bar that is shown on top of the boss bar when a player is + # subscribed. It currently does not function. It is only set if the EventType is BossEventShow, + # BossEventAppearanceProperties or BossEventTexture. + overlay: varint + if register_player or unregister_player: + # PlayerUniqueID is the unique ID of the player that is registered to or unregistered from the boss + # fight. It is set if EventType is either BossEventRegisterPlayer or BossEventUnregisterPlayer. + player_id: zigzag64 + if set_bar_progress: + progress: lf32 + if set_bar_title: + title: string + if update_properties: + screen_darkening: li16 + color: varint + overlay: varint + if texture: + color: varint + overlay: varint + +packet_show_credits: + !id: 0x4b + !bound: client + runtime_entity_id: varint64 + status: zigzag32 + +# This packet sends a list of commands to the client. Commands can have +# arguments, and some of those arguments can have 'enum' values, which are a list of possible +# values for the argument. The serialization is rather complex and involves palettes like chunks. +## In bedrock-protocol, listen to on('client.commands') for a simpler representation +packet_available_commands: + !id: 0x4c + !bound: client + # The length of the enums for all the command paramaters in this packet + values_len: varint + # Not read from stream: instead calculated from the `values_len` field + # + # If the values_len < 0xff => byte, + # If the values_len < 0xffff => short, + # If the values_len < 0xffffff => int + _enum_type: '["enum_size_based_on_values_len"]' + # Here all the enum values for all of the possible commands are stored to one array palette + enum_values: string[]$values_len + # Integer paramaters may sometimes have a prefix, such as the XP command: + # /xp [player: target] <- here, the xp command gives experience points + # /xp L [player: target] <- here, the xp command gives experience levels + # This is the palette of suffixes + suffixes: string[]varint + # The list of enum objects + enums: []varint + # The name of the enum + name: string + # The values in the enum + values: []varint + # The indexes to value in the palette + _: ../_enum_type? + if byte: u8 + if short: lu16 + if int: lu32 + command_data: []varint + name: string + description: string + flags: lu16 + permission_level: u8 + alias: li32 + # The list of overload paramaters for this command + overloads: []varint + # Each of the paramaters gets an array of posible overloads + _: []varint + # The name of the paramater shown to the user (the `amount` in `/xp `) + paramater_name: string + value_type: lu16 => + 1: int + 2: float + 3: value + 4: wildcard_int + 5: operator + 6: target + 16: file_path + 32: string + 40: position + 44: message + 46: raw_text + 50: json + 63: command + # In MC, this + prior field are combined to one 32bit bitfield + enum_type: lu16 => + 0x10: valid + 0x20: enum + 0x100: suffixed + 0x400: soft_enum + # Is this paramater required? + optional: bool + # Additinal options for this command (thanks macroshaft...) + options: CommandFlags + # There are two types of enums: static enums which cannot be changed after sending AvaliableCommands, + # (unless you resend the whole packet) and 'soft' or 'dynamic' enums like below which is an array + # that can be updated with the UpdateSoftEnum packet + dynamic_enums: []varint + name: string + values: string[]varint + enum_constraints: []varint + value_index: li32 + enum_index: li32 + constraints: []varint + constraint: u8 => + 0: cheats_enabled + 1: operator_permissions + 2: host_permissions + +# ParamOptionCollapseEnum specifies if the enum (only if the Type is actually an enum type. If not, +# setting this to true has no effect) should be collapsed. This means that the options of the enum are +# never shown in the actual usage of the command, but only as auto-completion, like it automatically does +# with enums that have a big amount of options. To illustrate, it can make +# <$Name: bool>. +CommandFlags: [ "bitfield", [ + { "name": "unused", "size": 6, "signed": false }, # 6 unused upper bits + { "name": "has_semantic_constraint", "size": 1, "signed": false }, + { "name": "collapse_enum", "size": 1, "signed": false } +]] + +# enum_size_based_on_values_len: native + +# CommandRequest is sent by the client to request the execution of a server-side command. Although some +# servers support sending commands using the Text packet, this packet is guaranteed to have the correct +# result. +packet_command_request: + !id: 0x4d + !bound: server + # CommandLine is the raw entered command line. The client does no parsing of the command line by itself + # (unlike it did in the early stages), but lets the server do that. + command: string + # Origin holds information about the command sender that will be returnd back in the command response + origin: CommandOrigin + # Internal specifies if the command request internal. Setting it to false seems to work and the usage of + # this field is not known. + interval: bool + + +# CommandBlockUpdate is sent by the client to update a command block at a specific position. The command +# block may be either a physical block or an entity. +packet_command_block_update: + !id: 0x4e + !bound: server + # Block specifies if the command block updated was an actual physical block. If false, the command block + # is in a minecart and has an entity runtime ID instead. + is_block: bool + # Position is the position of the command block updated. It is only set if Block is set to true. Nothing + # happens if no command block is set at this position. + _: is_block ? + if true: + # Position is the position of the command block updated. It is only set if Block is set to true. Nothing + # happens if no command block is set at this position. + position: BlockCoordinates + # Mode is the mode of the command block. It is either CommandBlockImpulse, CommandBlockChain or + # CommandBlockRepeat. It is only set if Block is set to true. + mode: varint => + 0: impulse + 1: repeat + 2: chain + # NeedsRedstone specifies if the command block needs to be powered by redstone to be activated. If false, + # the command block is always active. The field is only set if Block is set to true. + needs_redstone: bool + # Conditional specifies the behaviour of the command block if the command block before it (the opposite + # side of the direction the arrow if facing) fails to execute. If set to false, it will activate at all + # times, whereas if set to true, it will activate only if the previous command block executed + # successfully. The field is only set if Block is set to true. + conditional: bool + default: + minecart_entity_runtime_id: varint64 + # Command is the command currently entered in the command block. This is the command that is executed + # when the command block is activated. + command: string + # LastOutput is the output of the last command executed by the command block. It may be left empty to + # show simply no output at all, in combination with setting ShouldTrackOutput to false. + last_output: string + # Name is the name of the command block updated. If not empty, it will show this name hovering above the + # command block when hovering over the block with the cursor. + name: string + # ShouldTrackOutput specifies if the command block tracks output. If set to false, the output box won't + # be shown within the command block. + should_track_output: bool + # TickDelay is the delay in ticks between executions of a command block, if it is a repeating command + # block. + tick_delay: li32 + # ExecuteOnFirstTick specifies if the command block should execute on the first tick, AKA as soon as the + # command block is enabled. + execute_on_first_tick: bool + +packet_command_output: + !id: 0x4f + !bound: client + # CommandOrigin is the data specifying the origin of the command. In other words, the source that the + # command request was from, such as the player itself or a websocket server. The client forwards the + # messages in this packet to the right origin, depending on what is sent here. + origin: CommandOrigin + # OutputType specifies the type of output that is sent. + output_type: i8 => + 1: last + 2: silent + 3: all + 4: data_set + # SuccessCount is the amount of times that a command was executed successfully as a result of the command + # that was requested. For servers, this is usually a rather meaningless fields, but for vanilla, this is + # applicable for commands created with Functions. + success_count: varint + # OutputMessages is a list of all output messages that should be sent to the player. Whether they are + # shown or not, depends on the type of the messages. + output: []varint + # Success indicates if the output message was one of a successful command execution. If set to true, the + # output message is by default coloured white, whereas if set to false, the message is by default + # coloured red. + success: bool + # Message is the message that is sent to the client in the chat window. It may either be simply a + # message or a translated built-in string like 'commands.tp.success.coordinates', combined with specific + # parameters below. + message_id: string + # Parameters is a list of parameters that serve to supply the message sent with additional information, + # such as the position that a player was teleported to or the effect that was applied to an entity. + # These parameters only apply for the Minecraft built-in command output. + paramaters: string[]varint + data_set: output_type ? + if data_set: string + default: void + + +# UpdateTrade is sent by the server to update the trades offered by a villager to a player. It is sent at the +# moment that a player interacts with a villager. +packet_update_trade: + !id: 0x50 + !bound: client + # WindowID is the ID that identifies the trading window that the client currently has opened. + window_id: WindowID + # WindowType is an identifier specifying the type of the window opened. In vanilla, it appears this is + # always filled out with 15. + window_type: WindowType + # Size is the amount of trading options that the villager has. + size: varint + # TradeTier is the tier of the villager that the player is trading with. The tier starts at 0 with a + # first two offers being available, after which two additional offers are unlocked each time the tier + # becomes one higher. + trade_tier: varint + # VillagerUniqueID is the unique ID of the villager entity that the player is trading with. The + # TradeTier sent above applies to this villager. + villager_unique_id: varint64 + # EntityUniqueID is the unique ID of the entity (usually a player) for which the trades are updated. The + # updated trades may apply only to this entity. + entity_unique_id: varint64 + # DisplayName is the name displayed at the top of the trading UI. It is usually used to represent the + # profession of the villager in the UI. + display_name: string + # NewTradeUI specifies if the villager should be using the new trade UI (The one added in 1.11.) rather + # than the old one. This should usually be set to true. + new_trading_ui: bool + # Trading based on Minecraft economy - specifies if the prices of the villager's offers are modified by an increase in + # demand for the item. (A mechanic added in 1.11.) Buying more of the same item will increase the price + # of that particular item. + # https://minecraft.gamepedia.com/Trading#Economics + economic_trades: bool + # NBT serialised compound of offers that the villager has. + offers: nbt + +# UpdateEquip is sent by the server to the client upon opening a horse inventory. It is used to set the +# content of the inventory and specify additional properties, such as the items that are allowed to be put +# in slots of the inventory. +packet_update_equipment: + !id: 0x51 + !bound: client + # WindowID is the identifier associated with the window that the UpdateEquip packet concerns. It is the + # ID sent for the horse inventory that was opened before this packet was sent. + window_id: WindowID + # WindowType is the type of the window that was opened. Generally, this is the type of a horse inventory, + # as the packet is specifically made for that. + window_type: WindowType + # Size is the size of the horse inventory that should be opened. A bigger size does, in fact, change the + # amount of slots displayed. + size: u8 + # EntityUniqueID is the unique ID of the entity whose equipment was 'updated' to the player. It is + # typically the horse entity that had its inventory opened. + entity_id: zigzag64 + # `inventory` is a network NBT serialised compound holding the content of the inventory of + # the entity (the equipment) and additional data such as the allowed items for a particular slot, used to + # make sure only saddles can be put in the saddle slot etc. + inventory: nbt + + +# ResourcePackDataInfo is sent by the server to the client to inform the client about the data contained in +# one of the resource packs that are about to be sent. +packet_resource_pack_data_info: + !id: 0x52 + !bound: client + # UUID is the unique ID of the resource pack that the info concerns. + pack_id: string + # DataChunkSize is the maximum size in bytes of the chunks in which the total size of the resource pack + # to be sent will be divided. A size of 1MB (1024*1024) means that a resource pack of 15.5MB will be + # split into 16 data chunks. + max_chunk_size: lu32 + # ChunkCount is the total amount of data chunks that the sent resource pack will exist out of. It is the + # total size of the resource pack divided by the DataChunkSize field. + # The client doesn't actually seem to use this field. Rather, it divides the size by the chunk size to + # calculate it itself. + chunk_count: lu32 + # Size is the total size in bytes that the resource pack occupies. This is the size of the compressed + # archive (zip) of the resource pack. + size: lu64 + # Hash is a SHA256 hash of the content of the resource pack. + hash: ByteArray + # Premium specifies if the resource pack was a premium resource pack, meaning it was bought from the + # Minecraft store. + is_premium: bool + # PackType is the type of the resource pack. It is one of the resource pack types listed. + pack_type: u8 => + 1: addon + 2: cached + 3: copy_protected + 4: behavior + 5: persona_piece + 6: resources + 7: skins + 8: world_template + +# ResourcePackChunkData is sent to the client so that the client can download the resource pack. Each packet +# holds a chunk of the compressed resource pack, of which the size is defined in the ResourcePackDataInfo +# packet sent before. +packet_resource_pack_chunk_data: + !id: 0x53 + !bound: client + # UUID is the unique ID of the resource pack that the chunk of data is taken out of. + pack_id: string + # ChunkIndex is the current chunk index of the chunk. It is a number that starts at 0 and is incremented + # for each resource pack data chunk sent to the client. + chunk_index: lu32 + # DataOffset is the current progress in bytes or offset in the data that the resource pack data chunk is + # taken from. + progress: lu64 + # RawPayload is a byte slice containing a chunk of data from the resource pack. It must be of the same size or + # less than the DataChunkSize set in the ResourcePackDataInfo packet. + payload: ByteArray + +# ResourcePackChunkRequest is sent by the client to request a chunk of data from a particular resource pack, +# that it has obtained information about in a ResourcePackDataInfo packet. +packet_resource_pack_chunk_request: + !id: 0x54 + !bound: server + # UUID is the unique ID of the resource pack that the chunk of data is requested from. + pack_id: string + # ChunkIndex is the requested chunk index of the chunk. It is a number that starts at 0 and is + # incremented for each resource pack data chunk requested. + chunk_index: lu32 + +packet_transfer: + !id: 0x55 + !bound: client + server_address: string + port: lu16 + +packet_play_sound: + !id: 0x56 + !bound: client + name: string + coordinates: BlockCoordinates + volume: lf32 + pitch: lf32 + +packet_stop_sound: + !id: 0x57 + !bound: client + name: string + stop_all: bool + +# SetTitle is sent by the server to make a title, subtitle or action bar shown to a player. It has several +# fields that allow setting the duration of the titles. +packet_set_title: + !id: 0x58 + !bound: client + # ActionType is the type of the action that should be executed upon the title of a player. It is one of + # the constants above and specifies the response of the client to the packet. + type: zigzag32 => + 0: clear + 1: reset + 2: set_title + 3: set_subtitle + 4: action_bar_message + 5: set_durations + 6: set_title_json + 7: set_subtitle_json + 8: action_bar_message_json + # Text is the text of the title, which has a different meaning depending on the ActionType that the + # packet has. The text is the text of a title, subtitle or action bar, depending on the type set. + text: string + # FadeInDuration is the duration that the title takes to fade in on the screen of the player. It is + # measured in 20ths of a second (AKA in ticks). + fade_in_time: zigzag32 + # RemainDuration is the duration that the title remains on the screen of the player. It is measured in + # 20ths of a second (AKA in ticks). + stay_time: zigzag32 + # FadeOutDuration is the duration that the title takes to fade out of the screen of the player. It is + # measured in 20ths of a second (AKA in ticks). + fade_out_time: zigzag32 + # XUID is the XBOX Live user ID of the player, which will remain consistent as long as the player is + # logged in with the XBOX Live account. It is empty if the user is not logged into its XBL account. + xuid: string + # PlatformOnlineID is either a uint64 or an empty string. + platform_online_id: string + +packet_add_behavior_tree: + !id: 0x59 + !bound: client + behaviortree: string + +# StructureBlockUpdate is sent by the client when it updates a structure block using the in-game UI. The +# data it contains depends on the type of structure block that it is. In Minecraft Bedrock Edition v1.11, +# there is only the Export structure block type, but in v1.13 the ones present in Java Edition will, +# according to the wiki, be added too. +packet_structure_block_update: + !id: 0x5a + !bound: client + # Position is the position of the structure block that is updated. + position: BlockCoordinates + # StructureName is the name of the structure that was set in the structure block's UI. This is the name + # used to export the structure to a file. + structure_name: string + # DataField is the name of a function to run, usually used during natural generation. A description can + # be found here: https://minecraft.gamepedia.com/Structure_Block#Data. + data_field: string + # IncludePlayers specifies if the 'Include Players' toggle has been enabled, meaning players are also + # exported by the structure block. + include_players: bool + # ShowBoundingBox specifies if the structure block should have its bounds outlined. A thin line will + # encapsulate the bounds of the structure if set to true. + show_bounding_box: bool + # StructureBlockType is the type of the structure block updated. A list of structure block types that + # will be used can be found in the constants above. + structure_block_type: zigzag32 + # Settings is a struct of settings that should be used for exporting the structure. These settings are + # identical to the last sent in the StructureBlockUpdate packet by the client. + settings: StructureBlockSettings + # RedstoneSaveMode is the mode that should be used to save the structure when used with redstone. In + # Java Edition, this is always stored in memory, but in Bedrock Edition it can be stored either to disk + # or memory. See the constants above for the options. + redstone_save_mode: zigzag32 + # ShouldTrigger specifies if the structure block should be triggered immediately after this packet + # reaches the server. + should_trigger: bool + +# ShowStoreOffer is sent by the server to show a Marketplace store offer to a player. It opens a window +# client-side that displays the item. +# The ShowStoreOffer packet only works on the partnered servers: Servers that are not partnered will not have +# a store buttons show up in the in-game pause menu and will, as a result, not be able to open store offers +# on the client side. Sending the packet does therefore not work when using a proxy that is not connected to +# with the domain of one of the partnered servers. +packet_show_store_offer: + !id: 0x5b + !bound: client + # OfferID is a string that identifies the offer for which a window should be opened. While typically a + # UUID, the ID could be anything. + offer_id: string + # ShowAll specifies if all other offers of the same 'author' as the one of the offer associated with the + # OfferID should also be displayed, alongside the target offer. + show_all: bool + + +# PurchaseReceipt is sent by the client to the server to notify the server it purchased an item from the +# Marketplace store that was offered by the server. The packet is only used for partnered servers. +packet_purchase_receipt: + !id: 0x5c + !bound: server + # Receipts is a list of receipts, or proofs of purchases, for the offers that have been purchased by the + # player. + receipts: string[]varint + +packet_player_skin: + !id: 0x5d + !bound: both + uuid: uuid + skin: Skin + skin_name: string + old_skin_name: string + is_verified: bool + +# SubClientLogin is sent when a sub-client joins the server while another client is already connected to it. +# The packet is sent as a result of split-screen game play, and allows up to four players to play using the +# same network connection. After an initial Login packet from the 'main' client, each sub-client that +# connects sends a SubClientLogin to request their own login. +packet_sub_client_login: + !id: 0x5e + !bound: client + # ConnectionRequest is a string containing information about the player and JWTs that may be used to + # verify if the player is connected to XBOX Live. The connection request also contains the necessary + # client public key to initiate encryption. + # The ConnectionRequest in this packet is identical to the one found in the Login packet. + tokens: '["encapsulated", { "lengthType": "varint", "type": "LoginTokens" }]' + +# AutomationClientConnect is used to make the client connect to a websocket server. This websocket server has +# the ability to execute commands on the behalf of the client and it can listen for certain events fired by +# the client. +packet_initiate_web_socket_connection: + !id: 0x5f + !bound: client + # ServerURI is the URI to make the client connect to. It can be, for example, 'localhost:8000/ws' to + # connect to a websocket server on the localhost at port 8000. + server: string + + +# SetLastHurtBy is sent by the server to let the client know what entity type it was last hurt by. At this +# moment, the packet is useless and should not be used. There is no behaviour that depends on if this +# packet is sent or not. +packet_set_last_hurt_by: + !id: 0x60 + !bound: client + entity_type: varint + +# BookEdit is sent by the client when it edits a book. It is sent each time a modification was made and the +# player stops its typing 'session', rather than simply after closing the book. +packet_book_edit: + !id: 0x61 + !bound: client + type: u8 => + 0: replace_page + 1: add_page + 2: delete_page + 3: swap_pages + 4: sign + slot: u8 + _: type? + if replace_page or add_page: + page_number: u8 + text: string + # Only available on Education Edition. + photo_name: string + if delete_page: + page_number: u8 + if swap_pages: + page1: u8 + page2: u8 + if sign: + title: string + author: string + xuid: string + + +# NPCRequest is sent by the client when it interacts with an NPC. +# The packet is specifically made for Education Edition, where NPCs are available to use. +packet_npc_request: + !id: 0x62 + !bound: both + # EntityRuntimeID is the runtime ID of the NPC entity that the player interacted with. It is the same + # as sent by the server when spawning the entity. + runtime_entity_id: varint64 + # RequestType is the type of the request, which depends on the permission that the player has. It will + # be either a type that indicates that the NPC should show its dialog, or that it should open the + # editing window. + request_type: u8 => + 0: set_actions + 1: execute_action + 2: execute_closing_commands + 3: set_name + 4: set_skin + 5: set_interaction_text + # CommandString is the command string set in the NPC. It may consist of multiple commands, depending on + # what the player set in it. + command: string + # ActionType is the type of the action to execute. + action_type: u8 => + 0: set_actions + 1: execute_action + 2: execute_closing_commands + 3: set_name + 4: set_skin + 5: set_interact_text + 6: execute_openining_commands + # SceneName is the name of the scene. + scene_name: string + +# PhotoTransfer is sent by the server to transfer a photo (image) file to the client. It is typically used +# to transfer photos so that the client can display it in a portfolio in Education Edition. +# While previously usable in the default Bedrock Edition, the displaying of photos in books was disabled and +# the packet now has little use anymore. +packet_photo_transfer: + !id: 0x63 + !bound: server + # PhotoName is the name of the photo to transfer. It is the exact file name that the client will download + # the photo as, including the extension of the file. + image_name: string + # PhotoData is the raw data of the photo image. The format of this data may vary: Formats such as JPEG or + # PNG work, as long as PhotoName has the correct extension. + image_data: string + # BookID is the ID of the book that the photo is associated with. If the PhotoName in a book with this ID + # is set to PhotoName, it will display the photo (provided Education Edition is used). + # The photo image is downloaded to a sub-folder with this book ID. + book_id: string + +# ModalFormRequest is sent by the server to make the client open a form. This form may be either a modal form +# which has two options, a menu form for a selection of options and a custom form for properties. +packet_modal_form_request: + !id: 0x64 + !bound: client + # FormID is an ID used to identify the form. The ID is saved by the client and sent back when the player + # submits the form, so that the server can identify which form was submitted. + form_id: varint + # FormData is a JSON encoded object of form data. The content of the object differs, depending on the + # type of the form sent, which is also set in the JSON. + data: string + +# ModalFormResponse is sent by the client in response to a ModalFormRequest, after the player has submitted +# the form sent. It contains the options/properties selected by the player, or a JSON encoded 'null' if +# the form was closed by clicking the X at the top right corner of the form. +packet_modal_form_response: + !id: 0x65 + !bound: server + # FormID is the form ID of the form the client has responded to. It is the same as the ID sent in the + # ModalFormRequest, and may be used to identify which form was submitted. + form_id: varint + # ResponseData is a JSON encoded value representing the response of the player. If the form was + # cancelled, a JSON encoded 'null' is in the response. For a modal form, the response is either true or + # false, for a menu form, the response is an integer specifying the index of the button clicked, and for + # a custom form, the response is an array containing a value for each element. + data: string + +# ServerSettingsRequest is sent by the client to request the settings specific to the server. These settings +# are shown in a separate tab client-side, and have the same structure as a custom form. +# ServerSettingsRequest has no fields. +packet_server_settings_request: + !id: 0x66 + !bound: server + +# ServerSettingsResponse is optionally sent by the server in response to a ServerSettingsRequest from the +# client. It is structured the same as a ModalFormRequest packet, and if filled out correctly, will show +# a specific tab for the server in the settings of the client. A ModalFormResponse packet is sent by the +# client in response to a ServerSettingsResponse, when the client fills out the settings and closes the +# settings again. +packet_server_settings_response: + !id: 0x67 + !bound: client + # FormID is an ID used to identify the form. The ID is saved by the client and sent back when the player + # submits the form, so that the server can identify which form was submitted. + form_id: varint + # FormData is a JSON encoded object of form data. The content of the object differs, depending on the + # type of the form sent, which is also set in the JSON. + data: string + +# ShowProfile is sent by the server to show the XBOX Live profile of one player to another. +packet_show_profile: + !id: 0x68 + !bound: client + # XUID is the XBOX Live User ID of the player whose profile should be shown to the player. If it is not + # a valid XUID, the client ignores the packet. + xuid: string + +# SetDefaultGameType is sent by the client when it toggles the default game type in the settings UI, and is +# sent by the server when it actually changes the default game type, resulting in the toggle being changed +# in the settings UI. +packet_set_default_game_type: + !id: 0x69 + !bound: client + # GameType is the new game type that is set. When sent by the client, this is the requested new default + # game type. + gamemode: GameMode + +# RemoveObjective is sent by the server to remove a scoreboard objective. It is used to stop showing a +# scoreboard to a player. +packet_remove_objective: + !id: 0x6a + !bound: client + # ObjectiveName is the name of the objective that the scoreboard currently active has. This name must + # be identical to the one sent in the SetDisplayObjective packet. + objective_name: string + +# SetDisplayObjective is sent by the server to display an object as a scoreboard to the player. Once sent, +# it should be followed up by a SetScore packet to set the lines of the packet. +packet_set_display_objective: + !id: 0x6b + !bound: client + # DisplaySlot is the slot in which the scoreboard should be displayed. Available options can be found in + # the constants above. + display_slot: string + # ObjectiveName is the name of the objective that the scoreboard displays. Filling out a random unique + # value for this field works: It is not displayed in the scoreboard. + objective_name: string + # DisplayName is the name, or title, that is displayed at the top of the scoreboard. + display_name: string + # CriteriaName is the name of the criteria that need to be fulfilled in order for the score to be + # increased. This can be any kind of string and does not show up client-side. + criteria_name: string + # SortOrder is the order in which entries on the scoreboard should be sorted. It is one of the constants + # that may be found above. + sort_order: zigzag32 + +# SetScore is sent by the server to send the contents of a scoreboard to the player. It may be used to either +# add, remove or edit entries on the scoreboard. +packet_set_score: + !id: 0x6c + !bound: client + # ActionType is the type of the action to execute upon the scoreboard with the entries that the packet + # has. If ActionType is ScoreboardActionModify, all entries will be added to the scoreboard if not yet + # present, or modified if already present. If set to ScoreboardActionRemove, all scoreboard entries set + # will be removed from the scoreboard. + action: u8 => + 0: change + 1: remove + entries: []varint + scoreboard_id: zigzag64 + objective_name: string + score: li32 + _: ../action ? + if change: + entry_type: i8 => + 1: player + 2: entity + 3: fake_player + entity_unique_id: entry_type ? + if player or entity: zigzag64 + custom_name: entry_type ? + if fake_player: string + +# LabTable is sent by the client to let the server know it started a chemical reaction in Education Edition, +# and is sent by the server to other clients to show the effects. +# The packet is only functional if Education features are enabled. +packet_lab_table: + !id: 0x6d + !bound: both + # ActionType is the type of the action that was executed. It is one of the constants above. Typically, + # only LabTableActionCombine is sent by the client, whereas LabTableActionReact is sent by the server. + action_type: u8 => + 0: combine + 1: react + # Position is the position at which the lab table used was located. + position: vec3u + # ReactionType is the type of the reaction that took place as a result of the items put into the lab + # table. The reaction type can be either that of an item or a particle, depending on whatever the result + # was of the reaction. + reaction_type: u8 + +# UpdateBlockSynced is sent by the server to synchronise the falling of a falling block entity with the +# transitioning back and forth from and to a solid block. It is used to prevent the entity from flickering, +# and is used in places such as the pushing of blocks with pistons. +packet_update_block_synced: + !id: 0x6e + !bound: client + # Position is the block position at which a block is updated. + position: BlockCoordinates + # NewBlockRuntimeID is the runtime ID of the block that is placed at Position after sending the packet + # to the client. + block_runtime_id: varint + # Flags is a combination of flags that specify the way the block is updated client-side. It is a + # combination of the flags above, but typically sending only the BlockUpdateNetwork flag is sufficient. + flags: UpdateBlockFlags + # Layer is the world layer on which the block is updated. For most blocks, this is the first layer, as + # that layer is the default layer to place blocks on, but for blocks inside of each other, this differs. + layer: varint + # EntityUniqueID is the unique ID of the falling block entity that the block transitions to or that the + # entity transitions from. + # Note that for both possible values for TransitionType, the EntityUniqueID should point to the falling + # block entity involved. + entity_unique_id: zigzag64 + # TransitionType is the type of the transition that happened. It is either BlockToEntityTransition, when + # a block placed becomes a falling entity, or EntityToBlockTransition, when a falling entity hits the + # ground and becomes a solid block again. + transition_type: varint64 => + # For falling sand, when a sand turns to an entity + 0: entity + # When sand turns back to a new block + 1: create + 2: destroy + + +# MoveActorDelta is sent by the server to move an entity. The packet is specifically optimised to save as +# much space as possible, by only writing non-zero fields. +# As of 1.16.100, this packet no longer actually contains any deltas. +packet_move_entity_delta: + !id: 0x6f + !bound: client + # EntityRuntimeID is the runtime ID of the entity that is being moved. The packet works provided a + # non-player entity with this runtime ID is present. + runtime_entity_id: varint64 + # Flags is a list of flags that specify what data is in the packet. + flags: DeltaMoveFlags + x: flags.has_x? + if true: lf32 + y: flags.has_y? + if true: lf32 + z: flags.has_z? + if true: lf32 + rot_x: flags.has_rot_x? + if true: u8 # TODO: * implement ByteFloat + rot_y: flags.has_rot_y? + if true: u8 + rot_z: flags.has_rot_z? + if true: u8 + +DeltaMoveFlags: [ "bitflags", + { + "type": "lu16", + "flags": { + "has_x": 0x01, + "has_y": 0x02, + "has_z": 0x04, + "has_rot_x": 0x08, + "has_rot_y": 0x10, + "has_rot_z": 0x20, + "on_ground": 0x40, + "teleport": 0x80, + "force_move": 0x100 + } + } +] + +# SetScoreboardIdentity is sent by the server to change the identity type of one of the entries on a +# scoreboard. This is used to change, for example, an entry pointing to a player, to a fake player when it +# leaves the server, and to change it back to a real player when it joins again. +# In non-vanilla situations, the packet is quite useless. +packet_set_scoreboard_identity: + !id: 0x70 + !bound: client + # ActionType is the type of the action to execute. The action is either ScoreboardIdentityActionRegister + # to associate an identity with the entry, or ScoreboardIdentityActionClear to remove associations with + # an entity. + action: i8 => + 0: register_identity + 1: clear_identity + # Entries is a list of all entries in the packet. Each of these entries points to one of the entries on + # a scoreboard. Depending on ActionType, their identity will either be registered or cleared. + entries: []varint + scoreboard_id: zigzag64 + entity_unique_id: ../action ? + if register_identity: zigzag64 + default: void + + +# SetLocalPlayerAsInitialised is sent by the client in response to a PlayStatus packet with the status set +# to spawn. The packet marks the moment at which the client is fully initialised and can receive any packet +# without discarding it. +packet_set_local_player_as_initialized: + !id: 0x71 + !bound: server + # EntityRuntimeID is the entity runtime ID the player was assigned earlier in the login sequence in the + # StartGame packet. + runtime_entity_id: varint64 + +packet_update_soft_enum: + !id: 0x72 + !bound: client + +# NetworkStackLatency is sent by the server (and the client, on development builds) to measure the latency +# over the entire Minecraft stack, rather than the RakNet latency. It has other usages too, such as the +# ability to be used as some kind of acknowledgement packet, to know when the client has received a certain +# other packet. +packet_network_stack_latency: + !id: 0x73 + !bound: both + # Timestamp is the timestamp of the network stack latency packet. The client will, if NeedsResponse is + # set to true, send a NetworkStackLatency packet with this same timestamp packet in response. + timestamp: lu64 + # NeedsResponse specifies if the sending side of this packet wants a response to the packet, meaning that + # the other side should send a NetworkStackLatency packet back. + needs_response: u8 + +# ScriptCustomEvent is sent by both the client and the server. It is a way to let scripts communicate with +# the server, so that the client can let the server know it triggered an event, or the other way around. +# It is essentially an RPC kind of system. +packet_script_custom_event: + !id: 0x75 + !bound: both + # EventName is the name of the event. The script and the server will use this event name to identify the + # data that is sent. + event_name: string + # EventData is the data of the event. This data is typically a JSON encoded string, that the script is + # able to encode and decode too. + event_data: string + +# SpawnParticleEffect is sent by the server to spawn a particle effect client-side. Unlike other packets that +# result in the appearing of particles, this packet can show particles that are not hardcoded in the client. +# They can be added and changed through behaviour packs to implement custom particles. +packet_spawn_particle_effect: + !id: 0x76 + !bound: client + # Dimension is the dimension that the particle is spawned in. Its exact usage is not clear, as the + # dimension has no direct effect on the particle. + dimension: u8 + # EntityUniqueID is the unique ID of the entity that the spawned particle may be attached to. If this ID + # is not -1, the Position below will be interpreted as relative to the position of the entity associated + # with this unique ID. + entity_id: zigzag64 + # Position is the position that the particle should be spawned at. If the position is too far away from + # the player, it will not show up. + # If EntityUniqueID is not -1, the position will be relative to the position of the entity. + position: vec3f + # ParticleName is the name of the particle that should be shown. This name may point to a particle effect + # that is built-in, or to one implemented by behaviour packs. + particle_name: string + +# AvailableActorIdentifiers is sent by the server at the start of the game to let the client know all +# entities that are available on the server. +packet_available_entity_identifiers: + !id: 0x77 + !bound: client + # SerialisedEntityIdentifiers is a network NBT serialised compound of all entity identifiers that are + # available in the server. + nbt: nbt + +# Not used. Use `packet_level_sound_event`. +packet_level_sound_event_v2: + !id: 0x78 + !bound: both + sound_id: u8 + position: vec3f + block_id: zigzag32 + entity_type: string + is_baby_mob: bool + is_global: bool + +# NetworkChunkPublisherUpdate is sent by the server to change the point around which chunks are and remain +# loaded. This is useful for mini-game servers, where only one area is ever loaded, in which case the +# NetworkChunkPublisherUpdate packet can be sent in the middle of it, so that no chunks ever need to be +# additionally sent during the course of the game. +# In reality, the packet is not extraordinarily useful, and most servers just send it constantly at the +# position of the player. +# If the packet is not sent at all, no chunks will be shown to the player, regardless of where they are sent. +packet_network_chunk_publisher_update: + !id: 0x79 + !bound: client + # Position is the block position around which chunks loaded will remain shown to the client. Most servers + # set this position to the position of the player itself. + coordinates: BlockCoordinates + # Radius is the radius in blocks around Position that chunks sent show up in and will remain loaded in. + # Unlike the RequestChunkRadius and ChunkRadiusUpdated packets, this radius is in blocks rather than + # chunks, so the chunk radius needs to be multiplied by 16. (Or shifted to the left by 4.) + radius: varint + +# BiomeDefinitionList is sent by the server to let the client know all biomes that are available and +# implemented on the server side. It is much like the AvailableActorIdentifiers packet, but instead +# functions for biomes. +packet_biome_definition_list: + !id: 0x7a + !bound: client + # SerialisedBiomeDefinitions is a network NBT serialised compound of all definitions of biomes that are + # available on the server. + nbt: nbt + +# LevelSoundEvent is sent by the server to make any kind of built-in sound heard to a player. It is sent to, +# for example, play a stepping sound or a shear sound. The packet is also sent by the client, in which case +# it could be forwarded by the server to the other players online. If possible, the packets from the client +# should be ignored however, and the server should play them on its own accord. +packet_level_sound_event: + !id: 0x7b + !bound: both + # SoundType is the type of the sound to play. Some of the sound types + # require additional data, which is set in the EventData field. + sound_id: SoundType + # Position is the position of the sound event. The player will be able to hear the direction of the sound + # based on what position is sent here. + position: vec3f + # ExtraData is a packed integer that some sound types use to provide extra data. An example of this is + # the note sound, which is composed of a pitch and an instrument type. + extra_data: zigzag32 + # EntityType is the string entity type of the entity that emitted the sound, for example + # 'minecraft:skeleton'. Some sound types use this entity type for additional data. + entity_type: string + # BabyMob specifies if the sound should be that of a baby mob. It is most notably used for parrot + # imitations, which will change based on if this field is set to true or not. + is_baby_mob: bool + # DisableRelativeVolume specifies if the sound should be played relatively or not. If set to true, the + # sound will have full volume, regardless of where the Position is, whereas if set to false, the sound's + # volume will be based on the distance to Position. + is_global: bool + +# LevelEventGeneric is sent by the server to send a 'generic' level event to the client. This packet sends an +# NBT serialised object and may for that reason be used for any event holding additional data. +packet_level_event_generic: + !id: 0x7c + !bound: client + # EventID is a unique identifier that identifies the event called. The data that follows has fields in + # the NBT depending on what event it is. + event_id: varint + # SerialisedEventData is a network little endian serialised object of event data, with fields that vary + # depending on EventID. + # Unlike many other NBT structures, this data is not actually in a compound but just loosely floating + # NBT tags. To decode using the nbt package, you would need to append 0x0a00 at the start (compound id + # and name length) and add 0x00 at the end, to manually wrap it in a compound. Likewise, you would have + # to remove these bytes when encoding. + nbt: nbtLoop + +# LecternUpdate is sent by the client to update the server on which page was opened in a book on a lectern, +# or if the book should be removed from it. +packet_lectern_update: + !id: 0x7d + !bound: client + # Page is the page number in the book that was opened by the player on the lectern. + page: u8 + # PageCount is the number of pages that the book opened in the lectern has. + page_count: u8 + # Position is the position of the lectern that was updated. If no lectern is at the block position, + # the packet should be ignored. + position: vec3i + # DropBook specifies if the book currently set on display in the lectern should be dropped server-side. + drop_book: bool + +# This packet was removed. +packet_video_stream_connect: + !id: 0x7e + !bound: client + server_uri: string + frame_send_frequency: lf32 + action: u8 + resolution_x: li32 + resolution_y: li32 + +# This is NOT a Minecraft entity, but an entity in the Entity Component System (ECS) +# for the game engine Minecrat Bedrock uses. Internally, all 'Minecraft entities' are +# known as Actors including in packet names and fields. However, these are irrelevant +# internal details so we don't do the renames in these protocol definitions, for simplicity we just use Entity. +# +# AddEntity is sent by the server to the client. Its function is not entirely clear: It does not add an +# entity in the sense of an in-game entity, but has to do with the ECS that Minecraft uses. +packet_add_ecs_entity: + !id: 0x7f + !bound: client + # EntityNetworkID is the network ID of the entity that should be added. + network_id: varint64 + +# RemoveEntity is sent by the server to the client. Its function is not entirely clear: It does not remove an +# entity in the sense of an in-game entity, but has to do with the ECS that Minecraft uses +packet_remove_ecs_entity: + !id: 0x80 + !bound: client + # EntityNetworkID is the network ID of the entity that should be removed. + network_id: varint64 + +# ClientCacheStatus is sent by the client to the server at the start of the game. It is sent to let the +# server know if it supports the client-side blob cache. Clients such as Nintendo Switch do not support the +# cache, and attempting to use it anyway will fail. +packet_client_cache_status: + !id: 0x81 + !bound: both + # Enabled specifies if the blob cache is enabled. If false, the server should not attempt to use the + # blob cache. If true, it may do so, but it may also choose not to use it. + enabled: bool + +# OnScreenTextureAnimation is sent by the server to show a certain animation on the screen of the player. +# The packet is used, as an example, for when a raid is triggered and when a raid is defeated. +packet_on_screen_texture_animation: + !id: 0x82 + !bound: client + # AnimationType is the type of the animation to show. The packet provides no further extra data to allow + # modifying the duration or other properties of the animation. + animation_type: lu32 + + +# MapCreateLockedCopy is sent by the server to create a locked copy of one map into another map. In vanilla, +# it is used in the cartography table to create a map that is locked and cannot be modified. +packet_map_create_locked_copy: + !id: 0x83 + !bound: client + # OriginalMapID is the ID of the map that is being copied. The locked copy will obtain all content that + # is visible on this map, except the content will not change. + original_map_id: zigzag64 + # NewMapID is the ID of the map that holds the locked copy of the map that OriginalMapID points to. Its + # contents will be impossible to change. + new_map_id: zigzag64 + + +# StructureTemplateDataRequest is sent by the client to request data of a structure. +packet_structure_template_data_export_request: + !id: 0x84 + !bound: client + # StructureName is the name of the structure that was set in the structure block's UI. This is the name + # used to export the structure to a file. + name: string + # Position is the position of the structure block that has its template data requested. + position: BlockCoordinates + # Settings is a struct of settings that should be used for exporting the structure. These settings are + # identical to the last sent in the StructureBlockUpdate packet by the client. + settings: StructureBlockSettings + # RequestType specifies the type of template data request that the player sent. + request_type: u8 => + 1: export_from_save + 2: export_from_load + 3: query_saved_structure + +# StructureTemplateDataResponse is sent by the server to send data of a structure to the client in response +# to a StructureTemplateDataRequest packet. +packet_structure_template_data_export_response: + !id: 0x85 + !bound: client + name: string + success: bool + nbt: success ? + if true: nbt + # ResponseType specifies the response type of the packet. This depends on the RequestType field sent in + # the StructureTemplateDataRequest packet and is one of the constants above. + response_type: u8 => + 1: export + 2: query + +# No longer used. +packet_update_block_properties: + !id: 0x86 + !bound: client + nbt: nbt + +# ClientCacheBlobStatus is part of the blob cache protocol. It is sent by the client to let the server know +# what blobs it needs and which blobs it already has, in an ACK type system. +packet_client_cache_blob_status: + !id: 0x87 + !bound: client + # The number of MISSes in this packet + misses: varint + # The number of HITs in this packet + haves: varint + # A list of blob hashes that the client does not have a blob available for. The server + # should send the blobs matching these hashes as soon as possible. + missing: lu64[]$misses + # A list of hashes that the client does have a cached blob for. Server doesn't need to send. + have: lu64[]$haves + +# ClientCacheMissResponse is part of the blob cache protocol. It is sent by the server in response to a +# ClientCacheBlobStatus packet and contains the blob data of all blobs that the client acknowledged not to +# have yet. +packet_client_cache_miss_response: + !id: 0x88 + !bound: client + blobs: Blob[]varint + +# EducationSettings is a packet sent by the server to update Minecraft: Education Edition related settings. +# It is unused by the normal base game. +packet_education_settings: + !id: 0x89 + !bound: client + # CodeBuilderDefaultURI is the default URI that the code builder is ran on. Using this, a Code Builder + # program can make code directly affect the server. + CodeBuilderDefaultURI: string + # CodeBuilderTitle is the title of the code builder shown when connected to the CodeBuilderDefaultURI. + CodeBuilderTitle: string + # CanResizeCodeBuilder specifies if clients connected to the world should be able to resize the code + # builder when it is opened. + CanResizeCodeBuilder: bool + HasOverrideURI: bool + OverrideURI: HasOverrideURI? + if true: string + # HasQuiz specifies if the world has a quiz connected to it. + HasQuiz: bool + +# MultiPlayerSettings is sent by the client to update multi-player related settings server-side and sent back +# to online players by the server. +# The MultiPlayerSettings packet is a Minecraft: Education Edition packet. It has no functionality for the +# base game. +packet_multiplayer_settings: + !id: 0x8b + !bound: server + # ActionType is the action that should be done when this packet is sent. It is one of the constants that + # may be found above. + action_type: zigzag32 => + 0: enable_multiplayer + 1: disable_multiplayer + 2: refresh_join_code + +# SettingsCommand is sent by the client when it changes a setting in the settings that results in the issuing +# of a command to the server, such as when Show Coordinates is enabled. +packet_settings_command: + !id: 0x8c + !bound: server + # CommandLine is the full command line that was sent to the server as a result of the setting that the + # client changed. + command_line: string + # SuppressOutput specifies if the client requests the suppressing of the output of the command that was + # executed. Generally this is set to true, as the client won't need a message to confirm the output of + # the change. + suppress_output: bool + +# AnvilDamage is sent by the client to request the dealing damage to an anvil. This packet is completely +# pointless and the server should never listen to it. +packet_anvil_damage: + !id: 0x8d + !bound: server + # Damage is the damage that the client requests to be dealt to the anvil. + damage: u8 + # AnvilPosition is the position in the world that the anvil can be found at. + position: BlockCoordinates + +# CompletedUsingItem is sent by the server to tell the client that it should be done using the item it is +# currently using. +packet_completed_using_item: + !id: 0x8e + !bound: client + # UsedItemID is the item ID of the item that the client completed using. This should typically be the + # ID of the item held in the hand. + used_item_id: li16 + # UseMethod is the method of the using of the item that was completed. It is one of the constants that + # may be found above. + use_method: li32 => + 0: equip_armor + 1: eat + 2: attack + 3: consume + 4: throw + 5: shoot + 6: place + 7: fill_bottle + 8: fill_bucket + 9: pour_bucket + 10: use_tool + 11: interact + 12: retrieved + 13: dyed + 14: traded + +# NetworkSettings is sent by the server to update a variety of network settings. These settings modify the +# way packets are sent over the network stack. +packet_network_settings: + !id: 0x8f + !bound: both + # CompressionThreshold is the minimum size of a packet that is compressed when sent. If the size of a + # packet is under this value, it is not compressed. + # When set to 0, all packets will be left uncompressed. + compression_threshold: u16 + + +# PlayerAuthInput is sent by the client to allow for server authoritative movement. It is used to synchronise +# the player input with the position server-side. +# The client sends this packet when the ServerAuthoritativeMovementMode field in the StartGame packet is set +# to true, instead of the MovePlayer packet. The client will send this packet once every tick. +packet_player_auth_input: + !id: 0x90 + !bound: server + # Pitch that the player reports it has. + pitch: lf32 + # Yaw that player reports it has. + yaw: lf32 + # Position holds the position that the player reports it has. + position: vec3f + # MoveVector is a Vec2 that specifies the direction in which the player moved, as a combination of X/Z + # values which are created using the WASD/controller stick state. + move_vector: vec2f + # HeadYaw is the horizontal rotation of the head that the player reports it has. + head_yaw: lf32 + # InputData is a combination of bit flags that together specify the way the player moved last tick. It + # is a combination of the flags above. + input_data: InputFlag + # InputMode specifies the way that the client inputs data to the screen. It is one of the constants that + # may be found above. + input_mode: varint => + 0: unknown + 1: mouse + 2: touch + 3: game_pad + 4: motion_controller + # PlayMode specifies the way that the player is playing. The values it holds, which are rather random, + # may be found above. + play_mode: varint => + 0: normal + 1: teaser + 2: screen + 3: viewer + 4: reality + 5: placement + 6: living_room + 7: exit_level + 8: exit_level_living_room + 9: num_modes + # GazeDirection is the direction in which the player is gazing, when the PlayMode is PlayModeReality: In + # other words, when the player is playing in virtual reality. + gaze_direction: play_mode ? + if reality: vec3f + # Tick is the server tick at which the packet was sent. It is used in relation to + # CorrectPlayerMovePrediction. + tick: varint64 + # Delta was the delta between the old and the new position. There isn't any practical use for this field + # as it can be calculated by the server itself. + delta: vec3f + transaction: input_data.item_interact ? + if true: + legacy: TransactionLegacy + actions: TransactionActions + data: TransactionUseItem + item_stack_request: input_data.item_stack_request ? + if true: ItemStackRequest + block_action: input_data.block_action ? + if true: []zigzag32 + action: Action + _: action? + if start_break or abort_break or crack_break or predict_break or continue_break: + # BlockPosition is the position of the target block, if the action with the ActionType set concerned a + # block. If that is not the case, the block position will be zero. + position: BlockCoordinates + # BlockFace is the face of the target block that was touched. If the action with the ActionType set + # concerned a block. If not, the face is always 0. + face: zigzag32 + +#TODO: update to use the new `shift` option in bitflags +InputFlag: [ "bitflags", { + "type": "varint64", "big": true, + "flags": [ + "ascend", + "descend", + "north_jump", + "jump_down", + "sprint_down", + "change_height", + "jumping", + "auto_jumping_in_water", + "sneaking", + "sneak_down", + "up", + "down", + "left", + "right", + "up_left", + "up_right", + "want_up", + "want_down", + "want_down_slow", + "want_up_slow", + "sprinting", + "ascend_block", + "descend_block", + "sneak_toggle_down", + "persist_sneak", + "start_sprinting", + "stop_sprinting", + "start_sneaking", + "stop_sneaking", + "start_swimming", + "stop_swimming", + "start_jumping", + "start_gliding", + "stop_gliding", + "item_interact", + "block_action", + "item_stack_request" + ] +}] + +# CreativeContent is a packet sent by the server to set the creative inventory's content for a player. +# Introduced in 1.16, this packet replaces the previous method - sending an InventoryContent packet with +# creative inventory window ID. +# As of v1.16.100, this packet must be sent during the login sequence. Not sending it will stop the client +# from joining the server. +packet_creative_content: + !id: 0x91 + !bound: client + # Items is a list of the items that should be added to the creative inventory. + items: []varint + entry_id: varint + item: ItemLegacy + +# PlayerEnchantOptions is sent by the server to update the enchantment options displayed when the user opens +# the enchantment table and puts an item in. This packet was added in 1.16 and allows the server to decide on +# the enchantments that can be selected by the player. +# The PlayerEnchantOptions packet should be sent once for every slot update of the enchantment table. The +# vanilla server sends an empty PlayerEnchantOptions packet when the player opens the enchantment table +# (air is present in the enchantment table slot) and sends the packet with actual enchantments in it when +# items are put in that can have enchantments. +packet_player_enchant_options: + !id: 0x92 + !bound: client + # Options is a list of possible enchantment options for the item that was put into the enchantment table. + options: EnchantOption[]varint + +# ItemStackRequest is sent by the client to change item stacks in an inventory. It is essentially a +# replacement of the InventoryTransaction packet added in 1.16 for inventory specific actions, such as moving +# items around or crafting. The InventoryTransaction packet is still used for actions such as placing blocks +# and interacting with entities. +packet_item_stack_request: + !id: 0x93 + !bound: server + requests: ItemStackRequest[]varint + +# ItemStackResponse is sent by the server in response to an ItemStackRequest packet from the client. This +# packet is used to either approve or reject ItemStackRequests from the client. If a request is approved, the +# client will simply continue as normal. If rejected, the client will undo the actions so that the inventory +# should be in sync with the server again. +packet_item_stack_response: + !id: 0x94 + !bound: client + # Responses is a list of responses to ItemStackRequests sent by the client before. Responses either + # approve or reject a request from the client. + # Vanilla limits the size of this slice to 4096. + responses: ItemStackResponses + +# PlayerArmourDamage is sent by the server to damage the armour of a player. It is a very efficient packet, +# but generally it's much easier to just send a slot update for the damaged armour. +packet_player_armor_damage: + !id: 0x95 + !bound: client + # Bitset holds a bitset of 4 bits that indicate which pieces of armour need to have damage dealt to them. + # The first bit, when toggled, is for a helmet, the second for the chestplate, the third for the leggings + # and the fourth for boots. + type: ArmorDamageType + helmet_damage: type.head ? + if true: zigzag32 + chestplate_damage: type.chest ? + if true: zigzag32 + leggings_damage: type.legs ? + if true: zigzag32 + boots_damage: type.feet ? + if true: zigzag32 + +ArmorDamageType: [ "bitflags", + { + "type": "u8", + "flags": { + "head": 0b1, + "chest": 0b10, + "legs": 0b100, + "feet": 0b1000 + } + } +] + +# UpdatePlayerGameType is sent by the server to change the game mode of a player. It is functionally +# identical to the SetPlayerGameType packet. +packet_update_player_game_type: + !id: 0x97 + !bound: server + # GameType is the new game type of the player. It is one of the constants that can be found in + # set_player_game_type.go. Some of these game types require additional flags to be set in an + # AdventureSettings packet for the game mode to obtain its full functionality. + gamemode: GameMode + # PlayerUniqueID is the entity unique ID of the player that should have its game mode updated. If this + # packet is sent to other clients with the player unique ID of another player, nothing happens. + player_unique_id: zigzag64 + + +# PositionTrackingDBClientRequest is a packet sent by the client to request the position and dimension of a +# 'tracking ID'. These IDs are tracked in a database by the server. In 1.16, this is used for lodestones. +# The client will send this request to find the position a lodestone compass needs to point to. If found, it +# will point to the lodestone. If not, it will start spinning around. +# A PositionTrackingDBServerBroadcast packet should be sent in response to this packet. +packet_position_tracking_db_request: + !id: 0x9a + !bound: server + # RequestAction is the action that should be performed upon the receiving of the packet. It is one of the + # constants found above. + action: u8 => + 0: query + # TrackingID is a unique ID used to identify the request. The server responds with a + # PositionTrackingDBServerBroadcast packet holding the same ID, so that the client can find out what that + # packet was in response to. + tracking_id: zigzag32 + +# PositionTrackingDBServerBroadcast is sent by the server in response to the +# PositionTrackingDBClientRequest packet. This packet is, as of 1.16, currently only used for lodestones. The +# server maintains a database with tracking IDs and their position and dimension. The client will request +# these tracking IDs, (NBT tag set on the lodestone compass with the tracking ID?) and the server will +# respond with the status of those tracking IDs. +# What is actually done with the data sent depends on what the client chooses to do with it. For the +# lodestone compass, it is used to make the compass point towards lodestones and to make it spin if the +# lodestone at a position is no longer there. +packet_position_tracking_db_broadcast: + !id: 0x99 + !bound: client + # BroadcastAction specifies the status of the position tracking DB response. It is one of the constants + # above, specifying the result of the request with the ID below. + # The Update action is sent for setting the position of a lodestone compass, the Destroy and NotFound to + # indicate that there is not (no longer) a lodestone at that position. + broadcast_action: u8 => + 0: update + 1: destory + 2: not_found + # TrackingID is the ID of the PositionTrackingDBClientRequest packet that this packet was in response to. + # The tracking ID is also present as the 'id' field in the SerialisedData field. + tracking_id: zigzag32 + nbt: nbt + +# PacketViolationWarning is sent by the client when it receives an invalid packet from the server. It holds +# some information on the error that occurred. +packet_packet_violation_warning: + !id: 0x9c + !bound: server + violation_type: zigzag32 => + 0: malformed + # Severity specifies the severity of the packet violation. The action the client takes after this + # violation depends on the severity sent. + severity: zigzag32 => + 0: warning + 1: final_warning + 2: terminating + # PacketID is the ID of the invalid packet that was received. + packet_id: zigzag32 + # ViolationContext holds a description on the violation of the packet. + reason: string + + +# MotionPredictionHints is sent by the server to the client. There is a predictive movement component for +# entities. This packet fills the "history" of that component and entity movement is computed based on the +# points. Vanilla sends this packet instead of the SetActorMotion packet when 'spatial optimisations' are +# enabled. +packet_motion_prediction_hints: + !id: 0x9d + !bound: client + # EntityRuntimeID is the runtime ID of the entity whose velocity is sent to the client. + entity_runtime_id: varint64 + # Velocity is the server-calculated velocity of the entity at the point of sending the packet. + velocity: vec3f + # OnGround specifies if the server currently thinks the entity is on the ground. + on_ground: bool + + +# AnimateEntity is sent by the server to animate an entity client-side. It may be used to play a single +# animation, or to activate a controller which can start a sequence of animations based on different +# conditions specified in an animation controller. +# Much of the documentation of this packet can be found at +# https://minecraft.gamepedia.com/Bedrock_Edition_beta_animation_documentation. +packet_animate_entity: + !id: 0x9e + !bound: client + # Animation is the name of a single animation to start playing. + animation: string + # NextState is the first state to start with. These states are declared in animation controllers (which, + # in themselves, are animations too). These states in turn may have animations and transitions to move to + # a next state. + next_state: string + # StopCondition is a MoLang expression that specifies when the animation should be stopped. + stop_condition: string + # Controller is the animation controller that is used to manage animations. These controllers decide when + # to play which animation. + controller: string + # How long to move from the previous animation to the next. + blend_out_time: lf32 + # EntityRuntimeIDs is list of runtime IDs of entities that the animation should be applied to. + runtime_entity_ids: varint64[]varint + +# CameraShake is sent by the server to make the camera shake client-side. This feature was added for map- +# making partners. +packet_camera_shake: + !id: 0x9f + !bound: client + # Intensity is the intensity of the shaking. The client limits this value to 4, so anything higher may + # not work. + intensity: lf32 + # Duration is the number of seconds the camera will shake for. + duration: lf32 + # Type is the type of shake, and is one of the constants listed above. The different type affects how + # the shake looks in game. + type: u8 + # Action is the action to be performed, and is one of the constants listed above. Currently the + # different actions will either add or stop shaking the client. + action: u8 => + 0: add + 1: stop + +# PlayerFog is sent by the server to render the different fogs in the Stack. The types of fog are controlled +# by resource packs to change how they are rendered, and the ability to create custom fog. +packet_player_fog: + !id: 0xa0 + !bound: client + # Stack is a list of fog identifiers to be sent to the client. Examples of fog identifiers are + # "minecraft:fog_ocean" and "minecraft:fog_hell". + stack: string[]varint + + +# CorrectPlayerMovePrediction is sent by the server if and only if StartGame.ServerAuthoritativeMovementMode +# is set to AuthoritativeMovementModeServerWithRewind. The packet is used to correct movement at a specific +# point in time. +packet_correct_player_move_prediction: + !id: 0xa1 + !bound: client + # Position is the position that the player is supposed to be at at the tick written in the field below. + # The client will change its current position based on movement after that tick starting from the + # Position. + position: vec3f + # Delta is the change in position compared to what the client sent as its position at that specific tick. + delta: vec3f + # OnGround specifies if the player was on the ground at the time of the tick below. + on_ground: bool + # Tick is the tick of the movement which was corrected by this packet. + tick: varint64 + +# ItemComponent is sent by the server to attach client-side components to a custom item. +packet_item_component: + !id: 0xa2 + !bound: client + # `entries` holds a list of all custom items with their respective components set. + entries: ItemComponentList + +# FilterText is sent by the both the client and the server. The client sends the packet to the server to +# allow the server to filter the text server-side. The server then responds with the same packet and the +# safer version of the text. +packet_filter_text_packet: + !id: 0xa3 + !bound: client + # Text is either the text from the client or the safer version of the text sent by the server. + text: string + # FromServer indicates if the packet was sent by the server or not. + from_server: bool + +# ClientBoundDebugRenderer is sent by the server to spawn an outlined cube on client-side. +packet_debug_renderer: + !id: 0xa4 + !bound: client + # Type is the type of action. It is one of the constants above. + type: li32 => + 1: clear + 2: add_cube + _: type ? + if clear: void + if add_cube: + # Text is the text that is displayed above the debug. + text: string + # Position is the position to spawn the debug on. + position: vec3f + # Red is the red value from the RGBA colour rendered on the debug. + red: lf32 + # Green is the green value from the RGBA colour rendered on the debug. + green: lf32 + # Blue is the blue value from the RGBA colour rendered on the debug. + blue: lf32 + # Alpha is the alpha value from the RGBA colour rendered on the debug. + alpha: lf32 + # Duration is how long the debug will last in the world for. It is measured in milliseconds. + duration: li64 + +# Sent by the server to synchronize/update entity properties as NBT, an alternative to Set Entity Data. +packet_sync_entity_property: + !id: 0xa5 + !bound: client + nbt: nbt + +# AddVolumeEntity sends a volume entity's definition and components from server to client. +packet_add_volume_entity: + !id: 0xa6 + !bound: client + # The Runtime Entity ID + entity_id: varint64 + nbt: nbt + +# RemoveVolumeEntity indicates a volume entity to be removed from server to client. +packet_remove_volume_entity: + !id: 0xa7 + !bound: client + # The Runtime Entity ID + entity_id: varint64 + +# SimulationType is an in-progress packet. We currently do not know the use case. +packet_simulation_type: + !id: 0xa8 + # SimulationType is the simulation type selected + type: u8 => + 0: game + 1: editor + 2: test + 3: invalid + +# NPCDialogue is a packet that allows the client to display dialog boxes for interacting with NPCs. +packet_npc_dialogue: + !id: 0xa9 + # ActorUniqueID is the ID of the NPC being requested. + entity_id: lu64 + # ActionType is the type of action for the packet. + action_type: varint => + 0: open + 1: close + # Dialogue is the text that the client should see. + dialogue: string + # SceneName is the scene the data was pulled from for the client. + screen_name: string + # NPCName is the name of the NPC to be displayed to the client. + npc_name: string + # ActionJSON is the JSON string of the buttons/actions the server can perform. + action_json: string \ No newline at end of file diff --git a/data/bedrock/latest/types.yml b/data/bedrock/latest/types.yml new file mode 100644 index 000000000..f88fba0e7 --- /dev/null +++ b/data/bedrock/latest/types.yml @@ -0,0 +1,1703 @@ +!StartDocs: Types + +BehaviourPackInfos: []li16 + uuid: string + version: string + size: lu64 + content_key: string + sub_pack_name: string + content_identity: string + has_scripts: bool + +TexturePackInfos: []li16 + uuid: string + version: string + size: lu64 + content_key: string + sub_pack_name: string + content_identity: string + has_scripts: bool + rtx_enabled: bool + +ResourcePackIdVersions: []varint + # The ID of the resource pack. + uuid: string + # The version of the resource pack. + version: string + # The subpack name of the resource pack. + name: string + +ResourcePackIds: string[]li16 + +Experiment: + name: string + enabled: bool + +Experiments: Experiment[]li32 + +GameMode: zigzag32 => + 0: survival + 1: creative + 2: adventure + 3: survival_spectator + 4: creative_spectator + 5: fallback + +GameRule: + name: string + editable: bool + type: varint => + 1: bool + 2: int + 3: float + value: type? + if bool: bool + if int: zigzag32 + if float: lf32 + +GameRules: GameRule[]varint + +# CacheBlob represents a blob as used in the client side blob cache protocol. It holds a hash of its data and +# the full data of it. +Blob: + # Hash is the hash of the blob. The hash is computed using xxHash, and must be deterministic for the same + # chunk data. + hash: lu64 + # Payload is the data of the blob. When sent, the client will associate the Hash of the blob with the + # Payload in it. + payload: ByteArray + +BlockProperties: []varint + name: string + state: nbt + +Itemstates: []varint + name: string + runtime_id: li16 + component_based: bool + + + +ItemExtraDataWithBlockingTick: + has_nbt: lu16 => + 0xffff: 'true' + 0x0000: 'false' + nbt: has_nbt ? + if true: + version: u8 + nbt: lnbt + default: void + can_place_on: ShortArray[]li32 + can_destroy: ShortArray[]li32 + blocking_tick: li64 + +ItemExtraDataWithoutBlockingTick: + has_nbt: lu16 => + 0xffff: 'true' + 0x0000: 'false' + nbt: has_nbt ? + if true: + version: u8 + nbt: lnbt + default: void + can_place_on: ShortArray[]li32 + can_destroy: ShortArray[]li32 + +# Same as below but without a "networkStackID" boolean +ItemLegacy: + network_id: zigzag32 + _: network_id? + if 0: void + default: + count: lu16 + metadata: varint + block_runtime_id: zigzag32 + extra: network_id ? + # The Shield Item ID is sent in the StartGame packet. It is usually 355 in vanilla. + if /ShieldItemID: '["encapsulated", { "lengthType": "varint", "type": "ItemExtraDataWithBlockingTick" }]' + default: '["encapsulated", { "lengthType": "varint", "type": "ItemExtraDataWithoutBlockingTick" }]' + +# An "ItemStack" here represents an Item instance. You can think about it like a pointer +# to an item class. The data for the class gets updated with the data in the `item` field +# As of 1.16.220, now functionally the same as `Item` just without an extra boolean when +# server auth inventories is disabled. +Item: + network_id: zigzag32 + _: network_id? + if 0: void + default: + count: lu16 + metadata: varint + # When server authoritative inventory is enabled, all allocated items have a unique ID used to identify + # a specifc item instance. + has_stack_id: u8 + # StackNetworkID is the network ID of this item *instance*. If the stack is empty, 0 is always written for this + # field. If not, the field should be set to 1 if the server authoritative inventories are disabled in the + # StartGame packet, or to a unique stack ID if it is enabled. + stack_id: has_stack_id ? + if 0: void + default: zigzag32 + block_runtime_id: zigzag32 + extra: network_id ? + # The Shield Item ID is sent in the StartGame packet. It is usually 355 in vanilla. + ## Really bad compiler hack to allow us to use a global variable + if /ShieldItemID: '["encapsulated", { "lengthType": "varint", "type": "ItemExtraDataWithBlockingTick" }]' + default: '["encapsulated", { "lengthType": "varint", "type": "ItemExtraDataWithoutBlockingTick" }]' + +vec3i: + x: zigzag32 + y: zigzag32 + z: zigzag32 + +vec3u: + x: varint + y: varint + z: varint + +vec3f: + x: lf32 + y: lf32 + z: lf32 + +vec2f: + x: lf32 + z: lf32 + +MetadataDictionary: []varint + # https://github.com/pmmp/PocketMine-MP/blob/stable/src/pocketmine/entity/Entity.php#L101 + key: varint => + 0: flags + 1: health #int (minecart/boat) + 2: variant #int + 3: color #byte + 4: nametag #string + 5: owner_eid #long + 6: target_eid #long + 7: air #short + 8: potion_color #int (ARGB!) + 9: potion_ambient #byte + 10: jump_duration #long + 11: hurt_time #int (minecart/boat) + 12: hurt_direction #int (minecart/boat) + 13: paddle_time_left #float + 14: paddle_time_right #float + 15: experience_value #int (xp orb) + 16: minecart_display_block #int (id | (data << 16)) + 17: minecart_display_offset #int + 18: minecart_has_display #byte (must be 1 for minecart to show block inside) + 20: old_swell + 21: swell_dir + 22: charge_amount + 23: enderman_held_runtime_id #short + 24: entity_age #short + 26: player_flags + 27: player_index + 28: player_bed_position #block coords + 29: fireball_power_x #float + 30: fireball_power_y + 31: fireball_power_z + 32: aux_power + 33: fish_x + 34: fish_z + 35: fish_angle + 36: potion_aux_value #short + 37: lead_holder_eid #long + 38: scale + 39: interactive_tag #string + 40: npc_skin_id #string + 41: url_tag #string + 42: max_airdata_max_air + 43: mark_variant #int + 44: container_type #byte + 45: container_base_size #int + 46: container_extra_slots_per_strength #int + 47: block_target + 48: wither_invulnerable_ticks #int + 49: wither_target_1 #long + 50: wither_target_2 #long + 51: wither_target_3 #long + 52: aerial_attack + 53: boundingbox_width + 54: boundingbox_height + 55: fuse_length + 56: rider_seat_position #vector3f + 57: rider_rotation_locked #byte + 58: rider_max_rotation #float + 59: rider_min_rotation #float + 60: rider_rotation_offset + 61: area_effect_cloud_radius #float + 62: area_effect_cloud_waiting #int + 63: area_effect_cloud_particle_id #int + 64: shulker_peek_id #int + 65: shulker_attach_face #byte + 66: shulker_attached #short + 67: shulker_attach_pos + 68: trading_player_eid #long + 69: trading_career + 70: has_command_block + 71: command_block_command #string + 72: command_block_last_output #string + 73: command_block_track_output #byte + 74: controlling_rider_seat_number #byte + 75: strength #int + 76: max_strength #int + 77: spell_casting_color #int + 78: limited_life + 79: armor_stand_pose_index # int + 80: ender_crystal_time_offset # int + 81: always_show_nametag # byte + 82: color_2 # byte + 83: name_author + 84: score_tag #String + 85: balloon_attached_entity # long + 86: pufferfish_size + 87: bubble_time + 88: agent + 89: sitting_amount + 90: sitting_amount_previous + 91: eating_counter + 92: flags_extended + 93: laying_amount + 94: laying_amount_previous + 95: duration + 96: spawn_time + 97: change_rate + 98: change_on_pickup + 99: pickup_count + 100: interact_text + 101: trade_tier + 102: max_trade_tier + 103: trade_experience + 104: skin_id + 105: spawning_frames + 106: command_block_tick_delay + 107: command_block_execute_on_first_tick + 108: ambient_sound_interval + 109: ambient_sound_interval_range + 110: ambient_sound_event_name + 111: fall_damage_multiplier + 112: name_raw_text + 113: can_ride_target + 114: low_tier_cured_discount + 115: high_tier_cured_discount + 116: nearby_cured_discount + 117: nearby_cured_discount_timestamp + 118: hitbox + 119: is_buoyant + 120: base_runtime_id + 121: freezing_effect_strength + 122: buoyancy_data + 123: goat_horn_count + 124: update_properties + type: varint => + 0: byte + 1: short + 2: int + 3: float + 4: string + 5: compound + 6: vec3i + 7: long + 8: vec3f + value: key ? + if flags: MetadataFlags1 + if flags_extended: MetadataFlags2 + default: type ? + if byte: i8 + if short: li16 + if int: zigzag32 + if float: lf32 + if string: string + if compound: nbt + if vec3i: vec3i + if long: zigzag64 + if vec3f: vec3f + +MetadataFlags1: [ "bitflags", { + "type": "zigzag64", + "big": true, + "flags": [ + "onfire", + "sneaking", + "riding", + "sprinting", + "action", + "invisible", + "tempted", + "inlove", + "saddled", + "powered", + "ignited", + "baby", + "converting", + "critical", + "can_show_nametag", + "always_show_nametag", + "no_ai", + "silent", + "wallclimbing", + "can_climb", + "swimmer", + "can_fly", + "walker", + "resting", + "sitting", + "angry", + "interested", + "charged", + "tamed", + "orphaned", + "leashed", + "sheared", + "gliding", + "elder", + "moving", + "breathing", + "chested", + "stackable", + "showbase", + "rearing", + "vibrating", + "idling", + "evoker_spell", + "charge_attack", + "wasd_controlled", + "can_power_jump", + "linger", + "has_collision", + "affected_by_gravity", + "fire_immune", + "dancing", + "enchanted", + "show_trident_rope", # tridents show an animated rope when enchanted with loyalty after they are thrown and return to their owner. to be combined with data_owner_eid + "container_private", #inventory is private, doesn't drop contents when killed if true + "transforming", + "spin_attack", + "swimming", + "bribed", #dolphins have this set when they go to find treasure for the player + "pregnant", + "laying_egg", + "rider_can_pick", #??? + "transition_sitting", + "eating", + "laying_down" + ] +}] + +MetadataFlags2: [ "bitflags", { + "type": "zigzag64", + "big": true, + "flags": [ + "sneezing", + "trusting", + "rolling", + "scared", + "in_scaffolding", + "over_scaffolding", + "fall_through_scaffolding", + "blocking", #shield + "transition_blocking", + "blocked_using_shield", + "blocked_using_damaged_shield", + "sleeping", + "wants_to_wake", + "trade_interest", + "door_breaker", #... + "breaking_obstruction", + "door_opener", #... + "illager_captain", + "stunned", + "roaring", + "delayed_attacking", + "avoiding_mobs", + "avoiding_block", + "facing_target_to_range_attack", + "hidden_when_invisible", #?????????????????? + "is_in_ui", + "stalking", + "emoting", + "celebrating", + "admiring", + "celebrating_special", + "unknown95", # 95 + "ram_attack", + "playing_dead" + ] +}] + +Link: + ridden_entity_id: zigzag64 + rider_entity_id: zigzag64 + type: u8 + immediate: bool + rider_initiated: bool + +Links: Link[]varint + +EntityAttributes: []varint + name: string + min: lf32 + value: lf32 + max: lf32 + +Rotation: + yaw: byterot + pitch: byterot + head_yaw: byterot + +BlockCoordinates: # mojang... + x: zigzag32 + y: varint + z: zigzag32 + +PlayerAttributes: []varint + min: lf32 + max: lf32 + current: lf32 + default: lf32 + name: string + +# UseItemTransactionData represents an inventory transaction data object sent when the client uses an item on +# a block. Also used in PlayerAuthoritativeInput packet +TransactionUseItem: + # ActionType is the type of the UseItem inventory transaction. It is one of the action types found above, + # and specifies the way the player interacted with the block. + action_type: varint => + 0: click_block + 1: click_air + 2: break_block + # BlockPosition is the position of the block that was interacted with. This is only really a correct + # block position if ActionType is not UseItemActionClickAir. + block_position: vec3i + # BlockFace is the face of the block that was interacted with. When clicking the block, it is the face + # clicked. When breaking the block, it is the face that was last being hit until the block broke. + face: varint + # HotBarSlot is the hot bar slot that the player was holding while clicking the block. It should be used + # to ensure that the hot bar slot and held item are correctly synchronised with the server. + hotbar_slot: varint + # HeldItem is the item that was held to interact with the block. The server should check if this item + # is actually present in the HotBarSlot. + held_item: Item + # Position is the position of the player at the time of interaction. For clicking a block, this is the + # position at that time, whereas for breaking the block it is the position at the time of breaking. + player_pos: vec3f + # ClickedPosition is the position that was clicked relative to the block's base coordinate. It can be + # used to find out exactly where a player clicked the block. + click_pos: vec3f + # BlockRuntimeID is the runtime ID of the block that was clicked. It may be used by the server to verify + # that the player's world client-side is synchronised with the server's. + block_runtime_id: varint + +# Actions is a list of actions that took place, that form the inventory transaction together. Each of +# these actions hold one slot in which one item was changed to another. In general, the combination of +# all of these actions results in a balanced inventory transaction. This should be checked to ensure that +# no items are cheated into the inventory. +TransactionActions: []varint + source_type: varint => + 0: container + 1: global + 2: world_interaction + 3: creative + 100: craft_slot + 99999: craft + _: source_type? + if container or craft: + inventory_id: WindowIDVarint + if world_interaction: + flags: varint + if craft or craft_slot: + action: varint + default: void + slot: varint + old_item: Item + new_item: Item + +# The Minecraft bedrock inventory system was refactored, but not all inventory actions use the new packet. +# This data structure holds actions that have not been updated to the new system. +TransactionLegacy: + # LegacyRequestID is an ID that is only non-zero at times when sent by the client. The server should + # always send 0 for this. When this field is not 0, the LegacySetItemSlots slice below will have values + # in it. + # LegacyRequestID ties in with the ItemStackResponse packet. If this field is non-0, the server should + # respond with an ItemStackResponse packet. Some inventory actions such as dropping an item out of the + # hotbar are still one using this packet, and the ItemStackResponse packet needs to tie in with it. + legacy_request_id: zigzag32 + # `legacy_transactions` are only present if the LegacyRequestID is non-zero. These item slots inform the + # server of the slots that were changed during the inventory transaction, and the server should send + # back an ItemStackResponse packet with these slots present in it. (Or false with no slots, if rejected.) + legacy_transactions: legacy_request_id? + if 0: void + default: []varint + container_id: u8 + changed_slots: []varint + slot_id: u8 + +Transaction: + # Old transaction system data + legacy: TransactionLegacy + # What type of transaction took place + transaction_type: varint => + 0: normal + 1: inventory_mismatch + 2: item_use + 3: item_use_on_entity + 4: item_release + # The list of inventory internal actions in this packet, e.g. inventory GUI actions + actions: TransactionActions + # Extra data if an intenal inventory transaction did not take place, e.g. use of an item + transaction_data: transaction_type? + if normal or inventory_mismatch: void + # UseItemTransactionData represents an inventory transaction data object sent when the client uses an item on + # a block. + if item_use: TransactionUseItem + # UseItemOnEntityTransactionData represents an inventory transaction data object sent when the client uses + # an item on an entity. + if item_use_on_entity: + # TargetEntityRuntimeID is the entity runtime ID of the target that was clicked. It is the runtime ID + # that was assigned to it in the AddEntity packet. + entity_runtime_id: varint64 + # ActionType is the type of the UseItemOnEntity inventory transaction. It is one of the action types + # found in the constants above, and specifies the way the player interacted with the entity. + action_type: varint => + 0: interact + 1: attack + # HotBarSlot is the hot bar slot that the player was holding while clicking the entity. It should be used + # to ensure that the hot bar slot and held item are correctly synchronised with the server. + hotbar_slot: zigzag32 + # HeldItem is the item that was held to interact with the entity. The server should check if this item + # is actually present in the HotBarSlot. + held_item: Item + # Position is the position of the player at the time of clicking the entity. + player_pos: vec3f + # ClickedPosition is the position that was clicked relative to the entity's base coordinate. It can be + # used to find out exactly where a player clicked the entity. + click_pos: vec3f + # ReleaseItemTransactionData represents an inventory transaction data object sent when the client releases + # the item it was using, for example when stopping while eating or stopping the charging of a bow. + if item_release: + # ActionType is the type of the ReleaseItem inventory transaction. It is one of the action types found + # in the constants above, and specifies the way the item was released. + # As of 1.13, the ActionType is always 0. This field can be ignored, because releasing food (by consuming + # it) or releasing a bow (to shoot an arrow) is essentially the same. + action_type: varint => + 0: release + 1: consume + # HotBarSlot is the hot bar slot that the player was holding while releasing the item. It should be used + # to ensure that the hot bar slot and held item are correctly synchronised with the server. + hotbar_slot: zigzag32 + # HeldItem is the item that was released. The server should check if this item is actually present in the + # HotBarSlot. + held_item: Item + # HeadPosition is the position of the player's head at the time of releasing the item. This is used + # mainly for purposes such as spawning eating particles at that position. + head_pos: vec3f + +ItemStacks: Item[]varint + +RecipeIngredient: + network_id: zigzag32 + _: network_id? + if 0: void + default: + network_data: zigzag32 + count: zigzag32 + +PotionTypeRecipes: []varint + input_item_id: zigzag32 + input_item_meta: zigzag32 + ingredient_id: zigzag32 + ingredient_meta: zigzag32 + output_item_id: zigzag32 + output_item_meta: zigzag32 + +PotionContainerChangeRecipes: []varint + input_item_id: zigzag32 + ingredient_id: zigzag32 + output_item_id: zigzag32 + +Recipes: []varint + type: zigzag32 => + 0: shapeless #'ENTRY_SHAPELESS', + 1: shaped #'ENTRY_SHAPED', + 2: furnace # 'ENTRY_FURNACE', + # `furnace_with_metadata` is a recipe specifically used for furnace-type crafting stations. It is equal to + # `furnace`, except it has an input item with a specific metadata value, instead of any metadata value. + 3: furnace_with_metadata # 'ENTRY_FURNACE_DATA', // has metadata + 4: multi #'ENTRY_MULTI', //TODO + 5: shulker_box #'ENTRY_SHULKER_BOX', //TODO + 6: shapeless_chemistry #'ENTRY_SHAPELESS_CHEMISTRY', //TODO + 7: shaped_chemistry #'ENTRY_SHAPED_CHEMISTRY', //TODO + recipe: type? + if shapeless or shulker_box or shapeless_chemistry: + recipe_id: string + input: RecipeIngredient[]varint + output: ItemLegacy[]varint + uuid: uuid + block: string + priority: zigzag32 + network_id: varint + if shaped or shaped_chemistry: + recipe_id: string + width: zigzag32 + height: zigzag32 + # 2D input array, size of width*height + input: []$width + _: RecipeIngredient[]$height + output: ItemLegacy[]varint + uuid: uuid + block: string + priority: zigzag32 + network_id: varint + if furnace: + input_id: zigzag32 + output: ItemLegacy + block: string + if furnace_with_metadata: + input_id: zigzag32 + input_meta: zigzag32 + output: ItemLegacy + block: string + if multi: + uuid: uuid + network_id: varint + +SkinImage: + width: li32 + height: li32 + data: ByteArray + +Skin: + skin_id: string + play_fab_id: string + skin_resource_pack: string + skin_data: SkinImage + animations: []li32 + skin_image: SkinImage + animation_type: li32 + animation_frames: lf32 + expression_type: lf32 + cape_data: SkinImage + geometry_data: string + animation_data: string + premium: bool + persona: bool + cape_on_classic: bool + cape_id: string + full_skin_id: string + arm_size: string + skin_color: string + personal_pieces: []li32 + piece_id: string + piece_type: string + pack_id: string + is_default_piece: bool + product_id: string + piece_tint_colors: []li32 + piece_type: string + colors: string[]li32 + +PlayerRecords: + type: u8 => + 0: add + 1: remove + records_count: varint + records: []$records_count + _: type? + if add: + uuid: uuid + entity_unique_id: zigzag64 + username: string + xbox_user_id: string + platform_chat_id: string + build_platform: li32 + skin_data: Skin + is_teacher: bool + is_host: bool + if remove: + uuid: uuid + verified: type ? + if add: bool[]$records_count + +Enchant: + id: u8 + level: u8 + +EnchantOption: + cost: varint + slot_flags: li32 + equip_enchants: Enchant[]varint + held_enchants: Enchant[]varint + self_enchants: Enchant[]varint + name: string + option_id: zigzag32 + +Action: zigzag32 => + 0: start_break + 1: abort_break + 2: stop_break + 3: get_updated_block + 4: drop_item + 5: start_sleeping + 6: stop_sleeping + 7: respawn + 8: jump + 9: start_sprint + 10: stop_sprint + 11: start_sneak + 12: stop_sneak + 13: creative_player_destroy_block + # sent when spawning in a different dimension to tell the server we spawned + 14: dimension_change_ack + 15: start_glide + 16: stop_glide + 17: build_denied + 18: crack_break + 19: change_skin + # no longer used + 20: set_enchatnment_seed + 21: swimming + 22: stop_swimming + 23: start_spin_attack + 24: stop_spin_attack + 25: interact_block + 26: predict_break + 27: continue_break + +# Source and Destination point to the source slot from which Count of the item stack were taken and the +# destination slot to which this item was moved. +StackRequestSlotInfo: + # ContainerID is the ID of the container that the slot was in. + slot_type: ContainerSlotType + # Slot is the index of the slot within the container with the ContainerID above. + slot: u8 + # StackNetworkID is the unique stack ID that the client assumes to be present in this slot. The server + # must check if these IDs match. If they do not match, servers should reject the stack request that the + # action holding this info was in. + stack_id: zigzag32 + +# ItemStackRequest is sent by the client to change item stacks in an inventory. It is essentially a +# replacement of the InventoryTransaction packet added in 1.16 for inventory specific actions, such as moving +# items around or crafting. The InventoryTransaction packet is still used for actions such as placing blocks +# and interacting with entities. +ItemStackRequest: + # RequestID is a unique ID for the request. This ID is used by the server to send a response for this + # specific request in the ItemStackResponse packet. + request_id: varint + actions: []varint + type_id: u8 => + # TakeStackRequestAction is sent by the client to the server to take x amount of items from one slot in a + # container to the cursor. + 0: take + # PlaceStackRequestAction is sent by the client to the server to place x amount of items from one slot into + # another slot, such as when shift clicking an item in the inventory to move it around or when moving an item + # in the cursor into a slot. + 1: place + # SwapStackRequestAction is sent by the client to swap the item in its cursor with an item present in another + # container. The two item stacks swap places. + 2: swap + # DropStackRequestAction is sent by the client when it drops an item out of the inventory when it has its + # inventory opened. This action is not sent when a player drops an item out of the hotbar using the Q button + # (or the equivalent on mobile). The InventoryTransaction packet is still used for that action, regardless of + # whether the item stack network IDs are used or not. + 3: drop + # DestroyStackRequestAction is sent by the client when it destroys an item in creative mode by moving it + # back into the creative inventory. + 4: destroy + # ConsumeStackRequestAction is sent by the client when it uses an item to craft another item. The original + # item is 'consumed'. + 5: consume + # CreateStackRequestAction is sent by the client when an item is created through being used as part of a + # recipe. For example, when milk is used to craft a cake, the buckets are leftover. The buckets are moved to + # the slot sent by the client here. + # Note that before this is sent, an action for consuming all items in the crafting table/grid is sent. Items + # that are not fully consumed when used for a recipe should not be destroyed there, but instead, should be + # turned into their respective resulting items. + 6: create + # LabTableCombineStackRequestAction is sent by the client when it uses a lab table to combine item stacks. + 7: lab_table_combine + # BeaconPaymentStackRequestAction is sent by the client when it submits an item to enable effects from a + # beacon. These items will have been moved into the beacon item slot in advance. + 8: beacon_payment + # MineBlockStackRequestAction is sent by the client when it breaks a block. + 9: mine_block + # CraftRecipeStackRequestAction is sent by the client the moment it begins crafting an item. This is the + # first action sent, before the Consume and Create item stack request actions. + # This action is also sent when an item is enchanted. Enchanting should be treated mostly the same way as + # crafting, where the old item is consumed. + 10: craft_recipe + # AutoCraftRecipeStackRequestAction is sent by the client similarly to the CraftRecipeStackRequestAction. The + # only difference is that the recipe is automatically created and crafted by shift clicking the recipe book. + 11: craft_recipe_auto #recipe book? + # CraftCreativeStackRequestAction is sent by the client when it takes an item out fo the creative inventory. + # The item is thus not really crafted, but instantly created. + 12: craft_creative + # CraftRecipeOptionalStackRequestAction is sent when using an anvil. When this action is sent, the + # CustomNames field in the respective stack request is non-empty and contains the name of the item created + # using the anvil. + 13: optional + # CraftNonImplementedStackRequestAction is an action sent for inventory actions that aren't yet implemented + # in the new system. These include, for example, anvils. + 14: non_implemented #anvils aren't fully implemented yet + # CraftResultsDeprecatedStackRequestAction is an additional, deprecated packet sent by the client after + # crafting. It holds the final results and the amount of times the recipe was crafted. It shouldn't be used. + # This action is also sent when an item is enchanted. Enchanting should be treated mostly the same way as + # crafting, where the old item is consumed. + 15: results_deprecated + _: type_id ? + if take or place: + count: u8 + source: StackRequestSlotInfo + destination: StackRequestSlotInfo + if swap: + # Source and Destination point to the source slot from which Count of the item stack were taken and the + # destination slot to which this item was moved. + source: StackRequestSlotInfo + destination: StackRequestSlotInfo + if drop: + # Count is the count of the item in the source slot that was taken towards the destination slot. + count: u8 + # Source is the source slot from which items were dropped to the ground. + source: StackRequestSlotInfo + # Randomly seems to be set to false in most cases. I'm not entirely sure what this does, but this is what + # vanilla calls this field. + randomly: bool + if destroy or consume: + # Count is the count of the item in the source slot that was destroyed. + count: u8 + # Source is the source slot from which items came that were destroyed by moving them into the creative + # inventory. + source: StackRequestSlotInfo + if create: + # ResultsSlot is the slot in the inventory in which the results of the crafting ingredients are to be + # placed. + result_slot_id: u8 + if beacon_payment: + # PrimaryEffect and SecondaryEffect are the effects that were selected from the beacon. + primary_effect: zigzag32 + secondary_effect: zigzag32 + if mine_block: + # // Unknown1 ... TODO: Find out what this is for + unknown1: zigzag32 + # PredictedDurability is the durability of the item that the client assumes to be present at the time + predicted_durability: zigzag32 + # StackNetworkID is the unique stack ID that the client assumes to be present at the time. The server + # must check if these IDs match. If they do not match, servers should reject the stack request that the + # action holding this info was in. + network_id: zigzag32 + if craft_recipe or craft_recipe_auto: + # RecipeNetworkID is the network ID of the recipe that is about to be crafted. This network ID matches + # one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as + # of 1.16. + recipe_network_id: varint + if craft_creative: + # The stack ID of the creative item that is being created. This is one of the + # creative item stack IDs sent in the CreativeContent packet. + item_id: varint + if optional: + # For the cartography table, if a certain MULTI recipe is being called, this points to the network ID that was assigned. + recipe_network_id: varint + # Most likely the index in the request's filter strings that this action is using + filtered_string_index: li32 + if non_implemented: void + if results_deprecated: + result_items: ItemLegacy[]varint + times_crafted: u8 + # CustomNames is a list of custom names involved in the request. This is typically filled with one string + # when an anvil is used. + # * Used for the server to determine which strings should be filtered. Used in anvils to verify a renamed item. + custom_names: string[]varint + +# ItemStackResponse is a response to an individual ItemStackRequest. +ItemStackResponses: []varint + # Status specifies if the request with the RequestID below was successful. If this is the case, the + # ContainerInfo below will have information on what slots ended up changing. If not, the container info + # will be empty. + # A non-0 status means an error occurred and will result in the action being reverted. + status: u8 => + 0: ok + 1: error + # RequestID is the unique ID of the request that this response is in reaction to. If rejected, the client + # will undo the actions from the request with this ID. + request_id: varint + _: status ? + if ok: + # ContainerInfo holds information on the containers that had their contents changed as a result of the + # request. + containers: []varint + # ContainerID is the container ID of the container that the slots that follow are in. For the main + # inventory, this value seems to be 0x1b. For the cursor, this value seems to be 0x3a. For the crafting + # grid, this value seems to be 0x0d. + # * actually, this is ContainerSlotType - used by the inventory system that specifies the type of slot + slot_type: ContainerSlotType + # SlotInfo holds information on what item stack should be present in specific slots in the container. + slots: []varint + # Slot and HotbarSlot seem to be the same value every time: The slot that was actually changed. I'm not + # sure if these slots ever differ. + slot: u8 + hotbar_slot: u8 + # Count is the total count of the item stack. This count will be shown client-side after the response is + # sent to the client. + count: u8 + # StackNetworkID is the network ID of the new stack at a specific slot. + item_stack_id: varint + # CustomName is the custom name of the item stack. It is used in relation to text filtering. + custom_name: string + # DurabilityCorrection is the current durability of the item stack. This durability will be shown + # client-side after the response is sent to the client. + durability_correction: zigzag32 + + +ItemComponentList: []varint + # Name is the name of the item, which is a name like 'minecraft:stick'. + name: string + # Data is a map containing the components and properties of the item. + nbt: nbt + +CommandOrigin: + # Origin is one of the values above that specifies the origin of the command. The origin may change, + # depending on what part of the client actually called the command. The command may be issued by a + # websocket server, for example. + type: varint => + 0: player + 1: block + 2: minecart_block + 3: dev_console + 4: test + 5: automation_player + 6: client_automation + 7: dedicated_server + 8: entity + 9: virtual + 10: game_argument + 11: entity_server + 12: precompiled + 13: game_director_entity_server # ? + 14: script + + # UUID is the UUID of the command called. This UUID is a bit odd as it is not specified by the server. It + # is not clear what exactly this UUID is meant to identify, but it is unique for each command called. + uuid: uuid + # RequestID is an ID that identifies the request of the client. The server should send a CommandOrigin + # with the same request ID to ensure it can be matched with the request by the caller of the command. + # This is especially important for websocket servers and it seems that this field is only non-empty for + # these websocket servers. + request_id: string + # PlayerUniqueID is an ID that identifies the player, the same as the one found in the AdventureSettings + # packet. Filling it out with 0 seems to work. + # PlayerUniqueID is only written if Origin is CommandOriginDevConsole or CommandOriginTest. + player_entity_id: type? + if dev_console or test: + player_entity_id: zigzag64 + +# MapTrackedObject is an object on a map that is 'tracked' by the client, such as an entity or a block. This +# object may move, which is handled client-side. +TrackedObject: + # Type is the type of the tracked object. It is either MapObjectTypeEntity or MapObjectTypeBlock. + type: li32 => + 0: entity + 1: block + # EntityUniqueID is the unique ID of the entity, if the tracked object was an entity. It needs not to be + # filled out if Type is not MapObjectTypeEntity. + entity_unique_id: type ? + if entity: zigzag64 + # BlockPosition is the position of the block, if the tracked object was a block. It needs not to be + # filled out if Type is not MapObjectTypeBlock. + block_position: type ? + if block: BlockCoordinates + +# MapDecoration is a fixed decoration on a map: Its position or other properties do not change automatically +# client-side. +MapDecoration: + type: u8 + # Rotation is the rotation of the map decoration. It is byte due to the 16 fixed directions that the + # map decoration may face. + rotation: u8 + # X is the offset on the X axis in pixels of the decoration. + x: u8 + # Y is the offset on the Y axis in pixels of the decoration. + y: u8 + # Label is the name of the map decoration. This name may be of any value. + label: string + # Colour is the colour of the map decoration. Some map decoration types have a specific colour set + # automatically, whereas others may be changed. + color_abgr: varint + + +StructureBlockSettings: + # PaletteName is the name of the palette used in the structure. Currently, it seems that this field is + # always 'default'. + palette_name: string + # IgnoreEntities specifies if the structure should ignore entities or include them. If set to false, + # entities will also show up in the exported structure. + ignore_entities: bool + # IgnoreBlocks specifies if the structure should ignore blocks or include them. If set to false, blocks + # will show up in the exported structure. + ignore_blocks: bool + # Size is the size of the area that is about to be exported. The area exported will start at the + # Position + Offset, and will extend as far as Size specifies. + size: BlockCoordinates + # Offset is the offset position that was set in the structure block. The area exported is offset by this + # position. + # **TODO**: This will be renamed to offset soon + structure_offset: BlockCoordinates + # LastEditingPlayerUniqueID is the unique ID of the player that last edited the structure block that + # these settings concern. + last_editing_player_unique_id: zigzag64 + # Rotation is the rotation that the structure block should obtain. See the constants above for available + # options. + rotation: u8 => + 0: none + 1: 90_deg + 2: 180_deg + 3: 270_deg + # Mirror specifies the way the structure should be mirrored. It is either no mirror at all, mirror on the + # x/z axis or both. + mirror: u8 => + 0: none + 1: x_axis + 2: z_axis + 3: both_axes + animation_mode: u8 => + 0: none + 1: layers + 2: blocks + # How long the duration for this animation is + animation_duration: lf32 + # Integrity is usually 1, but may be set to a number between 0 and 1 to omit blocks randomly, using + # the Seed that follows. + integrity: lf32 + # Seed is the seed used to omit blocks if Integrity is not equal to one. If the Seed is 0, a random + # seed is selected to omit blocks. + seed: lu32 + # Pivot is the pivot around which the structure may be rotated. + pivot: vec3f + +# List of Window IDs. When a new container is opened (container_open), a new sequential Window ID is created. +# Below window IDs are hard-coded and created when the game starts and the server does not +# send a `container_open` for them. +WindowID: i8 => + -100: drop_contents + -24: beacon + -23: trading_output + -22: trading_use_inputs + -21: trading_input_2 + -20: trading_input_1 + -17: enchant_output + -16: enchant_material + -15: enchant_input + -13: anvil_output + -12: anvil_result + -11: anvil_material + -10: container_input + -5: crafting_use_ingredient + -4: crafting_result + -3: crafting_remove_ingredient + -2: crafting_add_ingredient + -1: none + 0: inventory + 1: first + 100: last + 119: offhand + 120: armor + 121: creative + 122: hotbar + 123: fixed_inventory + 124: ui + +WindowIDVarint: varint => + -100: drop_contents + -24: beacon + -23: trading_output + -22: trading_use_inputs + -21: trading_input_2 + -20: trading_input_1 + -17: enchant_output + -16: enchant_material + -15: enchant_input + -13: anvil_output + -12: anvil_result + -11: anvil_material + -10: container_input + -5: crafting_use_ingredient + -4: crafting_result + -3: crafting_remove_ingredient + -2: crafting_add_ingredient + -1: none + 0: inventory + 1: first + 100: last + 119: offhand + 120: armor + 121: creative + 122: hotbar + 123: fixed_inventory + 124: ui + +WindowType: i8 => + -9: none + -1: inventory + 0: container + 1: workbench + 2: furnace + 3: enchantment + 4: brewing_stand + 5: anvil + 6: dispenser + 7: dropper + 8: hopper + 9: cauldron + 10: minecart_chest + 11: minecart_hopper + 12: horse + 13: beacon + 14: structure_editor + 15: trading + 16: command_block + 17: jukebox + 18: armor + 19: hand + 20: compound_creator + 21: element_constructor + 22: material_reducer + 23: lab_table + 24: loom + 25: lectern + 26: grindstone + 27: blast_furnace + 28: smoker + 29: stonecutter + 30: cartography + 31: hud + 32: jigsaw_editor + 33: smithing_table + +# Used in inventory transactions. +ContainerSlotType: u8 => + - anvil_input + - anvil_material + - anvil_result + - smithing_table_input + - smithing_table_material + - smithing_table_result + - armor + - container + - beacon_payment + - brewing_input + - brewing_result + - brewing_fuel + - hotbar_and_inventory + - crafting_input + - crafting_output + - recipe_construction + - recipe_nature + - recipe_items + - recipe_search + - recipe_search_bar + - recipe_equipment + - enchanting_input + - enchanting_lapis + - furnace_fuel + - furnace_ingredient + - furnace_output + - horse_equip + - hotbar + - inventory + - shulker + - trade_ingredient1 + - trade_ingredient2 + - trade_result + - offhand + - compcreate_input + - compcreate_output + - elemconstruct_output + - matreduce_input + - matreduce_output + - labtable_input + - loom_input + - loom_dye + - loom_material + - loom_result + - blast_furnace_ingredient + - smoker_ingredient + - trade2_ingredient1 + - trade2_ingredient2 + - trade2_result + - grindstone_input + - grindstone_additional + - grindstone_result + - stonecutter_input + - stonecutter_result + - cartography_input + - cartography_additional + - cartography_result + - barrel + - cursor + - creative_output + +SoundType: varint => + - ItemUseOn + - Hit + - Step + - Fly + - Jump + - Break + - Place + - HeavyStep + - Gallop + - Fall + - Ambient + - AmbientBaby + - AmbientInWater + - Breathe + - Death + - DeathInWater + - DeathToZombie + - Hurt + - HurtInWater + - Mad + - Boost + - Bow + - SquishBig + - SquishSmall + - FallBig + - FallSmall + - Splash + - Fizz + - Flap + - Swim + - Drink + - Eat + - Takeoff + - Shake + - Plop + - Land + - Saddle + - Armor + - MobArmorStandPlace + - AddChest + - Throw + - Attack + - AttackNoDamage + - AttackStrong + - Warn + - Shear + - Milk + - Thunder + - Explode + - Fire + - Ignite + - Fuse + - Stare + - Spawn + - Shoot + - BreakBlock + - Launch + - Blast + - LargeBlast + - Twinkle + - Remedy + - Infect + - LevelUp + - BowHit + - BulletHit + - ExtinguishFire + - ItemFizz + - ChestOpen + - ChestClosed + - ShulkerBoxOpen + - ShulkerBoxClosed + - EnderChestOpen + - EnderChestClosed + - PowerOn + - PowerOff + - Attach + - Detach + - Deny + - Tripod + - Pop + - DropSlot + - Note + - Thorns + - PistonIn + - PistonOut + - Portal + - Water + - LavaPop + - Lava + - Burp + - BucketFillWater + - BucketFillLava + - BucketEmptyWater + - BucketEmptyLava + - ArmorEquipChain + - ArmorEquipDiamond + - ArmorEquipGeneric + - ArmorEquipGold + - ArmorEquipIron + - ArmorEquipLeather + - ArmorEquipElytra + - Record13 + - RecordCat + - RecordBlocks + - RecordChirp + - RecordFar + - RecordMall + - RecordMellohi + - RecordStal + - RecordStrad + - RecordWard + - Record11 + - RecordWait + - unknown1 + - Flop + - ElderGuardianCurse + - MobWarning + - MobWarningBaby + - Teleport + - ShulkerOpen + - ShulkerClose + - Haggle + - HaggleYes + - HaggleNo + - HaggleIdle + - ChorusGrow + - ChorusDeath + - Glass + - PotionBrewed + - CastSpell + - PrepareAttack + - PrepareSummon + - PrepareWololo + - Fang + - Charge + - CameraTakePicture + - LeashKnotPlace + - LeashKnotBreak + - Growl + - Whine + - Pant + - Purr + - Purreow + - DeathMinVolume + - DeathMidVolume + - unknown2 + - ImitateCaveSpider + - ImitateCreeper + - ImitateElderGuardian + - ImitateEnderDragon + - ImitateEnderman + - unknown3 + - ImitateEvocationIllager + - ImitateGhast + - ImitateHusk + - ImitateIllusionIllager + - ImitateMagmaCube + - ImitatePolarBear + - ImitateShulker + - ImitateSilverfish + - ImitateSkeleton + - ImitateSlime + - ImitateSpider + - ImitateStray + - ImitateVex + - ImitateVindicationIllager + - ImitateWitch + - ImitateWither + - ImitateWitherSkeleton + - ImitateWolf + - ImitateZombie + - ImitateZombiePigman + - ImitateZombieVillager + - BlockEndPortalFrameFill + - BlockEndPortalSpawn + - RandomAnvilUse + - BottleDragonBreath + - PortalTravel + - ItemTridentHit + - ItemTridentReturn + - ItemTridentRiptide1 + - ItemTridentRiptide2 + - ItemTridentRiptide3 + - ItemTridentThrow + - ItemTridentThunder + - ItemTridentHitGround + - Default + - BlockFletchingTableUse + - ElemConstructOpen + - IceBombHit + - BalloonPop + - LtReactionIceBomb + - LtReactionBleach + - LtReactionEPaste + - LtReactionEPaste2 + - LtReactionFertilizer + - LtReactionFireball + - LtReactionMgsalt + - LtReactionMiscfire + - LtReactionFire + - LtReactionMiscexplosion + - LtReactionMiscmystical + - LtReactionMiscmystical2 + - LtReactionProduct + - SparklerUse + - GlowstickUse + - SparklerActive + - ConvertToDrowned + - BucketFillFish + - BucketEmptyFish + - BubbleUp + - BubbleDown + - BubblePop + - BubbleUpInside + - BubbleDownInside + - HurtBaby + - DeathBaby + - StepBaby + - BabySpawn + - Born + - BlockTurtleEggBreak + - BlockTurtleEggCrack + - BlockTurtleEggHatch + - TurtleLayEgg + - BlockTurtleEggAttack + - BeaconActivate + - BeaconAmbient + - BeaconDeactivate + - BeaconPower + - ConduitActivate + - ConduitAmbient + - ConduitAttack + - ConduitDeactivate + - ConduitShort + - Swoop + - BlockBambooSaplingPlace + - PreSneeze + - Sneeze + - AmbientTame + - Scared + - BlockScaffoldingClimb + - CrossbowLoadingStart + - CrossbowLoadingMiddle + - CrossbowLoadingEnd + - CrossbowShoot + - CrossbowQuickChargeStart + - CrossbowQuickChargeMiddle + - CrossbowQuickChargeEnd + - AmbientAggressive + - AmbientWorried + - CantBreed + - ItemShieldBlock + - ItemBookPut + - BlockGrindstoneUse + - BlockBellHit + - BlockCampfireCrackle + - Roar + - Stun + - BlockSweetBerryBushHurt + - BlockSweetBerryBushPick + - UICartographyTableTakeResult + - UIStoneCutterTakeResult + - BlockComposterEmpty + - BlockComposterFill + - BlockComposterFillSuccess + - BlockComposterReady + - BlockBarrelOpen + - BlockBarrelClose + - RaidHorn + - BlockLoomUse + - AmbientRaid + - UICartographyTableUse + - UIStoneCutterUse + - UILoomUse + - SmokerUse + - BlastFurnaceUse + - SmithingTableUse + - Screech + - Sleep + - FurnaceUse + - MooshroomConvert + - MilkSuspiciously + - Celebrate + - JumpPrevent + - AmbientPollinate + - BeeHiveDrip + - BeeHiveEnter + - BeeHiveExit + - BeeHiveWork + - BeeHiveShear + - HoneyBottleDrink + - AmbientCave + - Retreat + - ConvertToZombified + - Admire + - StepLava + - Tempt + - Panic + - Angry + - AmbientWarpedForest + - AmbientSoulsandValley + - AmbientNetherWastes + - AmbientBasaltDeltas + - AmbientCrimsonForest + - RespawnAnchorCharge + - RespawnAnchorDeplete + - RespawnAnchorSetSpawn + - RespawnAnchorAmbient + - SoulEscapeQuiet + - SoulEscapeLoud + - RecordPigstep + - LinkCompassToLodestone + - BlockSmithingTableUse + - EquipNetherite + - AmbientLoopWarpedForest + - AmbientLoopSoulsandValley + - AmbientLoopNetherWastes + - AmbientLoopBasaltDeltas + - AmbientLoopCrimsonForest + - AmbientAdditionWarpedForest + - AmbientAdditionSoulsandValley + - AmbientAdditionNetherWastes + - AmbientAdditionBasaltDeltas + - AmbientAdditionCrimsonForest + - SculkSensorPowerOn + - SculkSensorPowerOff + - BucketFillPowderSnow + - BucketEmptyPowderSnow + - PointedDripstoneCauldronDripWater + - PointedDripstoneCauldronDripLava + - PointedDripstoneDripWater + - PointedDripstoneDripLava + - CaveVinesPickBerries + - BigDripleafTiltDown + - BigDripleafTiltUp + - unknown335 + - unknown336 + - unknown337 + - unknown338 + - copper_wax_on + - copper_wax_off + - scrape + - player_hurt_drown + - player_hurt_on_fire + - player_hurt_freeze + - use_spyglass + - stop_using_spyglass + - amethyst_block_chime + - ambient_screamer + - hurt_screamer + - death_screamer + - milk_screamer + - jump_to_block + - pre_ram + - pre_ram_screamer + - ram_impact + - ram_impact_screamer + - squid_ink_squirt + - glow_squid_ink_squirt + - convert_to_stray + - extinguish_candle + - ambient_candle + - Undefined + +# TODO: remove? +LegacyEntityType: li32 => + 10: chicken + 11: cow + 12: pig + 13: sheep + 14: wolf + 15: villager + 16: mooshroom + 17: squid + 18: rabbit + 19: bat + 20: iron_golem + 21: snow_golem + 22: ocelot + 23: horse + 24: donkey + 25: mule + 26: skeleton_horse + 27: zombie_horse + 28: polar_bear + 29: llama + 30: parrot + 31: dolphin + 32: zombie + 33: creeper + 34: skeleton + 35: spider + 36: zombie_pigman + 37: slime + 38: enderman + 39: silverfish + 40: cave_spider + 41: ghast + 42: magma_cube + 43: blaze + 44: zombie_villager + 45: witch + 46: stray + 47: husk + 48: wither_skeleton + 49: guardian + 50: elder_guardian + 51: npc + 52: wither + 53: ender_dragon + 54: shulker + 55: endermite + 56: agent # LEARN_TO_CODE_MASCOT + 57: vindicator + 58: phantom + 61: armor_stand + 62: tripod_camera + 63: player + 64: item + 65: tnt + 66: falling_block + 67: moving_block + 68: xp_bottle + 69: xp_orb + 70: eye_of_ender_signal + 71: ender_crystal + 72: fireworks_rocket + 73: thrown_trident + 74: turtle + 75: cat + 76: shulker_bullet + 77: fishing_hook + 78: chalkboard + 79: dragon_fireball + 80: arrow + 81: snowball + 82: egg + 83: painting + 84: minecart + 85: fireball + 86: splash_potion + 87: ender_pearl + 88: leash_knot + 89: wither_skull + 90: boat + 91: wither_skull_dangerous + 93: lightning_bolt + 94: small_fireball + 95: area_effect_cloud + 96: hopper_minecart + 97: tnt_minecart + 98: chest_minecart + 100: command_block_minecart + 101: lingering_potion + 102: llama_spit + 103: evocation_fang + 104: evocation_illager + 105: vex + 106: ice_bomb + 107: balloon + 108: pufferfish + 109: salmon + 110: drowned + 111: tropicalfish + 112: cod + 113: panda \ No newline at end of file diff --git a/tools/js/compileProtocol.js b/tools/js/compileProtocol.js new file mode 100644 index 000000000..2245c978c --- /dev/null +++ b/tools/js/compileProtocol.js @@ -0,0 +1,60 @@ +/** + * This is a utility script that converts the YAML here into ProtoDef schema code + * You can run this with `npm run build` + */ +const fs = require('fs') +const { join } = require('path') + +function getJSON (path) { + return JSON.parse(fs.readFileSync(path, 'utf-8')) +} + +// Parse the YML files and turn to JSON +function genProtoSchema () { + const { parse, compile } = require('protodef-yaml') + + // Create the packet_map.yml from proto.yml + const parsed = parse('./proto.yml') + const version = parsed['!version'] + const packets = [] + for (const key in parsed) { + if (key.startsWith('%container')) { + const [, name] = key.split(',') + if (name.startsWith('packet_')) { + const children = parsed[key] + const packetName = name.replace('packet_', '') + const packetID = children['!id'] + packets.push([packetID, packetName, name]) + } + } + } + let l1 = '' + let l2 = '' + for (const [id, name, fname] of packets) { + l1 += ` 0x${id.toString(16).padStart(2, '0')}: ${name}\n` + l2 += ` if ${name}: ${fname}\n` + } + // TODO: skip creating packet_map.yml and just generate the ProtoDef map JSON directly + const t = `#Auto-generated from proto.yml, do not modify\n!import: types.yml\nmcpe_packet:\n name: varint =>\n${l1}\n params: name ?\n${l2}` + fs.writeFileSync('./packet_map.yml', t) + + compile('./proto.yml', 'proto.json') + return version +} + +function convert (ver) { + process.chdir(join(__dirname, '../../data/bedrock/' + ver)) + const version = genProtoSchema() + try { fs.mkdirSync(`../${version}`) } catch {} + fs.writeFileSync(`../${version}/protocol.json`, JSON.stringify({ types: getJSON('./proto.json') }, null, 2)) + fs.unlinkSync('./proto.json') // remove temp file + fs.unlinkSync('./packet_map.yml') // remove temp file + return version +} + +// If no argument, build everything +if (!process.argv[2]) { + convert('latest') +} else { // build the specified version + convert(process.argv[2]) +} diff --git a/tools/js/package.json b/tools/js/package.json index 2b1fb7dfb..a8d7398db 100644 --- a/tools/js/package.json +++ b/tools/js/package.json @@ -6,12 +6,14 @@ "test": "mocha --reporter spec", "lint": "standard", "fix": "standard --fix", - "pretest": "npm run lint" + "pretest": "npm run lint", + "build": "node ./compileProtocol.js" }, "dependencies": { "ajv": "^6.5.4", "mocha": "5.2.0", "protodef-validator": "^1.2.2", - "standard": "^12.0.1" + "protodef-yaml": "^1.2.2", + "standard": "^16.0.3" } } From 11efed5c5e0bf4dab554759395cff6b2714d0379 Mon Sep 17 00:00:00 2001 From: extremeheat Date: Sun, 8 Aug 2021 21:39:26 -0400 Subject: [PATCH 2/3] Create bedrock.yml --- .github/workflows/bedrock.yml | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .github/workflows/bedrock.yml diff --git a/.github/workflows/bedrock.yml b/.github/workflows/bedrock.yml new file mode 100644 index 000000000..f01711545 --- /dev/null +++ b/.github/workflows/bedrock.yml @@ -0,0 +1,53 @@ +on: + pull_request: + paths: + - '*bedrock*' + issue_comment: + types: [created] + +jobs: + debug: + runs-on: ubuntu-latest + steps: + - uses: hmarr/debug-action@v2 + + # commentTest: + # runs-on: ubuntu-latest + # outputs: + # ok: ${{ steps.check.outputs.triggered }} + # steps: + # # Check if we were triggered by a comment + # - uses: khan/pull-request-comment-trigger@master + # id: check + # with: + # trigger: '/rerun' + # reaction: thumbsup + # env: + # GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + + # test: + # runs-on: ubuntu-latest + # needs: commentTest + # if: {{ needs.commentTest.outputs.ok == 'true' || github.event.action == 'unassigned' }} + # steps: + + # - uses: actions/checkout@v2 + # # - uses: actions-ecosystem/action-regex-match@v2 + # - run: npm install + # working-directory: tools/js + # - run: npm build + # working-directory: tools/js + # - name: Comment PR + # uses: unsplash/comment-on-pr@master + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # msg: 'Running tests in bedrock-protocol...' + # check_for_duplicate_msg: false # OPTIONAL + # - uses: convictional/trigger-workflow-and-wait@v1.3.0 + # with: + # owner: extremeheat + # repo: bedrock-protocol + # waiting_interval: 60 + # inputs: '{"via": "minecraft-data", "reason": "PR"}' + # github_token: ${{ secrets.PAT_PASSWORD }} From 399b6fdf0d6fff17eb289192bd5338ab3adc92f4 Mon Sep 17 00:00:00 2001 From: extremeheat Date: Sun, 8 Aug 2021 21:40:59 -0400 Subject: [PATCH 3/3] Update proto.yml --- data/bedrock/latest/proto.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/bedrock/latest/proto.yml b/data/bedrock/latest/proto.yml index d2998d140..69cade42e 100644 --- a/data/bedrock/latest/proto.yml +++ b/data/bedrock/latest/proto.yml @@ -2,7 +2,7 @@ # The version below is the latest version this protocol schema was updated for. # The output protocol.json will be in the folder for the version !version: 1.17.10 - +# # Some ProtoDef aliases string: ["pstring",{"countType":"varint"}] # String / array types ByteArray: ["buffer",{"countType":"varint"}] @@ -3168,4 +3168,4 @@ packet_npc_dialogue: # NPCName is the name of the NPC to be displayed to the client. npc_name: string # ActionJSON is the JSON string of the buttons/actions the server can perform. - action_json: string \ No newline at end of file + action_json: string