fix: generate metadata and particles, fix switch

now entity metadata and particle data are loaded from minecraft-data and
thus should just work ™️ 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" ...
This commit is contained in:
əlemi 2023-11-01 22:08:52 +01:00
parent e74da435ea
commit 63da8ddcd5
Signed by: alemi
GPG key ID: A4895B84D311642C
4 changed files with 142 additions and 99 deletions

View file

@ -1,7 +1,7 @@
import io import io
import json import json
from asyncio import Event from asyncio import Event
from typing import Tuple, Dict, Any from typing import Tuple, List, Dict, Any
from .types import Type, VarInt, Context from .types import Type, VarInt, Context
@ -11,13 +11,13 @@ class Packet:
__slots__ = 'id', 'definition', '_processed', '_proto', '_state' __slots__ = 'id', 'definition', '_processed', '_proto', '_state'
id : int id : int
definition : Tuple[Tuple[str, Type]] definition : List[Tuple[str, Type]]
_processed : Event _processed : Event
_proto : int _proto : int
_state : int _state : int
_ids : Dict[int, int] # definitions are compiled at install time _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): def __init__(self, proto:int, **kwargs):
self._proto = proto self._proto = proto

74
aiocraft/mc/proto/ext.py Normal file
View file

@ -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 ), )}
}

View file

@ -11,7 +11,7 @@ from typing import List, Tuple, Dict, Any, Union, Optional, Callable, Type as Cl
from .definitions import Item from .definitions import Item
class Context(object): class Context:
def __init__(self, **kwargs): def __init__(self, **kwargs):
for k, v in kwargs.items(): for k, v in kwargs.items():
setattr(self, k, v) setattr(self, k, v)
@ -29,7 +29,7 @@ class Context(object):
values = ( f"{k}={repr(v)}" for k,v in vars(self).items() ) values = ( f"{k}={repr(v)}" for k,v in vars(self).items() )
return f"Context({', '.join(values)})" return f"Context({', '.join(values)})"
class Type(object): class Type:
pytype : Union[type, Callable] = lambda x : x pytype : Union[type, Callable] = lambda x : x
def write(self, data:Any, buffer:io.BytesIO, ctx:Context) -> None: def write(self, data:Any, buffer:io.BytesIO, ctx:Context) -> None:
@ -113,10 +113,11 @@ class NBTType(Type):
pynbt.NBTFile(value=data).save(buffer) pynbt.NBTFile(value=data).save(buffer)
def read(self, buffer:io.BytesIO, ctx:Context) -> Optional[dict]: def read(self, buffer:io.BytesIO, ctx:Context) -> Optional[dict]:
index = buffer.tell()
head = Byte.read(buffer, ctx) head = Byte.read(buffer, ctx)
if head == 0x0: if head == 0x0:
return None 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)) return nbt_to_py(pynbt.NBTFile(io=buffer))
NBTTag = NBTType() NBTTag = NBTType()
@ -302,10 +303,20 @@ class SwitchType(Type):
field : str field : str
mappings : Dict[Any, Type] 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.field = watch
self.mappings = mappings
self.default = default 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): def write(self, data:Any, buffer:io.BytesIO, ctx:Context):
watched = getattr(ctx, self.field, None) watched = getattr(ctx, self.field, None)
@ -379,88 +390,18 @@ class ParticleType(Type):
# TODO this changes across versions! # TODO this changes across versions!
def read(self, data:dict, buffer:io.BytesIO, ctx:Context): def read(self, data:dict, buffer:io.BytesIO, ctx:Context):
data : Dict[str, Any] = {} from aiocraft.mc.proto.ext import ParticlesDefinitions
data["id"] = VarInt.read(buffer, ctx) data_id = VarInt.read(buffer, ctx)
if data["id"] in (3, 23): if data_id in ParticlesDefinitions._definitions[ctx._proto]:
data["blockState"] = VarInt.read(buffer, ctx) t = ParticlesDefinitions._definitions[ctx._proto][data_id]
elif data["id"] == 32: data = t.read(buffer, ctx)
data["item"] = Slot.read(buffer, ctx) data["id"] = data_id
elif data["id"] == 14: else:
data["red"] = Float.read(buffer, ctx) data = {"id": data_id}
data["green"] = Float.read(buffer, ctx)
data["blue"] = Float.read(buffer, ctx)
data["scale"] = Float.read(buffer, ctx)
return data return data
Particle = ParticleType() 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): class EntityMetadataType(Type):
pytype : type = dict pytype : type = dict
@ -470,7 +411,8 @@ class EntityMetadataType(Type):
buffer.write(b'\xFF') buffer.write(b'\xFF')
def read(self, buffer:io.BytesIO, ctx:Context) -> Dict[int, Any]: 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] = {} out : Dict[int, Any] = {}
while True: while True:
index = UnsignedByte.read(buffer, ctx) index = UnsignedByte.read(buffer, ctx)

