fix for fixed len arrays

This commit is contained in:
əlemi 2021-12-10 13:03:48 +01:00
parent eab07320b5
commit 7e24764df5
3 changed files with 16 additions and 14 deletions

View file

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

View file

@ -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

View file

@ -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