mirror of
https://github.com/kuitoi/kuitoi-Server.git
synced 2025-08-17 08:15:42 +00:00
Add TODOs to code.
This commit is contained in:
parent
4f688d7c02
commit
5a40ab8b05
@ -32,11 +32,11 @@ class Client:
|
|||||||
return True
|
return True
|
||||||
res = self.writer.is_closing()
|
res = self.writer.is_closing()
|
||||||
if res:
|
if res:
|
||||||
self.log.debug(f"Client Disconnected")
|
self.log.debug(f"Disconnected.")
|
||||||
self.alive = False
|
self.alive = False
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self.log.debug(f"Client Alive")
|
self.log.debug(f"Alive.")
|
||||||
self.alive = True
|
self.alive = True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -44,10 +44,10 @@ class Client:
|
|||||||
if not self.alive:
|
if not self.alive:
|
||||||
self.log.debug(f"Kick({reason}) skipped;")
|
self.log.debug(f"Kick({reason}) skipped;")
|
||||||
return
|
return
|
||||||
|
# TODO: i18n
|
||||||
self.log.info(f"Kicked with reason: \"{reason}\"")
|
self.log.info(f"Kicked with reason: \"{reason}\"")
|
||||||
await self.tcp_send(b"K" + bytes(reason, "utf-8"))
|
await self.tcp_send(b"K" + bytes(reason, "utf-8"))
|
||||||
self.alive = False
|
self.alive = False
|
||||||
# await self.remove_me()
|
|
||||||
|
|
||||||
async def tcp_send(self, data, to_all=False, writer=None):
|
async def tcp_send(self, data, to_all=False, writer=None):
|
||||||
|
|
||||||
@ -67,7 +67,6 @@ class Client:
|
|||||||
await client.tcp_send(data)
|
await client.tcp_send(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
# self.log.debug(f"tcp_send({data})")
|
|
||||||
if len(data) == 10:
|
if len(data) == 10:
|
||||||
data += b"."
|
data += b"."
|
||||||
header = len(data).to_bytes(4, "little", signed=True)
|
header = len(data).to_bytes(4, "little", signed=True)
|
||||||
@ -81,7 +80,7 @@ class Client:
|
|||||||
|
|
||||||
async def recv(self):
|
async def recv(self):
|
||||||
try:
|
try:
|
||||||
header = await self.reader.read(4) # header: 4 bytes
|
header = await self.reader.read(4)
|
||||||
|
|
||||||
int_header = 0
|
int_header = 0
|
||||||
for i in range(len(header)):
|
for i in range(len(header)):
|
||||||
@ -121,7 +120,8 @@ class Client:
|
|||||||
real_size = end - start
|
real_size = end - start
|
||||||
writer = self.down_rw[1] if d_sock else self.writer
|
writer = self.down_rw[1] if d_sock else self.writer
|
||||||
who = 'dwn' if d_sock else 'srv'
|
who = 'dwn' if d_sock else 'srv'
|
||||||
self.log.debug(f"[{who}] Real size: {real_size / MB}mb; {real_size == end}, {real_size * 2 == end}")
|
if config.Server["debug"]:
|
||||||
|
self.log.debug(f"[{who}] Real size: {real_size / MB}mb; {real_size == end}, {real_size * 2 == end}")
|
||||||
|
|
||||||
with open(filename, 'rb') as f:
|
with open(filename, 'rb') as f:
|
||||||
f.seek(start)
|
f.seek(start)
|
||||||
@ -133,46 +133,16 @@ class Client:
|
|||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
self.alive = False
|
self.alive = False
|
||||||
self.log.debug(f"[{who}] Disconnected.")
|
self.log.debug(f"[{who}] Disconnected.")
|
||||||
# break
|
|
||||||
return real_size
|
return real_size
|
||||||
|
|
||||||
# chunk_size = 125 * MB
|
|
||||||
# if chunk_size > real_size:
|
|
||||||
# chunk_size = real_size
|
|
||||||
# chunks = math.floor(real_size / chunk_size)
|
|
||||||
# self.log.debug(f"[{who}] s:{start}, e:{end}, c:{chunks}, cz:{chunk_size/MB}mb, rs:{real_size/MB}mb")
|
|
||||||
# dw = 0
|
|
||||||
# for chunk in range(1, chunks + 1):
|
|
||||||
# chunk_end = start + (chunk_size * chunk)
|
|
||||||
# chunk_start = chunk_end - chunk_size
|
|
||||||
# # if chunk_start != 0:
|
|
||||||
# # chunk_start -= 1
|
|
||||||
# real_size -= chunk_size
|
|
||||||
# if chunk_size > real_size:
|
|
||||||
# chunk_end = real_size
|
|
||||||
# self.log.debug(f"[{who}] Chunk: {chunk}; Start: {chunk_start}; End: {chunk_end/MB};")
|
|
||||||
# with open(filename, 'rb') as f:
|
|
||||||
# f.seek(chunk_start)
|
|
||||||
# data = f.read(chunk_end)
|
|
||||||
# try:
|
|
||||||
# writer.write(data)
|
|
||||||
# await writer.drain()
|
|
||||||
# except ConnectionError:
|
|
||||||
# self.alive = False
|
|
||||||
# self.log.debug(f"[{who}] Disconnected")
|
|
||||||
# break
|
|
||||||
# dw += len(data)
|
|
||||||
# del data
|
|
||||||
# self.log.debug(f"[{who}] File sent.")
|
|
||||||
# return dw
|
|
||||||
|
|
||||||
async def sync_resources(self):
|
async def sync_resources(self):
|
||||||
while self.alive:
|
while self.alive:
|
||||||
data = await self.recv()
|
data = await self.recv()
|
||||||
self.log.debug(f"data: {data!r}")
|
self.log.debug(f"data: {data!r}")
|
||||||
if data.startswith(b"f"):
|
if data.startswith(b"f"):
|
||||||
file = data[1:].decode("utf-8")
|
file = data[1:].decode("utf-8")
|
||||||
self.log.debug(f"Sending File: {file}")
|
# TODO: i18n
|
||||||
|
self.log.info(f"Requested mode: {file!r}")
|
||||||
size = -1
|
size = -1
|
||||||
for mod in self.Core.mods_list:
|
for mod in self.Core.mods_list:
|
||||||
if type(mod) == int:
|
if type(mod) == int:
|
||||||
@ -181,6 +151,7 @@ class Client:
|
|||||||
size = mod['size']
|
size = mod['size']
|
||||||
self.log.debug("File is accept.")
|
self.log.debug("File is accept.")
|
||||||
break
|
break
|
||||||
|
self.log.debug(f"Mode size: {size}")
|
||||||
if size == -1:
|
if size == -1:
|
||||||
await self.tcp_send(b"CO")
|
await self.tcp_send(b"CO")
|
||||||
await self.kick(f"Not allowed mod: " + file)
|
await self.kick(f"Not allowed mod: " + file)
|
||||||
@ -193,28 +164,20 @@ class Client:
|
|||||||
if t > 50:
|
if t > 50:
|
||||||
await self.kick("Missing download socket")
|
await self.kick("Missing download socket")
|
||||||
return
|
return
|
||||||
self.log.info(f"Requested mode: {file!r}")
|
|
||||||
self.log.debug(f"Mode size: {size / MB}")
|
|
||||||
|
|
||||||
msize = math.floor(size / 2)
|
half_size = math.floor(size / 2)
|
||||||
# uploads = [
|
|
||||||
# asyncio.create_task(self._split_load(0, msize, False, file)), # SplitLoad_0
|
|
||||||
# asyncio.create_task(self._split_load(msize, size, True, file)) # SplitLoad_1
|
|
||||||
# ]
|
|
||||||
# await asyncio.wait(uploads)
|
|
||||||
uploads = [
|
uploads = [
|
||||||
self._split_load(0, msize, False, file),
|
self._split_load(0, half_size, False, file),
|
||||||
self._split_load(msize, size, True, file)
|
self._split_load(half_size, size, True, file)
|
||||||
]
|
]
|
||||||
sl0, sl1 = await asyncio.gather(*uploads)
|
sl0, sl1 = await asyncio.gather(*uploads)
|
||||||
sent = sl0 + sl1
|
sent = sl0 + sl1
|
||||||
ok = sent == size
|
ok = sent == size
|
||||||
lost = size - sent
|
lost = size - sent
|
||||||
self.log.debug(f"SplitLoad_0: {sl0}; SplitLoad_1: {sl1}; At all ({ok}): Sent: {sent}; Lost: {lost}")
|
self.log.debug(f"SplitLoad_0: {sl0}; SplitLoad_1: {sl1}; At all ({ok}): Sent: {sent}; Lost: {lost}")
|
||||||
self.log.debug(f"SplitLoad_0: {sl0 / MB}mb; "
|
|
||||||
f"SplitLoad_1: {sl1 / MB}MB; At all ({ok}): Sent: {sent / MB}mb; Lost: {lost / MB}mb")
|
|
||||||
if not ok:
|
if not ok:
|
||||||
self.alive = False
|
self.alive = False
|
||||||
|
# TODO: i18n
|
||||||
self.log.error(f"Error while sending.")
|
self.log.error(f"Error while sending.")
|
||||||
return
|
return
|
||||||
elif data.startswith(b"SR"):
|
elif data.startswith(b"SR"):
|
||||||
@ -245,7 +208,7 @@ class Client:
|
|||||||
if not self.alive:
|
if not self.alive:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
await asyncio.sleep(.2)
|
await asyncio.sleep(.1)
|
||||||
self.is_disconnected()
|
self.is_disconnected()
|
||||||
continue
|
continue
|
||||||
code = data.decode()[0]
|
code = data.decode()[0]
|
||||||
@ -257,6 +220,7 @@ class Client:
|
|||||||
await self.tcp_send(b"Sn" + bytes(self.nick, "utf-8"), to_all=True)
|
await self.tcp_send(b"Sn" + bytes(self.nick, "utf-8"), to_all=True)
|
||||||
case "C":
|
case "C":
|
||||||
# Chat
|
# Chat
|
||||||
|
ev.call_event("chat_receive", f"{data}")
|
||||||
await self.tcp_send(data, to_all=True)
|
await self.tcp_send(data, to_all=True)
|
||||||
|
|
||||||
async def remove_me(self):
|
async def remove_me(self):
|
||||||
@ -267,6 +231,7 @@ class Client:
|
|||||||
# if self.ready:
|
# if self.ready:
|
||||||
# await self.tcp_send(b"", to_all=True) # I'm disconnected.
|
# await self.tcp_send(b"", to_all=True) # I'm disconnected.
|
||||||
self.log.debug(f"Removing client {self.nick}:{self.cid}")
|
self.log.debug(f"Removing client {self.nick}:{self.cid}")
|
||||||
|
# TODO: i18n
|
||||||
self.log.info("Disconnected")
|
self.log.info("Disconnected")
|
||||||
self.Core.clients[self.cid] = None
|
self.Core.clients[self.cid] = None
|
||||||
self.Core.clients_by_id.pop(self.cid)
|
self.Core.clients_by_id.pop(self.cid)
|
||||||
|
@ -121,6 +121,7 @@ class Core:
|
|||||||
async def heartbeat(self, test=False):
|
async def heartbeat(self, test=False):
|
||||||
if config.Auth["private"] or self.direct:
|
if config.Auth["private"] or self.direct:
|
||||||
if test:
|
if test:
|
||||||
|
# TODO: i18n
|
||||||
self.log.info(f"Server runnig in Direct connect mode.")
|
self.log.info(f"Server runnig in Direct connect mode.")
|
||||||
self.direct = True
|
self.direct = True
|
||||||
return
|
return
|
||||||
@ -171,6 +172,7 @@ class Core:
|
|||||||
status = body.get("status")
|
status = body.get("status")
|
||||||
msg = body.get("msg")
|
msg = body.get("msg")
|
||||||
if status == "2000":
|
if status == "2000":
|
||||||
|
# TODO: i18n
|
||||||
self.log.info(f"Authenticated! {msg}")
|
self.log.info(f"Authenticated! {msg}")
|
||||||
elif status == "200":
|
elif status == "200":
|
||||||
self.log.info(f"Resumed authenticated session. {msg}")
|
self.log.info(f"Resumed authenticated session. {msg}")
|
||||||
@ -186,6 +188,7 @@ class Core:
|
|||||||
if not config.Auth['private']:
|
if not config.Auth['private']:
|
||||||
raise KeyboardInterrupt
|
raise KeyboardInterrupt
|
||||||
if test:
|
if test:
|
||||||
|
# TODO: i18n
|
||||||
self.log.info(f"Server still runnig, but only in Direct connect mode.")
|
self.log.info(f"Server still runnig, but only in Direct connect mode.")
|
||||||
|
|
||||||
if test:
|
if test:
|
||||||
@ -226,24 +229,24 @@ class Core:
|
|||||||
self.mods_list.append({"path": path, "size": size})
|
self.mods_list.append({"path": path, "size": size})
|
||||||
self.mods_list[0] += size
|
self.mods_list[0] += size
|
||||||
self.log.debug(f"mods_list: {self.mods_list}")
|
self.log.debug(f"mods_list: {self.mods_list}")
|
||||||
lmods = len(self.mods_list) - 1
|
len_mods = len(self.mods_list) - 1
|
||||||
if lmods > 0:
|
if len_mods > 0:
|
||||||
self.log.info(f"Loaded {lmods} mods: {round(self.mods_list[0] / MB, 2)}mb")
|
# TODO: i18n
|
||||||
|
self.log.info(f"Loaded {len_mods} mods: {round(self.mods_list[0] / MB, 2)}mb")
|
||||||
|
|
||||||
await self.heartbeat(True)
|
await self.heartbeat(True)
|
||||||
for i in range(int(config.Game["players"] * 1.3)):
|
for i in range(int(config.Game["players"] * 2.3)): # * 2.3 For down sock and buffer.
|
||||||
self.clients.append(None)
|
self.clients.append(None)
|
||||||
tasks = []
|
tasks = []
|
||||||
# self.udp.start,
|
# self.udp.start,
|
||||||
nrtasks = [self.tcp.start, console.start, self.stop_me, self.heartbeat, self.check_alive]
|
f_tasks = [self.tcp.start, console.start, self.stop_me, self.heartbeat, self.check_alive]
|
||||||
for task in nrtasks:
|
for task in f_tasks:
|
||||||
tasks.append(asyncio.create_task(task()))
|
tasks.append(asyncio.create_task(task()))
|
||||||
t = asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)
|
t = asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)
|
||||||
|
|
||||||
self.log.info(i18n.start)
|
self.log.info(i18n.start)
|
||||||
ev.call_event("on_started")
|
ev.call_event("on_started")
|
||||||
await t
|
await t # Wait end.
|
||||||
# Wait the end.
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error(f"Exception: {e}")
|
self.log.error(f"Exception: {e}")
|
||||||
self.log.exception(e)
|
self.log.exception(e)
|
||||||
|
@ -23,10 +23,12 @@ class TCPServer:
|
|||||||
|
|
||||||
async def auth_client(self, reader, writer):
|
async def auth_client(self, reader, writer):
|
||||||
client = self.Core.create_client(reader, writer)
|
client = self.Core.create_client(reader, writer)
|
||||||
|
# TODO: i18n
|
||||||
self.log.info(f"Identifying new ClientConnection...")
|
self.log.info(f"Identifying new ClientConnection...")
|
||||||
data = await client.recv()
|
data = await client.recv()
|
||||||
self.log.debug(f"Version: {data}")
|
self.log.debug(f"Version: {data}")
|
||||||
if data.decode("utf-8") != f"VC{self.Core.client_major_version}":
|
if data.decode("utf-8") != f"VC{self.Core.client_major_version}":
|
||||||
|
# TODO: i18n
|
||||||
await client.kick("Outdated Version.")
|
await client.kick("Outdated Version.")
|
||||||
return False, client
|
return False, client
|
||||||
else:
|
else:
|
||||||
@ -35,6 +37,7 @@ class TCPServer:
|
|||||||
data = await client.recv()
|
data = await client.recv()
|
||||||
self.log.debug(f"Key: {data}")
|
self.log.debug(f"Key: {data}")
|
||||||
if len(data) > 50:
|
if len(data) > 50:
|
||||||
|
# TODO: i18n
|
||||||
await client.kick("Invalid Key (too long)!")
|
await client.kick("Invalid Key (too long)!")
|
||||||
return False, client
|
return False, client
|
||||||
client.key = data.decode("utf-8")
|
client.key = data.decode("utf-8")
|
||||||
@ -46,6 +49,7 @@ class TCPServer:
|
|||||||
res = await response.json()
|
res = await response.json()
|
||||||
self.log.debug(f"res: {res}")
|
self.log.debug(f"res: {res}")
|
||||||
if res.get("error"):
|
if res.get("error"):
|
||||||
|
# TODO: i18n
|
||||||
await client.kick('Invalid key! Please restart your game.')
|
await client.kick('Invalid key! Please restart your game.')
|
||||||
return False, client
|
return False, client
|
||||||
client.nick = res["username"]
|
client.nick = res["username"]
|
||||||
@ -54,6 +58,7 @@ class TCPServer:
|
|||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
client._update_logger()
|
client._update_logger()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
# TODO: i18n
|
||||||
self.log.error(f"Auth error: {e}")
|
self.log.error(f"Auth error: {e}")
|
||||||
await client.kick('Invalid authentication data! Try to reconnect in 5 minutes.')
|
await client.kick('Invalid authentication data! Try to reconnect in 5 minutes.')
|
||||||
return False, client
|
return False, client
|
||||||
@ -62,15 +67,18 @@ class TCPServer:
|
|||||||
if not _client:
|
if not _client:
|
||||||
continue
|
continue
|
||||||
if _client.nick == client.nick and _client.guest == client.guest:
|
if _client.nick == client.nick and _client.guest == client.guest:
|
||||||
|
# TODO: i18n
|
||||||
await client.kick('Stale Client (replaced by new client)')
|
await client.kick('Stale Client (replaced by new client)')
|
||||||
return False, client
|
return False, client
|
||||||
|
|
||||||
ev.call_event("auth_ok", client)
|
ev.call_event("auth_ok", client)
|
||||||
|
|
||||||
if len(self.Core.clients_by_id) > config.Game["players"]:
|
if len(self.Core.clients_by_id) > config.Game["players"]:
|
||||||
|
# TODO: i18n
|
||||||
await client.kick("Server full!")
|
await client.kick("Server full!")
|
||||||
return False, client
|
return False, client
|
||||||
else:
|
else:
|
||||||
|
# TODO: i18n
|
||||||
self.log.info("Identification success")
|
self.log.info("Identification success")
|
||||||
await self.Core.insert_client(client)
|
await self.Core.insert_client(client)
|
||||||
|
|
||||||
@ -103,6 +111,7 @@ class TCPServer:
|
|||||||
await writer.drain()
|
await writer.drain()
|
||||||
writer.close()
|
writer.close()
|
||||||
case _:
|
case _:
|
||||||
|
# TODO: i18n
|
||||||
self.log.error(f"Unknown code: {code}")
|
self.log.error(f"Unknown code: {code}")
|
||||||
writer.close()
|
writer.close()
|
||||||
return False, None
|
return False, None
|
||||||
@ -123,6 +132,7 @@ class TCPServer:
|
|||||||
del cl
|
del cl
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
# TODO: i18n
|
||||||
self.log.error("Error while connecting..")
|
self.log.error("Error while connecting..")
|
||||||
self.log.exception(e)
|
self.log.exception(e)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@ -139,6 +149,7 @@ class TCPServer:
|
|||||||
async with server:
|
async with server:
|
||||||
await server.serve_forever()
|
await server.serve_forever()
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
# TODO: i18n
|
||||||
self.log.error("Cannot bind port")
|
self.log.error("Cannot bind port")
|
||||||
raise e
|
raise e
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
|
@ -3,9 +3,11 @@ import builtins
|
|||||||
from core import get_logger
|
from core import get_logger
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyShadowingBuiltins
|
||||||
class EventsSystem:
|
class EventsSystem:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
# TODO: default events
|
||||||
self.__events = {
|
self.__events = {
|
||||||
"on_started": [self.on_started],
|
"on_started": [self.on_started],
|
||||||
"on_stop": [self.on_stop],
|
"on_stop": [self.on_stop],
|
||||||
@ -20,6 +22,7 @@ class EventsSystem:
|
|||||||
def register_event(self, event_name, event_func):
|
def register_event(self, event_name, event_func):
|
||||||
self.log.debug(f"register_event({event_name}, {event_func}):")
|
self.log.debug(f"register_event({event_name}, {event_func}):")
|
||||||
if not callable(event_func):
|
if not callable(event_func):
|
||||||
|
# TODO: i18n
|
||||||
self.log.error(f"Cannot add event '{event_name}'. "
|
self.log.error(f"Cannot add event '{event_name}'. "
|
||||||
f"Use `KuiToi.add_event({event_name}', function)` instead. Skipping it...")
|
f"Use `KuiToi.add_event({event_name}', function)` instead. Skipping it...")
|
||||||
return
|
return
|
||||||
@ -34,13 +37,5 @@ class EventsSystem:
|
|||||||
for event in self.__events[event_name]:
|
for event in self.__events[event_name]:
|
||||||
event(*data)
|
event(*data)
|
||||||
else:
|
else:
|
||||||
|
# TODO: i18n
|
||||||
self.log.warning(f"Event {event_name} does not exist. Just skipping it...")
|
self.log.warning(f"Event {event_name} does not exist. Just skipping it...")
|
||||||
|
|
||||||
def on_started(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def on_stop(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def on_auth(self, client):
|
|
||||||
pass
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user