From 2af0466ee1c6e1f88da55df2ae5859b1e1fe4587 Mon Sep 17 00:00:00 2001 From: alemi Date: Mon, 11 Oct 2021 02:11:43 +0200 Subject: [PATCH] added barebones packet dispatcher --- aiocraft/dispatcher.py | 49 +++++++++++++++++++++++++++++------------- aiocraft/mc/mctypes.py | 10 ++++++--- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/aiocraft/dispatcher.py b/aiocraft/dispatcher.py index 0dbc727..368ea6c 100644 --- a/aiocraft/dispatcher.py +++ b/aiocraft/dispatcher.py @@ -1,20 +1,19 @@ import asyncio -from asyncio import StreamReader, StreamWriter +from asyncio import StreamReader, StreamWriter, Queue, Task from enum import Enum -class ConnectionState(Enum): - HANDSHAKING = 0 - STATUS = 1 - LOGIN = 2 - PLAY = 3 - class InvalidState(Exception): pass class Dispatcher: + _down : StreamReader + _up : StreamWriter + _reader : Task + _writer : Task + _dispatching : bool + incoming : Queue + outgoing : Queue connected : bool - down : StreamReader - up : StreamWriter host : str port : int @@ -22,21 +21,41 @@ class Dispatcher: self.host = host self.port = port self.connected = False + self._dispatching = False - async def _connect(self): - self.down, self.up = await asyncio.open_connection( + async def connect(self): + self._down, self._up = await asyncio.open_connection( host=self.host, port=self.port, ) self.connected = True - async def _work(self): - while True: - buf = await self.down. + async def _down_worker(self): + while self._dispatching: + length = await VarInt.read(self._down) + buffer = await self._down.read(length) + # TODO encryption + # TODO compression + await self.incoming.put(packet) + + async def _up_worker(self): + while self._dispatching: + buffer = await self.outgoing.get() + length = len(buffer) + # TODO compression + # TODO encryption + await self._up.write(VarInt.serialize(length) + buffer) async def run(self): if self.connected: raise InvalidState("Dispatcher already connected") - await self._connect() + await self.connect() + self._dispatching = True + self._reader = asyncio.get_event_loop().create_task(self._down_worker()) + self._writer = asyncio.get_event_loop().create_task(self._up_worker()) + + async def stop(self): + self._dispatching = False + await asyncio.gather(self._writer, self._reader) diff --git a/aiocraft/mc/mctypes.py b/aiocraft/mc/mctypes.py index 7aff0bd..6151466 100644 --- a/aiocraft/mc/mctypes.py +++ b/aiocraft/mc/mctypes.py @@ -65,10 +65,14 @@ class VarInt(Type): @classmethod async def read(cls, stream: asyncio.StreamReader) -> int: - buf = 0b10000000 + """Utility method to read a VarInt off the socket, because len comes as a VarInt...""" + buf = 0 off = 0 - while (buf & 0b0000000) != 0: - buf |= (await stream.read(1)) >> (7*off) + while True: + byte = await stream.read(1) + buf |= (byte & 0b01111111) >> (7*off) + if not byte & 0b10000000: + break off += 1 return buf