added barebones packet dispatcher

This commit is contained in:
əlemi 2021-10-11 02:11:43 +02:00 committed by alemidev
parent 495fec6b39
commit 2af0466ee1
2 changed files with 41 additions and 18 deletions

View file

@ -1,20 +1,19 @@
import asyncio import asyncio
from asyncio import StreamReader, StreamWriter from asyncio import StreamReader, StreamWriter, Queue, Task
from enum import Enum from enum import Enum
class ConnectionState(Enum):
HANDSHAKING = 0
STATUS = 1
LOGIN = 2
PLAY = 3
class InvalidState(Exception): class InvalidState(Exception):
pass pass
class Dispatcher: class Dispatcher:
_down : StreamReader
_up : StreamWriter
_reader : Task
_writer : Task
_dispatching : bool
incoming : Queue
outgoing : Queue
connected : bool connected : bool
down : StreamReader
up : StreamWriter
host : str host : str
port : int port : int
@ -22,21 +21,41 @@ class Dispatcher:
self.host = host self.host = host
self.port = port self.port = port
self.connected = False self.connected = False
self._dispatching = False
async def _connect(self): async def connect(self):
self.down, self.up = await asyncio.open_connection( self._down, self._up = await asyncio.open_connection(
host=self.host, host=self.host,
port=self.port, port=self.port,
) )
self.connected = True self.connected = True
async def _work(self): async def _down_worker(self):
while True: while self._dispatching:
buf = await self.down. 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): async def run(self):
if self.connected: if self.connected:
raise InvalidState("Dispatcher already 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)

View file

@ -65,10 +65,14 @@ class VarInt(Type):
@classmethod @classmethod
async def read(cls, stream: asyncio.StreamReader) -> int: 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 off = 0
while (buf & 0b0000000) != 0: while True:
buf |= (await stream.read(1)) >> (7*off) byte = await stream.read(1)
buf |= (byte & 0b01111111) >> (7*off)
if not byte & 0b10000000:
break
off += 1 off += 1
return buf return buf