implemented some more types
This commit is contained in:
parent
934e00f112
commit
b20a2c751b
2 changed files with 64 additions and 19 deletions
|
@ -17,6 +17,7 @@ from .util import encryption
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
DIFFICULT_PACKETS = (28, 36) # Explosion, Map
|
||||||
|
|
||||||
class InvalidState(Exception):
|
class InvalidState(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -194,6 +195,7 @@ class Dispatcher:
|
||||||
length = await self._read_varint()
|
length = await self._read_varint()
|
||||||
return await self._down.readexactly(length)
|
return await self._down.readexactly(length)
|
||||||
|
|
||||||
|
|
||||||
async def _down_worker(self, timeout:float=30):
|
async def _down_worker(self, timeout:float=30):
|
||||||
while self._dispatching:
|
while self._dispatching:
|
||||||
try: # these 2 will timeout or raise EOFError if client gets disconnected
|
try: # these 2 will timeout or raise EOFError if client gets disconnected
|
||||||
|
@ -215,6 +217,8 @@ 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)
|
||||||
|
@ -222,8 +226,6 @@ class Dispatcher:
|
||||||
await self._incoming.put(packet)
|
await self._incoming.put(packet)
|
||||||
if self.state != ConnectionState.PLAY:
|
if self.state != ConnectionState.PLAY:
|
||||||
await self._incoming.join() # During play we can pre-process packets
|
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):
|
except (asyncio.TimeoutError, TimeoutError):
|
||||||
self._logger.error("Connection timed out")
|
self._logger.error("Connection timed out")
|
||||||
await self.disconnect(block=False)
|
await self.disconnect(block=False)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import io
|
import io
|
||||||
import struct
|
import struct
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import uuid
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any, Optional, Type as VarType
|
||||||
|
|
||||||
class Type(object):
|
class Type(object):
|
||||||
_pytype : type
|
_pytype : type
|
||||||
|
@ -138,6 +139,29 @@ class VarLong(VarInt):
|
||||||
_pytype : type = int
|
_pytype : type = int
|
||||||
_size = 10
|
_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):
|
class String(Type):
|
||||||
_pytype : type = str
|
_pytype : type = str
|
||||||
|
|
||||||
|
@ -189,36 +213,46 @@ class Angle(Type):
|
||||||
_size : int = 1
|
_size : int = 1
|
||||||
_fmt : str = ">b"
|
_fmt : str = ">b"
|
||||||
|
|
||||||
class EntityMetadata(Type):
|
|
||||||
_pytype : type = bytes
|
|
||||||
# TODO
|
|
||||||
pass
|
|
||||||
|
|
||||||
class EntityMetadataItem(Type):
|
class EntityMetadataItem(Type):
|
||||||
_pytype : type = bytes
|
_pytype : type = bytes
|
||||||
# TODO
|
# TODO
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Slot(Type):
|
|
||||||
_pytype : type = bytes
|
|
||||||
# TODO
|
|
||||||
pass
|
|
||||||
|
|
||||||
class NBTTag(Type):
|
class NBTTag(Type):
|
||||||
_pytype : type = bytes
|
_pytype : type = bytes
|
||||||
# TODO
|
# TODO
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Position(Type):
|
class Position(Type):
|
||||||
_pytype : type = bytes
|
_pytype : type = tuple
|
||||||
# TODO
|
_size = 8
|
||||||
pass
|
|
||||||
|
|
||||||
|
# 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):
|
class UUID(Type):
|
||||||
_pytype : type = bytes
|
_pytype : type = str
|
||||||
# TODO
|
_size = 16
|
||||||
pass
|
|
||||||
|
@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):
|
class TrailingByteArray(Type):
|
||||||
_pytype : type = bytes
|
_pytype : type = bytes
|
||||||
|
@ -232,3 +266,12 @@ class TrailingByteArray(Type):
|
||||||
def read(cls, buffer:io.BytesIO) -> bytes:
|
def read(cls, buffer:io.BytesIO) -> bytes:
|
||||||
return buffer.read()
|
return buffer.read()
|
||||||
|
|
||||||
|
class EntityMetadata(TrailingByteArray):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Slot(TrailingByteArray):
|
||||||
|
_pytype : type = bytes
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue