Prepare for sync_resources;

Fix async bugs;
Recreate ID system;
Add Ss (Player counter) code;
This commit is contained in:
2023-07-13 17:49:23 +03:00
parent 1f595db700
commit 52893513d0
5 changed files with 260 additions and 163 deletions

View File

@@ -6,6 +6,8 @@
# (c) kuitoi.su 2023
import asyncio
import traceback
from asyncio import AbstractEventLoop
from threading import Thread
import aiohttp
@@ -15,10 +17,11 @@ from core import utils
class TCPServer:
def __init__(self, core, host, port):
self.log = utils.get_logger("TCPServer")
self.loop = asyncio.get_event_loop()
self.Core = core
self.host = host
self.port = port
self.loop = asyncio.get_event_loop()
self.run = False
async def auth_client(self, reader, writer):
client = self.Core.create_client(reader, writer)
@@ -37,49 +40,58 @@ class TCPServer:
await client.kick("Invalid Key (too long)!")
return False, None
client.key = data.decode("utf-8")
async with aiohttp.ClientSession() as session:
url = 'https://auth.beammp.com/pkToUser'
async with session.post(url, data={'key': client.key}) as response:
res = await response.json()
self.log.debug(f"res: {res}")
try:
async with aiohttp.ClientSession() as session:
url = 'https://auth.beammp.com/pkToUser'
async with session.post(url, data={'key': client.key}) as response:
res = await response.json()
self.log.debug(f"res: {res}")
if res.get("error"):
await client.kick('Invalid key! Please restart your game.')
return
return False, None
client.nick = res["username"]
client.roles = res["roles"]
client.guest = res["guest"]
client._update_logger()
except Exception as e:
self.log.error(f"Auth error: {e}")
await client.kick('Invalid authentication data! Try to connect in 5 minutes.')
await client.kick('Invalid authentication data! Try to reconnect in 5 minutes.')
return False, None
for _client in self.Core.clients:
if not _client:
continue
if _client.nick == client.nick and _client.guest == client.guest:
await client.kick('Stale Client (replaced by new client)')
return False, None
ev.call_event("on_auth", client)
if len(self.Core.clients) > config.Game["players"]:
if len(self.Core.clients_by_id) > config.Game["players"]:
await client.kick("Server full!")
return False, None
else:
self.log.info("Identification success")
self.Core.insert_client(client)
await self.Core.insert_client(client)
return True, client
async def set_down_rw(self, reader, writer):
try:
cid = (await reader.read(1)).decode() # FIXME: wtf? 1 byte?
self.log.debug(f"Client: \"ID: {cid}\" - HandleDownload!")
if not cid.isdigit():
return False
cid = (await reader.read(1))[0]
ok = False
for _client in self.Core.clients:
if not _client:
continue
if _client.cid == cid:
_client.down_rw = (reader, writer)
return True
ok = True
self.log.debug(f"Client: {_client.nick}:{cid} - HandleDownload!")
if not ok:
writer.close()
self.log.debug(f"Unknown client - HandleDownload")
finally:
return False
return
async def handle_code(self, code, reader, writer):
match code:
@@ -87,17 +99,17 @@ class TCPServer:
result, client = await self.auth_client(reader, writer)
if result:
await client.looper()
return True
return False
return result, client
case "D":
return await self.set_down_rw(reader, writer)
await self.set_down_rw(reader, writer)
case "P":
writer.write(b"P")
await writer.drain()
return True
writer.close()
case _:
self.log.error(f"Unknown code: {code}")
return False
writer.close()
return False, None
async def handle_client(self, reader, writer):
while True:
@@ -107,28 +119,37 @@ class TCPServer:
break
code = data.decode()
self.log.debug(f"Received {code!r} from {writer.get_extra_info('sockname')!r}")
result = await self.handle_code(code, reader, writer)
if not result:
break
# task = asyncio.create_task(self.handle_code(code, reader, writer))
# await asyncio.wait([task], return_when=asyncio.FIRST_EXCEPTION)
_, cl = await self.handle_code(code, reader, writer)
if cl:
await cl.remove_me()
break
except Exception as e:
self.log.error("Error while connecting..")
self.log.error(f"Error: {e}")
self.log.exception(e)
traceback.print_exc()
break
async def start(self):
self.log.debug("Starting TCP server.")
self.run = True
try:
server = await asyncio.start_server(self.handle_client, self.host, self.port,
backlog=int(config.Game["players"] * 1.3))
self.log.debug(f"TCP server started on {server.sockets[0].getsockname()!r}")
while True:
async with server:
await server.serve_forever()
except OSError as e:
self.log.error(f"Error: {e}")
self.Core.run = False
self.log.error("Cannot bind port")
raise e
self.log.debug(f"TCP server started on {server.sockets[0].getsockname()!r}")
while True:
async with server:
await server.serve_forever()
except BaseException as e:
self.log.error(f"Error: {e}")
raise e
finally:
self.run = False
self.Core.run = False
def stop(self):
self.log.debug("Stopping TCP server")