diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..cd19a23 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +data/*/*.json linguist-generated \ No newline at end of file diff --git a/data/1.16.220/protocol.json b/data/1.16.220/protocol.json index d12afd5..e859abd 100644 --- a/data/1.16.220/protocol.json +++ b/data/1.16.220/protocol.json @@ -956,100 +956,92 @@ ] ], "TransactionActions": [ - "container", - [ - { - "name": "actions", - "type": [ - "array", + "array", + { + "countType": "varint", + "type": [ + "container", + [ { - "countType": "varint", + "name": "source_type", "type": [ - "container", - [ - { - "name": "source_type", - "type": [ - "mapper", - { - "type": "varint", - "mappings": { - "0": "container", - "1": "global", - "2": "world_interaction", - "3": "creative", - "100": "craft_slot", - "99999": "craft" - } - } - ] - }, - { - "anon": true, - "type": [ - "switch", - { - "compareTo": "source_type", - "fields": { - "container": [ - "container", - [ - { - "name": "inventory_id", - "type": "varint" - } - ] - ], - "craft": [ - "container", - [ - { - "name": "action", - "type": "varint" - } - ] - ], - "world_interaction": [ - "container", - [ - { - "name": "flags", - "type": "varint" - } - ] - ], - "craft_slot": [ - "container", - [ - { - "name": "action", - "type": "varint" - } - ] - ] - }, - "default": "void" - } - ] - }, - { - "name": "slot", - "type": "varint" - }, - { - "name": "old_item", - "type": "Item" - }, - { - "name": "new_item", - "type": "Item" + "mapper", + { + "type": "varint", + "mappings": { + "0": "container", + "1": "global", + "2": "world_interaction", + "3": "creative", + "100": "craft_slot", + "99999": "craft" } - ] + } ] + }, + { + "anon": true, + "type": [ + "switch", + { + "compareTo": "source_type", + "fields": { + "container": [ + "container", + [ + { + "name": "inventory_id", + "type": "WindowIDVarint" + } + ] + ], + "craft": [ + "container", + [ + { + "name": "action", + "type": "varint" + } + ] + ], + "world_interaction": [ + "container", + [ + { + "name": "flags", + "type": "varint" + } + ] + ], + "craft_slot": [ + "container", + [ + { + "name": "action", + "type": "varint" + } + ] + ] + }, + "default": "void" + } + ] + }, + { + "name": "slot", + "type": "varint" + }, + { + "name": "old_item", + "type": "Item" + }, + { + "name": "new_item", + "type": "Item" } ] - } - ] + ] + } ], "TransactionLegacy": [ "container", @@ -2656,6 +2648,79 @@ } ] ], + "TrackedObject": [ + "container", + [ + { + "name": "type", + "type": [ + "mapper", + { + "type": "li32", + "mappings": { + "0": "entity", + "1": "block" + } + } + ] + }, + { + "name": "entity_unique_id", + "type": [ + "switch", + { + "compareTo": "type", + "fields": { + "entity": "zigzag64" + }, + "default": "void" + } + ] + }, + { + "name": "block_position", + "type": [ + "switch", + { + "compareTo": "type", + "fields": { + "block": "BlockCoordinates" + }, + "default": "void" + } + ] + } + ] + ], + "MapDecoration": [ + "container", + [ + { + "name": "type", + "type": "u8" + }, + { + "name": "rotation", + "type": "u8" + }, + { + "name": "x", + "type": "u8" + }, + { + "name": "y", + "type": "u8" + }, + { + "name": "label", + "type": "string" + }, + { + "name": "color_abgr", + "type": "varint" + } + ] + ], "WindowID": [ "mapper", { @@ -5673,8 +5738,132 @@ "container", [ { - "name": "mapinfo", - "type": "MapInfo" + "name": "map_id", + "type": "zigzag64" + }, + { + "name": "update_flags", + "type": "UpdateMapFlags" + }, + { + "name": "dimension", + "type": "u8" + }, + { + "name": "locked", + "type": "bool" + }, + { + "name": "included_in", + "type": [ + "switch", + { + "compareTo": "update_flags.initialisation", + "fields": { + "true": [ + "array", + { + "countType": "varint", + "type": "zigzag64" + } + ] + }, + "default": "void" + } + ] + }, + { + "name": "scale", + "type": [ + "switch", + { + "compareTo": "update_flags.initialisation || update_flags.decoration || update_flags.texture", + "fields": { + "true": "u8" + }, + "default": "void" + } + ] + }, + { + "name": "tracked", + "type": [ + "switch", + { + "compareTo": "update_flags.decoration", + "fields": { + "true": [ + "container", + [ + { + "name": "objects", + "type": [ + "array", + { + "countType": "varint", + "type": "TrackedObject" + } + ] + }, + { + "name": "decorations", + "type": [ + "array", + { + "countType": "varint", + "type": "MapDecoration" + } + ] + } + ] + ] + }, + "default": "void" + } + ] + }, + { + "name": "texture", + "type": [ + "switch", + { + "compareTo": "update_flags.texture", + "fields": { + "true": [ + "container", + [ + { + "name": "width", + "type": "zigzag32" + }, + { + "name": "height", + "type": "zigzag32" + }, + { + "name": "x_offset", + "type": "zigzag32" + }, + { + "name": "y_offset", + "type": "zigzag32" + }, + { + "name": "pixels", + "type": [ + "array", + { + "countType": "varint", + "type": "varint" + } + ] + } + ] + ] + }, + "default": "void" + } + ] } ] ], @@ -8216,6 +8405,18 @@ } } ], + "UpdateMapFlags": [ + "bitflags", + { + "type": "varint", + "flags": [ + "void", + "texture", + "decoration", + "initialisation" + ] + } + ], "CommandFlags": [ "bitfield", [ diff --git a/data/latest/proto.yml b/data/latest/proto.yml index da3a9e1..1b6efdd 100644 --- a/data/latest/proto.yml +++ b/data/latest/proto.yml @@ -465,12 +465,22 @@ packet_take_item_entity: 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 @@ -1249,10 +1259,74 @@ packet_spawn_experience_orb: 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 - mapinfo: MapInfo + # 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 diff --git a/data/latest/types.yaml b/data/latest/types.yaml index d633c70..7a5595c 100644 --- a/data/latest/types.yaml +++ b/data/latest/types.yaml @@ -484,26 +484,25 @@ TransactionUseItem: # 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: - actions: []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: varint - if world_interaction: - flags: varint - if craft or craft_slot: - action: varint - default: void - slot: varint - old_item: Item - new_item: Item +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. @@ -1011,6 +1010,39 @@ CommandOrigin: 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 + # Some arbitrary definitions from CBMC, Window IDs are normally # unique + sequential WindowID: i8 => diff --git a/src/datatypes/compiler-minecraft.js b/src/datatypes/compiler-minecraft.js index 6838a84..3fbc2b9 100644 --- a/src/datatypes/compiler-minecraft.js +++ b/src/datatypes/compiler-minecraft.js @@ -89,6 +89,22 @@ SizeOf.nbtLoop = ['context', (value, buffer, offset) => { return size }] +/** + * Read rotation float encoded as a byte + */ +Read.byterot = ['context', (buffer, offset) => { + const val = buffer.readUint8(buffer) + return { value: (val * (360 / 256)), size: 1 } +}] +Write.byterot = ['context', (value, buffer, offset) => { + const val = (value / (360 / 256)) + buffer.writeUint8(val, offset) + return offset + 1 +}] +SizeOf.byterot = ['context', (value, buffer, offset) => { + return 1 +}] + /** * NBT */