fix for Context changes

This commit is contained in:
əlemi 2022-01-15 04:22:13 +01:00
parent 4a6b843c24
commit 416b545e46
3 changed files with 18 additions and 13 deletions

View file

@ -222,7 +222,7 @@ class Dispatcher:
buffer = io.BytesIO(data) buffer = io.BytesIO(data)
if self.compression is not None: if self.compression is not None:
decompressed_size = VarInt.read(buffer, Context()) decompressed_size = VarInt.read(buffer, Context(_proto=self.proto))
if decompressed_size > 0: if decompressed_size > 0:
decompressor = zlib.decompressobj() decompressor = zlib.decompressobj()
decompressed_data = decompressor.decompress(buffer.read()) decompressed_data = decompressor.decompress(buffer.read())
@ -230,7 +230,7 @@ class Dispatcher:
raise ValueError(f"Failed decompressing packet: expected size is {decompressed_size}, but actual size is {len(decompressed_data)}") raise ValueError(f"Failed decompressing packet: expected size is {decompressed_size}, but actual size is {len(decompressed_data)}")
buffer = io.BytesIO(decompressed_data) buffer = io.BytesIO(decompressed_data)
packet_id = VarInt.read(buffer, Context()) packet_id = VarInt.read(buffer, Context(_proto=self.proto))
if self.state == ConnectionState.PLAY and self._packet_id_whitelist \ if self.state == ConnectionState.PLAY and self._packet_id_whitelist \
and packet_id not in self._packet_id_whitelist: and packet_id not in self._packet_id_whitelist:
self._logger.debug("[<--] Received | Packet(0x%02x) (ignored)", packet_id) self._logger.debug("[<--] Received | Packet(0x%02x) (ignored)", packet_id)
@ -269,12 +269,12 @@ class Dispatcher:
if self.compression is not None: if self.compression is not None:
if length > self.compression: if length > self.compression:
new_buffer = io.BytesIO() new_buffer = io.BytesIO()
VarInt.write(length, new_buffer) VarInt.write(length, new_buffer, Context(_proto=self.proto))
new_buffer.write(zlib.compress(buffer.read())) new_buffer.write(zlib.compress(buffer.read()))
buffer = new_buffer buffer = new_buffer
else: else:
new_buffer = io.BytesIO() new_buffer = io.BytesIO()
VarInt.write(0, new_buffer) VarInt.write(0, new_buffer, Context(_proto=self.proto))
new_buffer.write(buffer.read()) new_buffer.write(buffer.read())
buffer = new_buffer buffer = new_buffer
length = len(buffer.getvalue()) length = len(buffer.getvalue())

View file

@ -3,7 +3,7 @@ import json
from asyncio import Event from asyncio import Event
from typing import Tuple, Dict, Any from typing import Tuple, Dict, Any
from .types import Type, VarInt from .types import Type, VarInt, Context
class Packet: class Packet:
__slots__ = 'id', 'definition', '_processed', '_proto', '_state' __slots__ = 'id', 'definition', '_processed', '_proto', '_state'
@ -24,7 +24,7 @@ class Packet:
self.id = self._ids[proto] self.id = self._ids[proto]
for name, t in self.definition: for name, t in self.definition:
if name in kwargs and kwargs[name] is not None: if name in kwargs and kwargs[name] is not None:
setattr(self, name, t.pytype(kwargs[name])) setattr(self, name, kwargs[name])
@property @property
def processed(self) -> Event: def processed(self) -> Event:
@ -33,18 +33,20 @@ class Packet:
@classmethod @classmethod
def deserialize(cls, proto:int, buffer:io.BytesIO): def deserialize(cls, proto:int, buffer:io.BytesIO):
pkt = cls(proto) ctx = Context(_proto=proto)
for k, t in cls._definitions[proto]: for k, t in cls._definitions[proto]:
setattr(pkt, k, t.read(buffer, ctx=pkt)) setattr(ctx, k, t.read(buffer, ctx=ctx))
return pkt return cls(proto, **ctx.as_dict())
# return cls(proto, **{ name : t.read(buffer) for (name, t) in cls._definitions[proto] }) # return cls(proto, **{ name : t.read(buffer) for (name, t) in cls._definitions[proto] })
def serialize(self) -> io.BytesIO: def serialize(self) -> io.BytesIO:
ctx = Context(_proto=self._proto)
buf = io.BytesIO() buf = io.BytesIO()
VarInt.write(self.id, buf) VarInt.write(self.id, buf, ctx=ctx)
for name, t in self.definition: for name, t in self.definition:
if getattr(self, name, None) is not None: # minecraft proto has no null type: this is an optional field left unset if getattr(self, name, None) is not None: # minecraft proto has no null type: this is an optional field left unset
t.write(getattr(self, name), buf, ctx=self) setattr(ctx, name, getattr(self, name)) # TODO maybe **vars(self) in ctx constructor?
t.write(getattr(self, name), buf, ctx=ctx)
buf.seek(0) buf.seek(0)
return buf return buf

View file

@ -13,14 +13,17 @@ from .definitions import Item
class Context(object): class Context(object):
def __init__(self, **kwargs): def __init__(self, **kwargs):
for k, v in kwargs: for k, v in kwargs.items():
setattr(self, k, v) setattr(self, k, v)
def as_dict(self) -> dict:
return vars(self) # is this reliable?
def __getattr__(self, name) -> Any: def __getattr__(self, name) -> Any:
return None # return None rather than raising an exc return None # return None rather than raising an exc
def __str__(self) -> str: def __str__(self) -> str:
return json.dumps(vars(self), indent=2, default=str, sort_keys=True) return json.dumps(self.as_dict(), indent=2, default=str, sort_keys=True)
def __repr__(self) -> str: def __repr__(self) -> str:
values = ( f"{k}={repr(v)}" for k,v in vars(self).items() ) values = ( f"{k}={repr(v)}" for k,v in vars(self).items() )