From 6803d742e6d7557e76dc53e48a4a8808c1a2bbdf Mon Sep 17 00:00:00 2001 From: extremeheat Date: Mon, 22 Mar 2021 04:21:06 -0400 Subject: [PATCH] player input, transaction, bitflag updates --- data/1.16.210/protocol.json | 1253 +++++++++++++++------------ data/latest/proto.yml | 149 ++-- data/latest/types.yaml | 377 ++++---- src/datatypes/compiler-minecraft.js | 62 +- 4 files changed, 1033 insertions(+), 808 deletions(-) diff --git a/data/1.16.210/protocol.json b/data/1.16.210/protocol.json index 251b0c0..9aa256f 100644 --- a/data/1.16.210/protocol.json +++ b/data/1.16.210/protocol.json @@ -744,80 +744,62 @@ ] } ], - "Transaction": [ + "TransactionUseItem": [ "container", [ { - "name": "legacy_request_id", - "type": "zigzag32" - }, - { - "name": "legacy_transactions", - "type": [ - "switch", - { - "compareTo": "legacy_request_id", - "fields": { - "0": "void" - }, - "default": [ - "array", - { - "countType": "varint", - "type": [ - "container", - [ - { - "name": "container_id", - "type": "u8" - }, - { - "name": "changed_slots", - "type": [ - "array", - { - "countType": "varint", - "type": [ - "container", - [ - { - "name": "slot_id", - "type": "u8" - } - ] - ] - } - ] - } - ] - ] - } - ] - } - ] - }, - { - "name": "transaction_type", + "name": "action_type", "type": [ "mapper", { "type": "varint", "mappings": { - "0": "normal", - "1": "inventory_mismatch", - "2": "item_use", - "3": "item_use_on_entity", - "4": "item_release" + "0": "click_block", + "1": "click_air", + "2": "break_block" } } ] }, + { + "name": "block_position", + "type": "BlockCoordinates" + }, + { + "name": "face", + "type": "varint" + }, + { + "name": "hotbar_slot", + "type": "varint" + }, + { + "name": "held_item", + "type": "Item" + }, + { + "name": "player_pos", + "type": "vec3f" + }, + { + "name": "click_pos", + "type": "vec3f" + }, + { + "name": "block_runtime_id", + "type": "varint" + } + ] + ], + "TransactionActions": [ + "container", + [ { "name": "network_ids", "type": "bool" }, { - "name": "inventory_actions", + "name": "actions", "type": [ "array", { @@ -928,6 +910,89 @@ ] } ] + } + ] + ], + "TransactionLegacy": [ + "container", + [ + { + "name": "legacy_request_id", + "type": "zigzag32" + }, + { + "name": "legacy_transactions", + "type": [ + "switch", + { + "compareTo": "legacy_request_id", + "fields": { + "0": "void" + }, + "default": [ + "array", + { + "countType": "varint", + "type": [ + "container", + [ + { + "name": "container_id", + "type": "u8" + }, + { + "name": "changed_slots", + "type": [ + "array", + { + "countType": "varint", + "type": [ + "container", + [ + { + "name": "slot_id", + "type": "u8" + } + ] + ] + } + ] + } + ] + ] + } + ] + } + ] + } + ] + ], + "Transaction": [ + "container", + [ + { + "name": "legacy", + "type": "TransactionLegacy" + }, + { + "name": "transaction_type", + "type": [ + "mapper", + { + "type": "varint", + "mappings": { + "0": "normal", + "1": "inventory_mismatch", + "2": "item_use", + "3": "item_use_on_entity", + "4": "item_release" + } + } + ] + }, + { + "name": "actions", + "type": "TransactionActions" }, { "name": "transaction_data", @@ -938,53 +1003,7 @@ "fields": { "normal": "void", "inventory_mismatch": "void", - "item_use": [ - "container", - [ - { - "name": "action_type", - "type": [ - "mapper", - { - "type": "varint", - "mappings": { - "0": "click_block", - "1": "click_air", - "2": "break_block" - } - } - ] - }, - { - "name": "block_position", - "type": "BlockCoordinates" - }, - { - "name": "face", - "type": "varint" - }, - { - "name": "hotbar_slot", - "type": "varint" - }, - { - "name": "held_item", - "type": "Item" - }, - { - "name": "player_pos", - "type": "vec3f" - }, - { - "name": "click_pos", - "type": "vec3f" - }, - { - "name": "block_runtime_id", - "type": "varint" - } - ] - ], + "item_use": "TransactionUseItem", "item_use_on_entity": [ "container", [ @@ -2009,6 +2028,42 @@ ] } ], + "Action": [ + "mapper", + { + "type": "zigzag32", + "mappings": { + "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", + "14": "dimension_change_ack", + "15": "start_glide", + "16": "stop_glide", + "17": "build_denied", + "18": "crack_break", + "19": "change_skin", + "20": "set_enchatnment_seed", + "21": "swimming", + "22": "stop_swimming", + "23": "start_spin_attack", + "24": "stop_spin_attack", + "25": "ineract_block", + "26": "predict_break", + "27": "continue_break" + } + } + ], "StackRequestSlotInfo": [ "container", [ @@ -2026,272 +2081,266 @@ } ] ], - "ItemStackRequests": [ - "array", - { - "countType": "varint", - "type": [ - "container", - [ + "ItemStackRequest": [ + "container", + [ + { + "name": "request_id", + "type": "zigzag32" + }, + { + "name": "actions", + "type": [ + "array", { - "name": "request_id", - "type": "zigzag32" - }, - { - "name": "actions", + "countType": "varint", "type": [ - "array", - { - "countType": "varint", - "type": [ - "container", - [ + "container", + [ + { + "name": "type_id", + "type": [ + "mapper", { - "name": "type_id", - "type": [ - "mapper", - { - "type": "u8", - "mappings": { - "0": "take", - "1": "place", - "2": "swap", - "3": "drop", - "4": "destroy", - "5": "consume", - "6": "create", - "7": "lab_table_combine", - "8": "beacon_payment", - "9": "mine_block", - "10": "craft_recipe", - "11": "craft_recipe_auto", - "12": "craft_creative", - "13": "optional", - "14": "non_implemented", - "15": "results_deprecated" - } - } - ] - }, - { - "anon": true, - "type": [ - "switch", - { - "compareTo": "type_id", - "fields": { - "take": [ - "container", - [ - { - "name": "count", - "type": "u8" - }, - { - "name": "source", - "type": "StackRequestSlotInfo" - }, - { - "name": "destination", - "type": "StackRequestSlotInfo" - } - ] - ], - "place": [ - "container", - [ - { - "name": "count", - "type": "u8" - }, - { - "name": "source", - "type": "StackRequestSlotInfo" - }, - { - "name": "destination", - "type": "StackRequestSlotInfo" - } - ] - ], - "swap": [ - "container", - [ - { - "name": "source", - "type": "StackRequestSlotInfo" - }, - { - "name": "destination", - "type": "StackRequestSlotInfo" - } - ] - ], - "drop": [ - "container", - [ - { - "name": "count", - "type": "u8" - }, - { - "name": "source", - "type": "StackRequestSlotInfo" - }, - { - "name": "randomly", - "type": "bool" - } - ] - ], - "destroy": [ - "container", - [ - { - "name": "count", - "type": "u8" - }, - { - "name": "source", - "type": "StackRequestSlotInfo" - } - ] - ], - "consume": [ - "container", - [ - { - "name": "count", - "type": "u8" - }, - { - "name": "source", - "type": "StackRequestSlotInfo" - } - ] - ], - "create": [ - "container", - [ - { - "name": "result_slot_id", - "type": "u8" - } - ] - ], - "beacon_payment": [ - "container", - [ - { - "name": "primary_effect", - "type": "zigzag32" - }, - { - "name": "secondary_effect", - "type": "zigzag32" - } - ] - ], - "mine_block": [ - "container", - [ - { - "name": "unknown1", - "type": "zigzag32" - }, - { - "name": "predicted_durability", - "type": "zigzag32" - }, - { - "name": "network_id", - "type": "zigzag32" - } - ] - ], - "craft_recipe": [ - "container", - [ - { - "name": "recipe_network_id", - "type": "varint" - } - ] - ], - "craft_recipe_auto": [ - "container", - [ - { - "name": "recipe_network_id", - "type": "varint" - } - ] - ], - "craft_creative": [ - "container", - [ - { - "name": "creative_item_network_id", - "type": "varint32" - } - ] - ], - "optional": [ - "container", - [ - { - "name": "recipe_network_id", - "type": "varint" - }, - { - "name": "filtered_string_index", - "type": "li32" - } - ] - ], - "non_implemented": "void", - "results_deprecated": [ - "container", - [ - { - "name": "result_items", - "type": [ - "array", - { - "countType": "varint", - "type": "Item" - } - ] - }, - { - "name": "times_crafted", - "type": "u8" - } - ] - ] - }, - "default": "void" - } - ] + "type": "u8", + "mappings": { + "0": "take", + "1": "place", + "2": "swap", + "3": "drop", + "4": "destroy", + "5": "consume", + "6": "create", + "7": "lab_table_combine", + "8": "beacon_payment", + "9": "mine_block", + "10": "craft_recipe", + "11": "craft_recipe_auto", + "12": "craft_creative", + "13": "optional", + "14": "non_implemented", + "15": "results_deprecated" + } } ] - ] - } - ] - }, - { - "name": "custom_names", - "type": [ - "array", - { - "countType": "varint", - "type": "string" - } + }, + { + "anon": true, + "type": [ + "switch", + { + "compareTo": "type_id", + "fields": { + "take": [ + "container", + [ + { + "name": "count", + "type": "u8" + }, + { + "name": "source", + "type": "StackRequestSlotInfo" + }, + { + "name": "destination", + "type": "StackRequestSlotInfo" + } + ] + ], + "place": [ + "container", + [ + { + "name": "count", + "type": "u8" + }, + { + "name": "source", + "type": "StackRequestSlotInfo" + }, + { + "name": "destination", + "type": "StackRequestSlotInfo" + } + ] + ], + "swap": [ + "container", + [ + { + "name": "source", + "type": "StackRequestSlotInfo" + }, + { + "name": "destination", + "type": "StackRequestSlotInfo" + } + ] + ], + "drop": [ + "container", + [ + { + "name": "count", + "type": "u8" + }, + { + "name": "source", + "type": "StackRequestSlotInfo" + }, + { + "name": "randomly", + "type": "bool" + } + ] + ], + "destroy": [ + "container", + [ + { + "name": "count", + "type": "u8" + }, + { + "name": "source", + "type": "StackRequestSlotInfo" + } + ] + ], + "consume": [ + "container", + [ + { + "name": "count", + "type": "u8" + }, + { + "name": "source", + "type": "StackRequestSlotInfo" + } + ] + ], + "create": [ + "container", + [ + { + "name": "result_slot_id", + "type": "u8" + } + ] + ], + "beacon_payment": [ + "container", + [ + { + "name": "primary_effect", + "type": "zigzag32" + }, + { + "name": "secondary_effect", + "type": "zigzag32" + } + ] + ], + "mine_block": [ + "container", + [ + { + "name": "unknown1", + "type": "zigzag32" + }, + { + "name": "predicted_durability", + "type": "zigzag32" + }, + { + "name": "network_id", + "type": "zigzag32" + } + ] + ], + "craft_recipe": [ + "container", + [ + { + "name": "recipe_network_id", + "type": "varint" + } + ] + ], + "craft_recipe_auto": [ + "container", + [ + { + "name": "recipe_network_id", + "type": "varint" + } + ] + ], + "craft_creative": [ + "container", + [ + { + "name": "creative_item_network_id", + "type": "varint32" + } + ] + ], + "optional": [ + "container", + [ + { + "name": "recipe_network_id", + "type": "varint" + }, + { + "name": "filtered_string_index", + "type": "li32" + } + ] + ], + "non_implemented": "void", + "results_deprecated": [ + "container", + [ + { + "name": "result_items", + "type": [ + "array", + { + "countType": "varint", + "type": "Item" + } + ] + }, + { + "name": "times_crafted", + "type": "u8" + } + ] + ] + }, + "default": "void" + } + ] + } + ] ] } ] - ] - } + }, + { + "name": "custom_names", + "type": [ + "array", + { + "countType": "varint", + "type": "string" + } + ] + } + ] ], "ItemStackResponses": [ "array", @@ -4481,42 +4530,7 @@ }, { "name": "action", - "type": [ - "mapper", - { - "type": "zigzag32", - "mappings": { - "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", - "14": "dimension_change_ack", - "15": "start_glide", - "16": "stop_glide", - "17": "build_denied", - "18": "crack_break", - "19": "change_skin", - "20": "set_enchatnment_seed", - "21": "swimming", - "22": "stop_swimming", - "23": "start_spin_attack", - "24": "stop_spin_attack", - "25": "ineract_block", - "26": "predict_break", - "27": "continue_break" - } - } - ] + "type": "Action" }, { "name": "position", @@ -6821,10 +6835,11 @@ { "type": "varint", "mappings": { - "0": "mouse", - "1": "touch", - "2": "game_pad", - "3": "motion_controller" + "0": "unknown", + "1": "mouse", + "2": "touch", + "3": "game_pad", + "4": "motion_controller" } } ] @@ -6870,6 +6885,152 @@ { "name": "delta", "type": "vec3f" + }, + { + "name": "transaction", + "type": [ + "switch", + { + "compareTo": "input_data.item_interact", + "fields": { + "true": [ + "container", + [ + { + "name": "legacy", + "type": "TransactionLegacy" + }, + { + "name": "actions", + "type": "TransactionActions" + }, + { + "name": "data", + "type": "TransactionUseItem" + } + ] + ] + }, + "default": "void" + } + ] + }, + { + "name": "item_stack_request", + "type": [ + "switch", + { + "compareTo": "input_data.item_stack_request", + "fields": { + "true": "ItemStackRequest" + }, + "default": "void" + } + ] + }, + { + "name": "block_action", + "type": [ + "switch", + { + "compareTo": "input_data.block_action", + "fields": { + "true": [ + "array", + { + "countType": "zigzag32", + "type": [ + "container", + [ + { + "name": "action", + "type": "Action" + }, + { + "anon": true, + "type": [ + "switch", + { + "compareTo": "action", + "fields": { + "start_break": [ + "container", + [ + { + "name": "position", + "type": "BlockCoordinates" + }, + { + "name": "face", + "type": "zigzag32" + } + ] + ], + "abort_break": [ + "container", + [ + { + "name": "position", + "type": "BlockCoordinates" + }, + { + "name": "face", + "type": "zigzag32" + } + ] + ], + "crack_break": [ + "container", + [ + { + "name": "position", + "type": "BlockCoordinates" + }, + { + "name": "face", + "type": "zigzag32" + } + ] + ], + "predict_break": [ + "container", + [ + { + "name": "position", + "type": "BlockCoordinates" + }, + { + "name": "face", + "type": "zigzag32" + } + ] + ], + "continue_break": [ + "container", + [ + { + "name": "position", + "type": "BlockCoordinates" + }, + { + "name": "face", + "type": "zigzag32" + } + ] + ] + }, + "default": "void" + } + ] + } + ] + ] + } + ] + }, + "default": "void" + } + ] } ] ], @@ -6896,7 +7057,13 @@ [ { "name": "requests", - "type": "ItemStackRequests" + "type": [ + "array", + { + "countType": "varint", + "type": "ItemStackRequest" + } + ] } ] ], @@ -7304,72 +7471,72 @@ "type": "zigzag64", "big": true, "shift": true, - "flags": { - "onfire": 0, - "sneaking": 1, - "riding": 2, - "sprinting": 3, - "action": 4, - "invisible": 5, - "tempted": 6, - "inlove": 7, - "saddled": 8, - "powered": 9, - "ignited": 10, - "baby": 11, - "converting": 12, - "critical": 13, - "can_show_nametag": 14, - "always_show_nametag": 15, - "no_ai": 16, - "silent": 17, - "wallclimbing": 18, - "can_climb": 19, - "swimmer": 20, - "can_fly": 21, - "walker": 22, - "resting": 23, - "sitting": 24, - "angry": 25, - "interested": 26, - "charged": 27, - "tamed": 28, - "orphaned": 29, - "leashed": 30, - "sheared": 31, - "gliding": 32, - "elder": 33, - "moving": 34, - "breathing": 35, - "chested": 36, - "stackable": 37, - "showbase": 38, - "rearing": 39, - "vibrating": 40, - "idling": 41, - "evoker_spell": 42, - "charge_attack": 43, - "wasd_controlled": 44, - "can_power_jump": 45, - "linger": 46, - "has_collision": 47, - "affected_by_gravity": 48, - "fire_immune": 49, - "dancing": 50, - "enchanted": 51, - "show_trident_rope": 52, - "container_private": 53, - "transforming": 54, - "spin_attack": 55, - "swimming": 56, - "bribed": 57, - "pregnant": 58, - "laying_egg": 59, - "rider_can_pick": 60, - "transition_sitting": 61, - "eating": 62, - "laying_down": 63 - } + "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", + "container_private", + "transforming", + "spin_attack", + "swimming", + "bribed", + "pregnant", + "laying_egg", + "rider_can_pick", + "transition_sitting", + "eating", + "laying_down" + ] } ], "MetadataFlags2": [ @@ -7377,40 +7544,39 @@ { "type": "zigzag64", "big": true, - "shift": true, - "flags": { - "sneezing": 64, - "trusting": 65, - "rolling": 66, - "scared": 67, - "in_scaffolding": 68, - "over_scaffolding": 69, - "fall_through_scaffolding": 70, - "blocking": 71, - "transition_blocking": 72, - "blocked_using_shield": 73, - "blocked_using_damaged_shield": 74, - "sleeping": 75, - "wants_to_wake": 76, - "trade_interest": 77, - "door_breaker": 78, - "breaking_obstruction": 79, - "door_opener": 80, - "illager_captain": 81, - "stunned": 82, - "roaring": 83, - "delayed_attacking": 84, - "avoiding_mobs": 85, - "avoiding_block": 86, - "facing_target_to_range_attack": 87, - "hidden_when_invisible": 88, - "is_in_ui": 89, - "stalking": 90, - "emoting": 91, - "celebrating": 92, - "admiring": 93, - "celebrating_special": 94 - } + "flags": [ + "sneezing", + "trusting", + "rolling", + "scared", + "in_scaffolding", + "over_scaffolding", + "fall_through_scaffolding", + "blocking", + "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" + ] } ], "UpdateBlockFlags": [ @@ -7499,46 +7665,47 @@ "InputFlag": [ "bitflags", { - "type": "varint", - "flags": { - "ascend": 1, - "descend": 2, - "north_jump": 4, - "jump_down": 8, - "sprint_down": 16, - "change_height": 32, - "jumping": 64, - "auto_jumping_in_water": 128, - "sneaking": 256, - "sneak_down": 512, - "up": 1024, - "down": 2048, - "left": 4096, - "right": 8192, - "up_left": 16384, - "up_right": 32768, - "want_up": 65536, - "want_down": 131072, - "want_down_slow": 262144, - "want_up_slow": 524288, - "sprinting": 1048576, - "ascend_scaffolding": 2097152, - "descend_scaffolding": 4194304, - "sneak_toggle_down": 8388608, - "persist_sneak": 16777216, - "start_sprinting": 33554432, - "stop_sprinting": 67108864, - "start_sneaking": 134217728, - "stop_sneaking": 134217728, - "start_swimming": 268435456, - "stop_swimming": 536870912, - "start_jumping": 1073741824, - "start_gliding": 2147483648, - "stop_gliding": 4294967296, - "item_interact": 8589934592, - "block_action": 17179869184, - "item_stack_request": 34359738368 - } + "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_scaffolding", + "descend_scaffolding", + "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" + ] } ], "ArmorDamageType": [ diff --git a/data/latest/proto.yml b/data/latest/proto.yml index bc026ba..f24b5fb 100644 --- a/data/latest/proto.yml +++ b/data/latest/proto.yml @@ -753,6 +753,10 @@ packet_update_attributes: 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 @@ -821,37 +825,7 @@ packet_player_action: runtime_entity_id: varint # 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: 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: ineract_block - 26: predict_break - 27: continue_break + 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 @@ -2127,10 +2101,11 @@ packet_player_auth_input: # 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: mouse - 1: touch - 2: game_pad - 3: motion_controller + 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 => @@ -2154,49 +2129,67 @@ packet_player_auth_input: # 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": "varint", - "flags": { - "ascend": 0b1, - "descend": 0b10, - "north_jump": 0b100, - "jump_down": 0b1000, - "sprint_down": 0b10000, - "change_height": 0b100000, - "jumping": 0b1000000, - "auto_jumping_in_water": 0b10000000, - "sneaking": 0b100000000, - "sneak_down": 0b1000000000, - "up": 0b10000000000, - "down": 0b100000000000, - "left": 0b1000000000000, - "right": 0b10000000000000, - "up_left": 0b100000000000000, - "up_right": 0b1000000000000000, - "want_up": 0b10000000000000000, - "want_down": 0b100000000000000000, - "want_down_slow": 0b1000000000000000000, - "want_up_slow": 0b10000000000000000000, - "sprinting": 0b100000000000000000000, - "ascend_scaffolding": 0b1000000000000000000000, - "descend_scaffolding": 0b10000000000000000000000, - "sneak_toggle_down": 0b100000000000000000000000, - "persist_sneak": 0b1000000000000000000000000, - "start_sprinting": 0b10000000000000000000000000, - "stop_sprinting": 0b100000000000000000000000000, - "start_sneaking": 0b1000000000000000000000000000, - "stop_sneaking": 0b1000000000000000000000000000, - "start_swimming": 0b10000000000000000000000000000, - "stop_swimming": 0b100000000000000000000000000000, - "start_jumping": 0b1000000000000000000000000000000, - "start_gliding": 0b10000000000000000000000000000000, - "stop_gliding": 0b100000000000000000000000000000000, - "item_interact": 0b1000000000000000000000000000000000, - "block_action": 0b10000000000000000000000000000000000, - "item_stack_request": 0b100000000000000000000000000000000000 - } + "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_scaffolding", + "descend_scaffolding", + "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" + ] }] packet_creative_content: @@ -2209,10 +2202,14 @@ packet_player_enchant_options: !bound: client enchant_options: EnchantOptions +# 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: ItemStackRequests + requests: ItemStackRequest[]varint packet_item_stack_response: !id: 0x94 diff --git a/data/latest/types.yaml b/data/latest/types.yaml index c99030e..1c613d3 100644 --- a/data/latest/types.yaml +++ b/data/latest/types.yaml @@ -262,110 +262,112 @@ MetadataDictionary: []varint if vec3f: vec3f MetadataFlags1: [ "bitflags", { - "type": "zigzag64", "big": true, "shift": true, - "flags": { - "onfire": 0, - "sneaking": 1, - "riding": 2, - "sprinting": 3, - "action": 4, - "invisible": 5, - "tempted": 6, - "inlove": 7, - "saddled": 8, - "powered": 9, - "ignited": 10, - "baby": 11, - "converting": 12, - "critical": 13, - "can_show_nametag": 14, - "always_show_nametag": 15, - "no_ai": 16, - "silent": 17, - "wallclimbing": 18, - "can_climb": 19, - "swimmer": 20, - "can_fly": 21, - "walker": 22, - "resting": 23, - "sitting": 24, - "angry": 25, - "interested": 26, - "charged": 27, - "tamed": 28, - "orphaned": 29, - "leashed": 30, - "sheared": 31, - "gliding": 32, - "elder": 33, - "moving": 34, - "breathing": 35, - "chested": 36, - "stackable": 37, - "showbase": 38, - "rearing": 39, - "vibrating": 40, - "idling": 41, - "evoker_spell": 42, - "charge_attack": 43, - "wasd_controlled": 44, - "can_power_jump": 45, - "linger": 46, - "has_collision": 47, - "affected_by_gravity": 48, - "fire_immune": 49, - "dancing": 50, - "enchanted": 51, - "show_trident_rope": 52, # 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": 53, #inventory is private, doesn't drop contents when killed if true - "transforming": 54, - "spin_attack": 55, - "swimming": 56, - "bribed": 57, #dolphins have this set when they go to find treasure for the player - "pregnant": 58, - "laying_egg": 59, - "rider_can_pick": 60, #??? - "transition_sitting": 61, - "eating": 62, - "laying_down": 63, - } + "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, "shift": true, - "flags": { - "sneezing": 64, - "trusting": 65, - "rolling": 66, - "scared": 67, - "in_scaffolding": 68, - "over_scaffolding": 69, - "fall_through_scaffolding": 70, - "blocking": 71, #shield - "transition_blocking": 72, - "blocked_using_shield": 73, - "blocked_using_damaged_shield": 74, - "sleeping": 75, - "wants_to_wake": 76, - "trade_interest": 77, - "door_breaker": 78, #... - "breaking_obstruction": 79, - "door_opener": 80, #... - "illager_captain": 81, - "stunned": 82, - "roaring": 83, - "delayed_attacking": 84, - "avoiding_mobs": 85, - "avoiding_block": 86, - "facing_target_to_range_attack": 87, - "hidden_when_invisible": 88, #?????????????????? - "is_in_ui": 89, - "stalking": 90, - "emoting": 91, - "celebrating": 92, - "admiring": 93, - "celebrating_special": 94, - } + "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" + ] }] Link: @@ -400,31 +402,44 @@ PlayerAttributes: []varint default: lf32 name: string -Transaction: - # 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_type: varint => - 0: normal - 1: inventory_mismatch - 2: item_use - 3: item_use_on_entity - 4: item_release +# 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: BlockCoordinates + # 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: network_ids: bool - inventory_actions: []varint + actions: []varint source_type: varint => 0: container 1: global @@ -444,40 +459,47 @@ Transaction: old_item: Item new_item: Item new_item_stack_id: ../network_ids? - if true: zigzag32 + if true: zigzag32 default: void + +# 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: - # 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: BlockCoordinates - # 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 + 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: @@ -698,15 +720,48 @@ EnchantOptions: []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: ineract_block + 26: predict_break + 27: continue_break StackRequestSlotInfo: container_id: u8 slot_id: u8 stack_id: zigzag32 -# - -ItemStackRequests: []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. +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: zigzag32 @@ -836,10 +891,10 @@ ItemStackRequests: []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 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 diff --git a/src/datatypes/compiler-minecraft.js b/src/datatypes/compiler-minecraft.js index 91c8b0b..dd3afe3 100644 --- a/src/datatypes/compiler-minecraft.js +++ b/src/datatypes/compiler-minecraft.js @@ -81,57 +81,63 @@ SizeOf.nbt = ['native', minecraft.nbt[2]] */ Read.bitflags = ['parametrizable', (compiler, { type, flags, shift, big }) => { - if (shift) { - let i = 0 - for (const key in flags) { - const val = flags[key] - flags[key] = val << i++ - } + let fstr = JSON.stringify(flags) + if (Array.isArray(flags)) { + fstr = '{' + flags.map((v,k) => fstr += `"${v}": ${big ? 1n << BigInt(k) : 1 << k}` + (big ? 'n,' : ',')) + fstr += '}' + } else if (shift) { + fstr = '{' + for (const key in flags) fstr += `"${key}": ${1 << flags[key]},`; + fstr += '}' } return compiler.wrapCode(` const { value: _value, size } = ${compiler.callType(type, 'offset')} const value = { _value } - const flags = ${JSON.stringify(flags)} + const flags = ${fstr} for (const key in flags) { - const v = ${big ? `BigInt(flags[key])` : 'flags[key]'} - value[key] = (_value & v) == v + value[key] = (_value & flags[key]) == flags[key] } return { value, size } `.trim()) }] Write.bitflags = ['parametrizable', (compiler, { type, flags, shift, big }) => { - if (shift) { - let i = 0 - for (const key in flags) { - const val = flags[key] - flags[key] = val << i++ - } + let fstr = JSON.stringify(flags) + if (Array.isArray(flags)) { + fstr = '{' + flags.map((v,k) => fstr += `"${v}": ${big ? 1n << BigInt(k) : 1 << k}` + (big ? 'n,' : ',')) + fstr += '}' + } else if (shift) { + fstr = '{' + for (const key in flags) fstr += `"${key}": ${1 << flags[key]},`; + fstr += '}' } return compiler.wrapCode(` - const flags = ${JSON.stringify(flags)} - let val = value._value + const flags = ${fstr} + let val = value._value ${big ? '|| 0n' : ''} for (const key in flags) { - const v = ${big ? `BigInt(flags[key])` : 'flags[key]'} - if (value[key]) val |= v + if (value[key]) val |= flags[key] } return (ctx.${type})(val, buffer, offset) `.trim()) }] SizeOf.bitflags = ['parametrizable', (compiler, { type, flags, shift, big }) => { - if (shift) { - let i = 0 - for (const key in flags) { - const val = flags[key] - flags[key] = val << i++ - } + let fstr = JSON.stringify(flags) + if (Array.isArray(flags)) { + fstr = '{' + flags.map((v,k) => fstr += `"${v}": ${big ? 1n << BigInt(k) : 1 << k}` + (big ? 'n,' : ',')) + fstr += '}' + } else if (shift) { + fstr = '{' + for (const key in flags) fstr += `"${key}": ${1 << flags[key]},`; + fstr += '}' } return compiler.wrapCode(` - const flags = ${JSON.stringify(flags)} - let val = value._value + const flags = ${fstr} + let val = value._value ${big ? '|| 0n' : ''} for (const key in flags) { - const v = ${big ? `BigInt(flags[key])` : 'flags[key]'} if (value[key]) val |= flags[key] } return (ctx.${type})(val)