View file

@ -5,10 +5,7 @@ import keyword
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Tuple, List, Dict, Union, Set, Type as Class from typing import Any
from aiocraft.mc.types import *
from aiocraft.mc.definitions import Item
# TODO de-spaghetti this file sometime! # TODO de-spaghetti this file sometime!
@ -35,6 +32,15 @@ class {name}(Packet):
_definitions : Dict[int, List[Tuple[str, Type]]] = {definitions} _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: class Ref:
name : str name : str
args : tuple args : tuple
@ -135,7 +141,7 @@ def format_dict(d:dict, depth:int=1) -> str:
def format_list(l:list, depth:int=0) -> str: def format_list(l:list, depth:int=0) -> str:
return "[" + _format_line(l, depth) + "]" 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) + ")" return "(" + _format_line(l, depth) + ")"
def mctype(slot_type:Any) -> Ref: def mctype(slot_type:Any) -> Ref:
@ -231,11 +237,11 @@ def snake_to_camel(name:str) -> str:
class PacketClassWriter: class PacketClassWriter:
name : str name : str
attrs : Set[str] attrs : set[str]
types : Dict[str, List[Type]] types : dict[str, set[Ref]]
hints : Dict[str, List[Type]] hints : dict[str, set[Ref]]
ids : Dict[int, int] ids : dict[int, int]
definitions : Dict[int, List[Tuple[str, Type]]] definitions : dict[int, list[tuple[str, Ref]]]
state : int state : int
def __init__(self, pkt:dict, state:int): def __init__(self, pkt:dict, state:int):
@ -253,7 +259,7 @@ class PacketClassWriter:
if "name" not in field: if "name" not in field:
logging.error("Skipping anonymous field %s", str(field)) logging.error("Skipping anonymous field %s", str(field))
continue 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.attrs.add(field_name)
self.definitions[v].append((field_name, mctype(field["type"]))) self.definitions[v].append((field_name, mctype(field["type"])))
if field_name not in self.types: if field_name not in self.types:
@ -269,7 +275,7 @@ class PacketClassWriter:
OBJECT.format( OBJECT.format(
name=self.name, name=self.name,
ids=format_dict(self.ids, depth=2), 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 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)), fields="\n\t" + "\n\t".join(f"{a} : {pytype(sorted(self.hints[a]))}" for a in sorted(self.attrs)),
state=self.state, state=self.state,
@ -345,6 +351,9 @@ def compile():
"serverbound": {}, "serverbound": {},
} }
} }
METADATA = {}
PARTICLES = {}
all_versions = os.listdir(mc_path / f'{folder_name}/data/pc/') all_versions = os.listdir(mc_path / f'{folder_name}/data/pc/')
all_versions.remove("common") all_versions.remove("common")
@ -368,6 +377,15 @@ def compile():
with open(mc_path / f'{folder_name}/data/pc/{v}/protocol.json') as f: with open(mc_path / f'{folder_name}/data/pc/{v}/protocol.json') as f:
data = json.load(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 # Build data structure containing all packets with all their definitions for different versions
for state in ("handshaking", "status", "login", "play"): for state in ("handshaking", "status", "login", "play"):
for _direction in ("toClient", "toServer"): for _direction in ("toClient", "toServer"):
@ -402,6 +420,15 @@ def compile():
_STATE_MAP = {"handshaking": 0, "status":1, "login":2, "play":3} _STATE_MAP = {"handshaking": 0, "status":1, "login":2, "play":3}
_make_module(mc_path / 'proto', { k:"*" for k in PACKETS.keys() }) _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(): for state in PACKETS.keys():
_make_module(mc_path / f"proto/{state}", { k:"*" for k in PACKETS[state].keys() }) _make_module(mc_path / f"proto/{state}", { k:"*" for k in PACKETS[state].keys() })
for direction in PACKETS[state].keys(): for direction in PACKETS[state].keys():