fix for fixed len arrays
This commit is contained in:
parent
eab07320b5
commit
7e24764df5
3 changed files with 16 additions and 14 deletions
|
@ -17,8 +17,6 @@ from .util import encryption
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
DIFFICULT_PACKETS = (28, 36, 77) # Explosion, Map, Advancements
|
|
||||||
|
|
||||||
class InvalidState(Exception):
|
class InvalidState(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -217,8 +215,6 @@ class Dispatcher:
|
||||||
buffer = io.BytesIO(decompressed_data)
|
buffer = io.BytesIO(decompressed_data)
|
||||||
|
|
||||||
packet_id = VarInt.read(buffer)
|
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)
|
cls = self._packet_type_from_registry(packet_id)
|
||||||
self._logger.debug("Deserializing packet %s | %s", str(cls), cls._state)
|
self._logger.debug("Deserializing packet %s | %s", str(cls), cls._state)
|
||||||
packet = cls.deserialize(self.proto, buffer)
|
packet = cls.deserialize(self.proto, buffer)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import struct
|
||||||
import asyncio
|
import asyncio
|
||||||
import uuid
|
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):
|
class Type(object):
|
||||||
pytype : type
|
pytype : type
|
||||||
|
@ -109,7 +109,7 @@ class VarLenPrimitive(Type):
|
||||||
|
|
||||||
def deserialize(self, data:bytes) -> int:
|
def deserialize(self, data:bytes) -> int:
|
||||||
buf = io.BytesIO(data)
|
buf = io.BytesIO(data)
|
||||||
return self.read(buf, ctx=ctx)
|
return self.read(buf)
|
||||||
|
|
||||||
VarInt = VarLenPrimitive(5)
|
VarInt = VarLenPrimitive(5)
|
||||||
VarLong = VarLenPrimitive(10)
|
VarLong = VarLenPrimitive(10)
|
||||||
|
@ -181,20 +181,23 @@ UUID = UUIDType()
|
||||||
|
|
||||||
class ArrayType(Type):
|
class ArrayType(Type):
|
||||||
pytype : type = list
|
pytype : type = list
|
||||||
counter : Type
|
counter : Union[int, Type]
|
||||||
content : 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.content = content
|
||||||
self.counter = counter
|
self.counter = counter
|
||||||
|
|
||||||
def write(self, data:List[Any], buffer:io.BytesIO, ctx:object=None):
|
def write(self, data:List[Any], buffer:io.BytesIO, ctx:object=None):
|
||||||
self.counter.write(len(data), buffer, ctx=ctx)
|
if isinstance(self.counter, Type):
|
||||||
for el in data:
|
self.counter.write(len(data), buffer, ctx=ctx)
|
||||||
|
for i, el in enumerate(data):
|
||||||
self.content.write(el, buffer, ctx=ctx)
|
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]:
|
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) ]
|
return [ self.content.read(buffer, ctx=ctx) for _ in range(length) ]
|
||||||
|
|
||||||
class OptionalType(Type):
|
class OptionalType(Type):
|
||||||
|
@ -230,13 +233,13 @@ class SwitchType(Type):
|
||||||
elif self.default:
|
elif self.default:
|
||||||
return self.default.write(data, buffer, ctx=ctx)
|
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)
|
watched = getattr(ctx, self.field)
|
||||||
if watched in self.mappings:
|
if watched in self.mappings:
|
||||||
return self.mappings[watched].read(buffer, ctx=ctx)
|
return self.mappings[watched].read(buffer, ctx=ctx)
|
||||||
elif self.default:
|
elif self.default:
|
||||||
return self.default.read(buffer, ctx=ctx)
|
return self.default.read(buffer, ctx=ctx)
|
||||||
return {}
|
return None
|
||||||
|
|
||||||
class StructType(Type):
|
class StructType(Type):
|
||||||
pytype : type = dict
|
pytype : type = dict
|
||||||
|
|
|
@ -123,7 +123,10 @@ def mctype(slot_type:Any) -> Ref:
|
||||||
return Ref('IntegerByteArray')
|
return Ref('IntegerByteArray')
|
||||||
return Ref('ByteArray')
|
return Ref('ByteArray')
|
||||||
elif t == "array": # Generic array
|
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
|
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???
|
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
|
elif t == "option": # Optional
|
||||||
|
|
Loading…
Reference in a new issue