added initial types
This commit is contained in:
parent
3c628f8b0f
commit
894af39814
1 changed files with 123 additions and 0 deletions
123
aiocraft/minecraft/protocol/types.py
Normal file
123
aiocraft/minecraft/protocol/types.py
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
class Type(object):
|
||||||
|
_fmt : str
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def serialize(cls, data:Any) -> bytes:
|
||||||
|
return struct.pack(cls._fmt, data)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def unserialize(cls, data:bytes) -> Any:
|
||||||
|
return struct.unpack(cls._fmt, data)[0]
|
||||||
|
|
||||||
|
class Boolean(Type):
|
||||||
|
_fmt : str = ">?"
|
||||||
|
|
||||||
|
class Byte(Type):
|
||||||
|
_fmt : str = ">b"
|
||||||
|
|
||||||
|
class UnsignedByte(Type):
|
||||||
|
_fmt : str = ">B"
|
||||||
|
|
||||||
|
class Short(Type):
|
||||||
|
_fmt : str = ">h"
|
||||||
|
|
||||||
|
class UnsignedShort(Type):
|
||||||
|
_fmt : str = ">H"
|
||||||
|
|
||||||
|
class Int(Type):
|
||||||
|
_fmt : str = ">i"
|
||||||
|
|
||||||
|
class Long(Type):
|
||||||
|
_fmt : str = ">q"
|
||||||
|
|
||||||
|
class Float(Type):
|
||||||
|
_fmt : str = ">f"
|
||||||
|
|
||||||
|
class Double(Type):
|
||||||
|
_fmt : str = ">d"
|
||||||
|
|
||||||
|
class VarInt(Type):
|
||||||
|
_maxBytes = 5
|
||||||
|
@classmethod
|
||||||
|
def serialize(cls, data:int) -> bytes:
|
||||||
|
res : bytearray = bytearray()
|
||||||
|
count = 0
|
||||||
|
while True:
|
||||||
|
if count >= cls._maxBytes:
|
||||||
|
break
|
||||||
|
buf = data >> (7*count)
|
||||||
|
val = (buf & 0b01111111)
|
||||||
|
if (buf & 0b0000000) != 0:
|
||||||
|
val |= 0b1000000
|
||||||
|
res.extend(val.to_bytes(1, 'little'))
|
||||||
|
if (buf & 0b0000000) == 0:
|
||||||
|
break
|
||||||
|
count += 1
|
||||||
|
return res
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def unserialize(cls, data:bytes) -> int:
|
||||||
|
numRead = 0
|
||||||
|
result = 0
|
||||||
|
pos = 0
|
||||||
|
while True:
|
||||||
|
buf = data[0]
|
||||||
|
value = buf & 0b01111111
|
||||||
|
result |= value << (7 * numRead)
|
||||||
|
numRead +=1
|
||||||
|
if numRead > cls._maxBytes:
|
||||||
|
raise ValueError("VarInt is too big")
|
||||||
|
if buf & 0b10000000 == 0:
|
||||||
|
break
|
||||||
|
return result
|
||||||
|
|
||||||
|
class VarLong(VarInt):
|
||||||
|
_maxBytes = 10
|
||||||
|
|
||||||
|
class String(Type):
|
||||||
|
@classmethod
|
||||||
|
def serialize(cls, data:str) -> bytes:
|
||||||
|
encoded = data.encode('utf-8')
|
||||||
|
return VarInt.serialize(len(encoded)) + struct.pack(f">{len(encoded)}s", encoded)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def unserialize(cls, data:bytes) -> str:
|
||||||
|
length = VarInt.unserialize(data)
|
||||||
|
start_index = len(data) - length
|
||||||
|
return struct.unpack(f">{length}s", data[start_index:])[0]
|
||||||
|
|
||||||
|
class Chat(String):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Identifier(String):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class EntityMetadata(Type):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Slot(Type):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
if buf & 0b10000000 == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
class NBTTag(Type):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Position(Type):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Angle(Type):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
class UUID(Type):
|
||||||
|
# TODO
|
||||||
|
pass
|
Loading…
Reference in a new issue