From 63da8ddcd52dc00c754355ef4f48b51ee6ed1c14 Mon Sep 17 00:00:00 2001 From: alemi Date: Wed, 1 Nov 2023 22:08:52 +0100 Subject: [PATCH] fix: generate metadata and particles, fix switch now entity metadata and particle data are loaded from minecraft-data and thus should just work :tm: for all proto versions also fixed an ugly bug in switch type about string 'true' and 'false'. "fixed" is kind of an overstatement, more like "awfully patched hoping it's an exception and i don't need to parse numbers too" ... --- aiocraft/mc/packet.py | 6 +-- aiocraft/mc/proto/ext.py | 74 ++++++++++++++++++++++++++ aiocraft/mc/types.py | 110 +++++++++------------------------------ compiler/proto.py | 51 +++++++++++++----- 4 files changed, 142 insertions(+), 99 deletions(-) create mode 100644 aiocraft/mc/proto/ext.py diff --git a/aiocraft/mc/packet.py b/aiocraft/mc/packet.py index 222d59f..766f153 100644 --- a/aiocraft/mc/packet.py +++ b/aiocraft/mc/packet.py @@ -1,7 +1,7 @@ import io import json from asyncio import Event -from typing import Tuple, Dict, Any +from typing import Tuple, List, Dict, Any from .types import Type, VarInt, Context @@ -11,13 +11,13 @@ class Packet: __slots__ = 'id', 'definition', '_processed', '_proto', '_state' id : int - definition : Tuple[Tuple[str, Type]] + definition : List[Tuple[str, Type]] _processed : Event _proto : int _state : int _ids : Dict[int, int] # definitions are compiled at install time - _definitions : Dict[int, Tuple[Tuple[str, Type]]] # definitions are compiled at install time + _definitions : Dict[int, List[Tuple[str, Type]]] # definitions are compiled at install time def __init__(self, proto:int, **kwargs): self._proto = proto diff --git a/aiocraft/mc/proto/ext.py b/aiocraft/mc/proto/ext.py new file mode 100644 index 0000000..afdac52 --- /dev/null +++ b/aiocraft/mc/proto/ext.py @@ -0,0 +1,74 @@ +from ..types import * + +class MetadataDefinitions: + _definitions: dict[int, dict[int, Type]] = { + 47 : {0: Byte, 1: Short, 2: Int, 3: Float, 4: String, 5: Slot, 6: StructType(( 'x', Int ), ( 'y', Int ), ( 'z', Int ), ), 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), )}, + 76 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 107 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 108 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 109 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 110 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 201 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 210 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 304 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 315 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt}, + 321 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt, 13: NBTTag}, + 327 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt, 13: NBTTag}, + 331 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt, 13: NBTTag}, + 335 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt, 13: NBTTag}, + 338 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt, 13: NBTTag}, + 340 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt, 13: NBTTag}, + 351 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: Slot, 6: Boolean, 7: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 8: Position, 9: OptionalType(Position, ), 10: VarInt, 11: OptionalType(UUID, ), 12: VarInt, 13: NBTTag}, + 393 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData}, + 401 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData}, + 402 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData}, + 403 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData}, + 404 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData}, + 477 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 480 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 490 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 498 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 573 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 575 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 578 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 709 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 734 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 735 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 736 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 751 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 755 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 756 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 757 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 758 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 759 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt}, + 760 : {0: Byte, 1: VarInt, 2: Float, 3: String, 4: String, 5: OptionalType(String, ), 6: Slot, 7: Boolean, 8: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 9: Position, 10: OptionalType(Position, ), 11: VarInt, 12: OptionalType(UUID, ), 13: VarInt, 14: NBTTag, 15: TrailingData, 16: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 17: TrailingData, 18: VarInt, 19: VarInt, 20: VarInt, 21: OptionalType(String, ), 22: VarInt}, + 761 : {0: Byte, 1: VarInt, 2: VarLong, 3: Float, 4: String, 5: String, 6: OptionalType(String, ), 7: Slot, 8: Boolean, 9: StructType(( 'pitch', Float ), ( 'yaw', Float ), ( 'roll', Float ), ), 10: Position, 11: OptionalType(Position, ), 12: VarInt, 13: OptionalType(UUID, ), 14: VarInt, 15: NBTTag, 16: TrailingData, 17: StructType(( 'villagerType', VarInt ), ( 'villagerProfession', VarInt ), ( 'level', VarInt ), ), 18: TrailingData, 19: VarInt, 20: VarInt, 21: VarInt, 22: OptionalType(String, ), 23: VarInt} + } + +class ParticlesDefinitions: + _definitions: dict[int, dict[int, Type]] = { + 393 : {3: StructType(( 'blockState', VarInt ), ), 11: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 20: StructType(( 'blockState', VarInt ), ), 27: StructType(( 'item', Slot ), )}, + 401 : {3: StructType(( 'blockState', VarInt ), ), 11: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 20: StructType(( 'blockState', VarInt ), ), 27: StructType(( 'item', Slot ), )}, + 402 : {3: StructType(( 'blockState', VarInt ), ), 11: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 20: StructType(( 'blockState', VarInt ), ), 27: StructType(( 'item', Slot ), )}, + 403 : {3: StructType(( 'blockState', VarInt ), ), 11: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 20: StructType(( 'blockState', VarInt ), ), 27: StructType(( 'item', Slot ), )}, + 404 : {3: StructType(( 'blockState', VarInt ), ), 11: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 20: StructType(( 'blockState', VarInt ), ), 27: StructType(( 'item', Slot ), )}, + 477 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 32: StructType(( 'item', Slot ), )}, + 480 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 32: StructType(( 'item', Slot ), )}, + 490 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 32: StructType(( 'item', Slot ), )}, + 498 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 32: StructType(( 'item', Slot ), )}, + 573 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 32: StructType(( 'item', Slot ), )}, + 575 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 32: StructType(( 'item', Slot ), )}, + 578 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 32: StructType(( 'item', Slot ), )}, + 709 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 34: StructType(( 'item', Slot ), )}, + 734 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 34: StructType(( 'item', Slot ), )}, + 735 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 34: StructType(( 'item', Slot ), )}, + 736 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 34: StructType(( 'item', Slot ), )}, + 751 : {3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 23: StructType(( 'blockState', VarInt ), ), 34: StructType(( 'item', Slot ), )}, + 755 : {4: StructType(( 'blockState', VarInt ), ), 15: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 16: StructType(( 'fromRed', Float ), ( 'fromGreen', Float ), ( 'fromBlue', Float ), ( 'scale', Float ), ( 'toRed', Float ), ( 'toGreen', Float ), ( 'toBlue', Float ), ), 25: StructType(( 'blockState', VarInt ), ), 36: StructType(( 'item', Slot ), ), 37: StructType(( 'origin', Position ), ( 'positionType', String ), ( 'destination', SwitchType('positionType', { 'minecraft:block' : Position, 'minecraft:entity' : VarInt }, None, ) ), ( 'ticks', VarInt ), )}, + 756 : {4: StructType(( 'blockState', VarInt ), ), 15: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 16: StructType(( 'fromRed', Float ), ( 'fromGreen', Float ), ( 'fromBlue', Float ), ( 'scale', Float ), ( 'toRed', Float ), ( 'toGreen', Float ), ( 'toBlue', Float ), ), 25: StructType(( 'blockState', VarInt ), ), 36: StructType(( 'item', Slot ), ), 37: StructType(( 'origin', Position ), ( 'positionType', String ), ( 'destination', SwitchType('positionType', { 'minecraft:block' : Position, 'minecraft:entity' : VarInt }, None, ) ), ( 'ticks', VarInt ), )}, + 757 : {2: StructType(( 'blockState', VarInt ), ), 3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 15: StructType(( 'fromRed', Float ), ( 'fromGreen', Float ), ( 'fromBlue', Float ), ( 'scale', Float ), ( 'toRed', Float ), ( 'toGreen', Float ), ( 'toBlue', Float ), ), 24: StructType(( 'blockState', VarInt ), ), 35: StructType(( 'item', Slot ), ), 36: StructType(( 'origin', Position ), ( 'positionType', String ), ( 'destination', SwitchType('positionType', { 'minecraft:block' : Position, 'minecraft:entity' : VarInt }, None, ) ), ( 'ticks', VarInt ), )}, + 758 : {2: StructType(( 'blockState', VarInt ), ), 3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 15: StructType(( 'fromRed', Float ), ( 'fromGreen', Float ), ( 'fromBlue', Float ), ( 'scale', Float ), ( 'toRed', Float ), ( 'toGreen', Float ), ( 'toBlue', Float ), ), 24: StructType(( 'blockState', VarInt ), ), 35: StructType(( 'item', Slot ), ), 36: StructType(( 'origin', Position ), ( 'positionType', String ), ( 'destination', SwitchType('positionType', { 'minecraft:block' : Position, 'minecraft:entity' : VarInt }, None, ) ), ( 'ticks', VarInt ), )}, + 759 : {2: StructType(( 'blockState', VarInt ), ), 3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 15: StructType(( 'fromRed', Float ), ( 'fromGreen', Float ), ( 'fromBlue', Float ), ( 'scale', Float ), ( 'toRed', Float ), ( 'toGreen', Float ), ( 'toBlue', Float ), ), 24: StructType(( 'blockState', VarInt ), ), 35: StructType(( 'item', Slot ), ), 36: StructType(( 'origin', Position ), ( 'positionType', String ), ( 'destination', SwitchType('positionType', { 'minecraft:block' : Position, 'minecraft:entity' : VarInt }, None, ) ), ( 'ticks', VarInt ), )}, + 760 : {2: StructType(( 'blockState', VarInt ), ), 3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 15: StructType(( 'fromRed', Float ), ( 'fromGreen', Float ), ( 'fromBlue', Float ), ( 'scale', Float ), ( 'toRed', Float ), ( 'toGreen', Float ), ( 'toBlue', Float ), ), 24: StructType(( 'blockState', VarInt ), ), 35: StructType(( 'item', Slot ), ), 36: StructType(( 'origin', Position ), ( 'positionType', String ), ( 'destination', SwitchType('positionType', { 'minecraft:block' : Position, 'minecraft:entity' : VarInt }, None, ) ), ( 'ticks', VarInt ), )}, + 761 : {2: StructType(( 'blockState', VarInt ), ), 3: StructType(( 'blockState', VarInt ), ), 14: StructType(( 'red', Float ), ( 'green', Float ), ( 'blue', Float ), ( 'scale', Float ), ), 15: StructType(( 'fromRed', Float ), ( 'fromGreen', Float ), ( 'fromBlue', Float ), ( 'scale', Float ), ( 'toRed', Float ), ( 'toGreen', Float ), ( 'toBlue', Float ), ), 24: StructType(( 'blockState', VarInt ), ), 35: StructType(( 'item', Slot ), ), 36: StructType(( 'origin', Position ), ( 'positionType', String ), ( 'destination', SwitchType('positionType', { 'minecraft:block' : Position, 'minecraft:entity' : VarInt }, None, ) ), ( 'ticks', VarInt ), )} + } diff --git a/aiocraft/mc/types.py b/aiocraft/mc/types.py index 37e9015..0c67f43 100644 --- a/aiocraft/mc/types.py +++ b/aiocraft/mc/types.py @@ -11,7 +11,7 @@ from typing import List, Tuple, Dict, Any, Union, Optional, Callable, Type as Cl from .definitions import Item -class Context(object): +class Context: def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) @@ -29,7 +29,7 @@ class Context(object): values = ( f"{k}={repr(v)}" for k,v in vars(self).items() ) return f"Context({', '.join(values)})" -class Type(object): +class Type: pytype : Union[type, Callable] = lambda x : x def write(self, data:Any, buffer:io.BytesIO, ctx:Context) -> None: @@ -113,10 +113,11 @@ class NBTType(Type): pynbt.NBTFile(value=data).save(buffer) def read(self, buffer:io.BytesIO, ctx:Context) -> Optional[dict]: + index = buffer.tell() head = Byte.read(buffer, ctx) if head == 0x0: return None - buffer.seek(-1,1) # go back 1 byte + buffer.seek(index) # go back to start and read again return nbt_to_py(pynbt.NBTFile(io=buffer)) NBTTag = NBTType() @@ -302,10 +303,20 @@ class SwitchType(Type): field : str mappings : Dict[Any, Type] - def __init__(self, watch:str, mappings:Dict[Any, Type], default:Type = None): + def __init__(self, watch:str, mappings:Dict[Any, Type], default:Type | None = None): self.field = watch - self.mappings = mappings self.default = default + # TODO AWFUL FIX, probably because json is weird + self.mappings = {} + for k, v in mappings.items(): + if k == 'true': + self.mappings[True] = v + elif k == 'false': + self.mappings[False] = v + else: + # TODO probably breaks for numbers too? + self.mappings[k] = v + # TODO AWFUL FIX, probably because json is weird def write(self, data:Any, buffer:io.BytesIO, ctx:Context): watched = getattr(ctx, self.field, None) @@ -379,88 +390,18 @@ class ParticleType(Type): # TODO this changes across versions! def read(self, data:dict, buffer:io.BytesIO, ctx:Context): - data : Dict[str, Any] = {} - data["id"] = VarInt.read(buffer, ctx) - if data["id"] in (3, 23): - data["blockState"] = VarInt.read(buffer, ctx) - elif data["id"] == 32: - data["item"] = Slot.read(buffer, ctx) - elif data["id"] == 14: - data["red"] = Float.read(buffer, ctx) - data["green"] = Float.read(buffer, ctx) - data["blue"] = Float.read(buffer, ctx) - data["scale"] = Float.read(buffer, ctx) + from aiocraft.mc.proto.ext import ParticlesDefinitions + data_id = VarInt.read(buffer, ctx) + if data_id in ParticlesDefinitions._definitions[ctx._proto]: + t = ParticlesDefinitions._definitions[ctx._proto][data_id] + data = t.read(buffer, ctx) + data["id"] = data_id + else: + data = {"id": data_id} return data Particle = ParticleType() -# wiki.vg does not document these anymore. Minecraft 1.12.2 has these as metadata types -_ENTITY_METADATA_TYPES = { - 0 : Byte, - 1 : VarInt, - 2 : Float, - 3 : String, - 4 : Chat, - 5 : Slot, - 6 : Boolean, - 7 : StructType(("x", Float), ("y", Float), ("z", Float)), # Rotation - 8 : Position, - 9 : OptionalType(Position), - 10 : VarInt, # Direction (Down = 0, Up = 1, North = 2, South = 3, West = 4, East = 5) - 11 : OptionalType(UUID), - 12 : VarInt, # OptBlockID (VarInt) 0 for absent (implies air); otherwise, a block state ID as per the global palette - 13 : NBTTag, -} - -_ENTITY_METADATA_TYPES_NEW = { - 0 : Byte, - 1 : VarInt, - 2 : Float, - 3 : String, - 4 : Chat, - 5 : OptionalType(Chat), - 6 : Slot, - 7 : Boolean, - 8 : StructType(("x", Float), ("y", Float), ("z", Float)), - 9 : Position, - 10 : OptionalType(Position), - 11 : VarInt, # Direction - 12 : OptionalType(UUID), - 13 : VarInt, # Optional BlockID - 14 : NBTTag, - 15 : Particle, - 16 : StructType(("type", VarInt), ("profession", VarInt), ("level", VarInt)), - 17 : OptionalType(VarInt), - 18 : VarInt, # pose -} - -# This is for 1.19 -# _ENTITY_METADATA_TYPES_NEW = { -# 0 : Byte, -# 1 : VarInt, -# 2 : VarLong, -# 3 : Float, -# 4 : String, -# 5 : Chat, -# 6 : OptionalType(Chat), -# 7 : Slot, -# 8 : Boolean, -# 9 : StructType(("x", Float), ("y", Float), ("z", Float)), -# 10 : Position, -# 11 : OptionalType(Position), -# 12 : VarInt, # Direction -# 13 : OptionalType(UUID), -# 14 : OptionalType(VarInt), # Optional BlockID -# 15 : NBTTag, -# 16 : Particle, -# 17 : StructType(("type", VarInt), ("profession", VarInt), ("level", VarInt)), -# 18 : OptionalType(VarInt), -# 19 : VarInt, # pose -# 20 : VarInt, # cat variant -# 21 : VarInt, # frog variant -# 22 : StructType(("dimension", Identifier), ("position", Position)), -# 23 : VarInt, # painting variant -# } class EntityMetadataType(Type): pytype : type = dict @@ -470,7 +411,8 @@ class EntityMetadataType(Type): buffer.write(b'\xFF') def read(self, buffer:io.BytesIO, ctx:Context) -> Dict[int, Any]: - types_map = _ENTITY_METADATA_TYPES_NEW if ctx._proto > 340 else _ENTITY_METADATA_TYPES + from aiocraft.mc.proto.ext import MetadataDefinitions + types_map = MetadataDefinitions._definitions[ctx._proto] out : Dict[int, Any] = {} while True: index = UnsignedByte.read(buffer, ctx) diff --git a/compiler/proto.py b/compiler/proto.py index 29e7849..68dcc8f 100644 --- a/compiler/proto.py +++ b/compiler/proto.py @@ -5,10 +5,7 @@ import keyword import logging from pathlib import Path -from typing import Tuple, List, Dict, Union, Set, Type as Class - -from aiocraft.mc.types import * -from aiocraft.mc.definitions import Item +from typing import Any # TODO de-spaghetti this file sometime! @@ -35,6 +32,15 @@ class {name}(Packet): _definitions : Dict[int, List[Tuple[str, Type]]] = {definitions} """ +EXT_FORMATTER = """from ..types import * + +class MetadataDefinitions: + _definitions: dict[int, dict[int, Type]] = {metadata} + +class ParticlesDefinitions: + _definitions: dict[int, dict[int, Type]] = {particles} +""" + class Ref: name : str args : tuple @@ -135,7 +141,7 @@ def format_dict(d:dict, depth:int=1) -> str: def format_list(l:list, depth:int=0) -> str: return "[" + _format_line(l, depth) + "]" -def format_tuple(l:list, depth:int=0) -> str: +def format_tuple(l:tuple | list, depth:int=0) -> str: return "(" + _format_line(l, depth) + ")" def mctype(slot_type:Any) -> Ref: @@ -231,11 +237,11 @@ def snake_to_camel(name:str) -> str: class PacketClassWriter: name : str - attrs : Set[str] - types : Dict[str, List[Type]] - hints : Dict[str, List[Type]] - ids : Dict[int, int] - definitions : Dict[int, List[Tuple[str, Type]]] + attrs : set[str] + types : dict[str, set[Ref]] + hints : dict[str, set[Ref]] + ids : dict[int, int] + definitions : dict[int, list[tuple[str, Ref]]] state : int def __init__(self, pkt:dict, state:int): @@ -253,7 +259,7 @@ class PacketClassWriter: if "name" not in field: logging.error("Skipping anonymous field %s", str(field)) continue - field_name = field["name"] if not keyword.iskeyword(field["name"]) else "is_" + field["name"] + field_name : str = field["name"] if not keyword.iskeyword(field["name"]) else "is_" + field["name"] self.attrs.add(field_name) self.definitions[v].append((field_name, mctype(field["type"]))) if field_name not in self.types: @@ -269,7 +275,7 @@ class PacketClassWriter: OBJECT.format( name=self.name, ids=format_dict(self.ids, depth=2), - definitions=format_dict({ k : Ref(format_list(Ref(format_tuple(x)) for x in v)) for k,v in self.definitions.items() }, depth=2), + definitions=format_dict({ k : Ref(format_list([Ref(format_tuple(x)) for x in v])) for k,v in self.definitions.items() }, depth=2), slots=format_tuple(["id"] + sorted(self.attrs), depth=0), # TODO jank fix when no slots fields="\n\t" + "\n\t".join(f"{a} : {pytype(sorted(self.hints[a]))}" for a in sorted(self.attrs)), state=self.state, @@ -345,6 +351,9 @@ def compile(): "serverbound": {}, } } + + METADATA = {} + PARTICLES = {} all_versions = os.listdir(mc_path / f'{folder_name}/data/pc/') all_versions.remove("common") @@ -368,6 +377,15 @@ def compile(): with open(mc_path / f'{folder_name}/data/pc/{v}/protocol.json') as f: data = json.load(f) + METADATA[proto_version] = {} + for meta_id, meta_type in data["types"]["entityMetadataItem"][1]["fields"].items(): + METADATA[proto_version][int(meta_id)] = mctype(meta_type) + + if "particleData" in data["types"]: + PARTICLES[proto_version] = {} + for p_id, p_type in data["types"]["particleData"][1]["fields"].items(): + PARTICLES[proto_version][int(p_id)] = mctype(p_type) + # Build data structure containing all packets with all their definitions for different versions for state in ("handshaking", "status", "login", "play"): for _direction in ("toClient", "toServer"): @@ -402,6 +420,15 @@ def compile(): _STATE_MAP = {"handshaking": 0, "status":1, "login":2, "play":3} _make_module(mc_path / 'proto', { k:"*" for k in PACKETS.keys() }) + + with open(mc_path / 'proto' / 'ext.py', 'w') as f: + f.write( + EXT_FORMATTER.format( + metadata = format_dict(METADATA, depth=2), + particles = format_dict(PARTICLES, depth=2), + ) + ) + for state in PACKETS.keys(): _make_module(mc_path / f"proto/{state}", { k:"*" for k in PACKETS[state].keys() }) for direction in PACKETS[state].keys():