diff --git a/aiocraft/__main__.py b/aiocraft/__main__.py new file mode 100644 index 0000000..328b2e4 --- /dev/null +++ b/aiocraft/__main__.py @@ -0,0 +1 @@ +print(":)") diff --git a/aiocraft/impl/dispatcher.py b/aiocraft/impl/dispatcher.py new file mode 100644 index 0000000..c5d24ca --- /dev/null +++ b/aiocraft/impl/dispatcher.py @@ -0,0 +1,2 @@ +class Dispatcher: + diff --git a/aiocraft/minecraft/compiler.py b/aiocraft/minecraft/compiler.py index 247ad2e..8bce37d 100755 --- a/aiocraft/minecraft/compiler.py +++ b/aiocraft/minecraft/compiler.py @@ -6,14 +6,17 @@ from typing import List, Dict DIR_MAP = {"toClient": "clientbound", "toServer": "serverbound"} PREFACE = """\"\"\"[!] This file is autogenerated\"\"\"\n\n""" -IMPORTS = """from .minecraft.packet import Packet\nfrom .minecraft.types import *\n""" +IMPORTS = """from typing import Tuple +from .minecraft.packet import Packet +from .minecraft.types import *\n""" IMPORT_ALL = """from .* import * # TODO!\n""" OBJECT = """ class {name}(Packet): - ID : int = 0x{id:X} - SLOTS : list = ( + id : int = 0x{id:X} + _slots : Tuple[Tuple[str, Type]] = ( {slots} ) + {fields} """ def snake_to_camel(name:str) -> str: @@ -30,6 +33,20 @@ def parse_slot(slot: dict) -> str: return f"(\"anon\", {slot['type']})" else: return f"(\"anon\", [Special])" + return slot + +def parse_field(slot: dict) -> str: + if "name" in slot: + if "type" in slot and isinstance(slot["type"], str): + return f"{slot['name']} : {slot['type'].pytype()}" + else: + return f"{slot['name']} : Any" + elif "anon" in slot: + if "type" in slot and isinstance(slot["type"], str): + return f"anon : {slot['type'].pytype()}" + else: + return f"anon : Any" + class PacketClassWriter: @@ -43,7 +60,14 @@ class PacketClassWriter: self.slots = slots def compile(self) -> str: - return PREFACE + IMPORTS + OBJECT.format(id=pid, name=self.title, slots=parse_slot(self.slots)) + return PREFACE + \ + IMPORTS + \ + OBJECT.format( + id=pid, + name=self.title, + slots=parse_slot(self.slots), + fields=parse_field(self.slots), + ) def _make_module(path:str): os.mkdir(path) @@ -54,8 +78,8 @@ def _make_module(path:str): if __name__ == "__main__": # TODO load relatively! - # with open("???/minecraft-data/data/pc/1.12.2/protocol.json") as f: - # data = json.load(f) + with open("/home/alemi/projects/minecraft-data/data/pc/1.12.2/protocol.json") as f: + data = json.load(f) _make_module("protocol") for state in ("handshaking", "status", "login", "play"): diff --git a/aiocraft/minecraft/types.py b/aiocraft/minecraft/mctypes.py similarity index 98% rename from aiocraft/minecraft/types.py rename to aiocraft/minecraft/mctypes.py index bd566af..74d4b93 100644 --- a/aiocraft/minecraft/types.py +++ b/aiocraft/minecraft/mctypes.py @@ -103,8 +103,6 @@ class EntityMetadata(Type): class Slot(Type): # TODO pass - if buf & 0b10000000 == 0: - break class NBTTag(Type): # TODO diff --git a/aiocraft/minecraft/packet.py b/aiocraft/minecraft/packet.py new file mode 100644 index 0000000..3b7dac9 --- /dev/null +++ b/aiocraft/minecraft/packet.py @@ -0,0 +1,21 @@ +from typing import Tuple + +from .mctypes import Type + +class Packet: + id : int + _slots : Tuple[Tuple[str, Type]] + + def serialize(self) -> bytes: + return b''.join( + slot[1].serialize(getattr(self, slot[0])) + for slot in self._slots + ) + + @classmethod + def deserialize(cls, data:bytes): + pkt = cls() + for slot in cls._slots: + setattr(pkt, slot[0], slot[1].deserialize(data)) + return pkt + diff --git a/aiocraft/session.py b/aiocraft/session.py new file mode 100644 index 0000000..c182ae6 --- /dev/null +++ b/aiocraft/session.py @@ -0,0 +1,17 @@ + + +class Session: + host:str + port:int + + def __init__( + self, + host: str = "localhost", + port: int = 25565, + ): + self.host = host + self.port = port + + + async def run(self): +