diff --git a/aiocraft/dispatcher.py b/aiocraft/dispatcher.py index 736196d..a644824 100644 --- a/aiocraft/dispatcher.py +++ b/aiocraft/dispatcher.py @@ -17,8 +17,6 @@ from .util import encryption LOGGER = logging.getLogger(__name__) -DIFFICULT_PACKETS = (28, 36, 77) # Explosion, Map, Advancements - class InvalidState(Exception): pass @@ -217,8 +215,6 @@ class Dispatcher: buffer = io.BytesIO(decompressed_data) packet_id = VarInt.read(buffer) - if packet_id in DIFFICULT_PACKETS: - continue # don't try to parse, can't handle types this complex (yet! TODO) cls = self._packet_type_from_registry(packet_id) self._logger.debug("Deserializing packet %s | %s", str(cls), cls._state) packet = cls.deserialize(self.proto, buffer) diff --git a/aiocraft/mc/types.py b/aiocraft/mc/types.py index edfd21b..4b56bee 100644 --- a/aiocraft/mc/types.py +++ b/aiocraft/mc/types.py @@ -3,7 +3,7 @@ import struct import asyncio import uuid -from typing import List, Tuple, Dict, Any, Optional, Type as Class +from typing import List, Tuple, Dict, Any, Union, Optional, Type as Class class Type(object): pytype : type @@ -109,7 +109,7 @@ class VarLenPrimitive(Type): def deserialize(self, data:bytes) -> int: buf = io.BytesIO(data) - return self.read(buf, ctx=ctx) + return self.read(buf) VarInt = VarLenPrimitive(5) VarLong = VarLenPrimitive(10) @@ -181,20 +181,23 @@ UUID = UUIDType() class ArrayType(Type): pytype : type = list - counter : Type + counter : Union[int, Type] content : Type - def __init__(self, content:Type, counter:Type = VarInt): + def __init__(self, content:Type, counter:Union[int, Type] = VarInt): self.content = content self.counter = counter def write(self, data:List[Any], buffer:io.BytesIO, ctx:object=None): - self.counter.write(len(data), buffer, ctx=ctx) - for el in data: + if isinstance(self.counter, Type): + self.counter.write(len(data), buffer, ctx=ctx) + for i, el in enumerate(data): self.content.write(el, buffer, ctx=ctx) + if isinstance(self.counter, int) and i >= self.counter: + break # jank but should do def read(self, buffer:io.BytesIO, ctx:object=None) -> List[Any]: - length = self.counter.read(buffer, ctx=ctx) + length = self.counter if isinstance(self.counter, int) else self.counter.read(buffer, ctx=ctx) return [ self.content.read(buffer, ctx=ctx) for _ in range(length) ] class OptionalType(Type): @@ -230,13 +233,13 @@ class SwitchType(Type): elif self.default: return self.default.write(data, buffer, ctx=ctx) - def read(self, buffer:io.BytesIO, ctx:object=None) -> Dict[str, Any]: + def read(self, buffer:io.BytesIO, ctx:object=None) -> Optional[Any]: watched = getattr(ctx, self.field) if watched in self.mappings: return self.mappings[watched].read(buffer, ctx=ctx) elif self.default: return self.default.read(buffer, ctx=ctx) - return {} + return None class StructType(Type): pytype : type = dict diff --git a/compiler/proto.py b/compiler/proto.py index 31a51be..fdae4b3 100644 --- a/compiler/proto.py +++ b/compiler/proto.py @@ -123,7 +123,10 @@ def mctype(slot_type:Any) -> Ref: return Ref('IntegerByteArray') return Ref('ByteArray') elif t == "array": # Generic array - return Ref('ArrayType', mctype(v["type"]), (mctype(v["countType"]) if "countType" in v else Ref('VarInt'))) + return Ref('ArrayType', + mctype(v["type"]), + (v["count"] if "count" in v else mctype(v["countType"]) if "countType" in v else Ref('VarInt')) + ) elif t == "container": # Struct return Ref('StructType', Ref(", ".join(format_tuple((p["name"], mctype(p["type"]))) for p in v if "name" in p))) # some fields are anonymous??? elif t == "option": # Optional