implemented some more types

This commit is contained in:
əlemi 2021-11-29 03:51:58 +01:00
parent 934e00f112
commit b20a2c751b
2 changed files with 64 additions and 19 deletions

View file

@ -17,6 +17,7 @@ from .util import encryption
LOGGER = logging.getLogger(__name__)
DIFFICULT_PACKETS = (28, 36) # Explosion, Map
class InvalidState(Exception):
pass
@ -194,6 +195,7 @@ class Dispatcher:
length = await self._read_varint()
return await self._down.readexactly(length)
async def _down_worker(self, timeout:float=30):
while self._dispatching:
try: # these 2 will timeout or raise EOFError if client gets disconnected
@ -215,6 +217,8 @@ 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)
@ -222,8 +226,6 @@ class Dispatcher:
await self._incoming.put(packet)
if self.state != ConnectionState.PLAY:
await self._incoming.join() # During play we can pre-process packets
except AttributeError:
self._logger.debug("Received unimplemented packet [%d] %s", packet_id, cls.__name__) # TODO this is cheating! implement them!
except (asyncio.TimeoutError, TimeoutError):
self._logger.error("Connection timed out")
await self.disconnect(block=False)

View file

@ -1,8 +1,9 @@
import io
import struct
import asyncio
import uuid
from typing import Any
from typing import Any, Optional, Type as VarType
class Type(object):
_pytype : type
@ -138,6 +139,29 @@ class VarLong(VarInt):
_pytype : type = int
_size = 10
# class Maybe(Type): # TODO better fucking name!
# _t : Type
#
# @classmethod
# def of(cls, t:Type) -> VarType[Maybe]:
# return type(f"Optional{t.__name__}", (Maybe,), {"_t":t})
#
# @classmethod
# def write(cls, data:Optional[Any], buffer:io.BytesIO):
# if not hasattr(cls, "_t"):
# raise NotImplementedError
# Boolean.write(bool(data), buffer)
# if data:
# cls._t.write(data, buffer)
#
# @classmethod
# def read(cls, buffer:io.BytesIO) -> Optional[cls.T]:
# if not hasattr(cls, "_t"):
# raise NotImplementedError
# if Boolean.read(buffer):
# return cls._t.read(buffer)
# return None
class String(Type):
_pytype : type = str
@ -189,36 +213,46 @@ class Angle(Type):
_size : int = 1
_fmt : str = ">b"
class EntityMetadata(Type):
_pytype : type = bytes
# TODO
pass
class EntityMetadataItem(Type):
_pytype : type = bytes
# TODO
pass
class Slot(Type):
_pytype : type = bytes
# TODO
pass
class NBTTag(Type):
_pytype : type = bytes
# TODO
pass
class Position(Type):
_pytype : type = bytes
# TODO
pass
_pytype : type = tuple
_size = 8
# TODO THIS IS FOR 1.12.2!!!
@classmethod
def write(cls, data:tuple, buffer:io.BytesIO):
packed = ((0x3FFFFFF & data[0]) << 38) | ((0xFFF & data[1]) << 26) | (0x3FFFFFF & data[2])
UnsignedLong.write(packed, buffer)
@classmethod
def read(cls, buffer:io.BytesIO) -> tuple:
packed = UnsignedLong.read(buffer)
x = packed >> 38
y = (packed >> 24) & 0xFFF
z = packed & 0x3FFFFFF
return (x, y, z)
class UUID(Type):
_pytype : type = bytes
# TODO
pass
_pytype : type = str
_size = 16
@classmethod
def write(cls, data:uuid.UUID, buffer:io.BytesIO):
buffer.write(int(data).to_bytes(cls._size, 'big'))
@classmethod
def read(cls, buffer:io.BytesIO) -> uuid.UUID:
return uuid.UUID(int=int.from_bytes(buffer.read(cls._size), 'big'))
class TrailingByteArray(Type):
_pytype : type = bytes
@ -232,3 +266,12 @@ class TrailingByteArray(Type):
def read(cls, buffer:io.BytesIO) -> bytes:
return buffer.read()
class EntityMetadata(TrailingByteArray):
# TODO
pass
class Slot(TrailingByteArray):
_pytype : type = bytes
# TODO
pass