mirror of
https://github.com/kuitoi/kuitoi-Server.git
synced 2025-08-17 16:25:36 +00:00
CONNECTING TO WORLD!!!
This commit is contained in:
parent
cd6247feb8
commit
c1c18f4f3b
@ -12,7 +12,11 @@ BeamingDrive Multiplayer (BeamMP) server compatible with BeamMP clients.
|
|||||||
- [x] Understanding beamp header
|
- [x] Understanding beamp header
|
||||||
- [X] Authorization
|
- [X] Authorization
|
||||||
- [ ] Upload mods
|
- [ ] Upload mods
|
||||||
- [ ] Connecting to the world
|
- [x] Connecting to the world
|
||||||
|
- [x] Chat
|
||||||
|
- [ ] ABG: (compressed data)
|
||||||
|
- [ ] Decompress data
|
||||||
|
- [ ] Vehicle data
|
||||||
- [ ] UDP Server part:
|
- [ ] UDP Server part:
|
||||||
- [ ] Players synchronizations
|
- [ ] Players synchronizations
|
||||||
- [x] Additional:
|
- [x] Additional:
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
# Licence: FPA
|
# Licence: FPA
|
||||||
# (c) kuitoi.su 2023
|
# (c) kuitoi.su 2023
|
||||||
import asyncio
|
import asyncio
|
||||||
import socket
|
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from .tcp_server import TCPServer
|
from .tcp_server import TCPServer
|
||||||
@ -17,7 +16,7 @@ class Client:
|
|||||||
def __init__(self, reader, writer):
|
def __init__(self, reader, writer):
|
||||||
self.reader = reader
|
self.reader = reader
|
||||||
self.writer = writer
|
self.writer = writer
|
||||||
self.log = utils.get_logger("client(id: )")
|
self.log = utils.get_logger("client(None:0)")
|
||||||
self.addr = writer.get_extra_info("sockname")
|
self.addr = writer.get_extra_info("sockname")
|
||||||
self.loop = asyncio.get_event_loop()
|
self.loop = asyncio.get_event_loop()
|
||||||
self.cid = 0
|
self.cid = 0
|
||||||
@ -28,7 +27,8 @@ class Client:
|
|||||||
self.alive = True
|
self.alive = True
|
||||||
|
|
||||||
def _update_logger(self):
|
def _update_logger(self):
|
||||||
self.log = utils.get_logger(f"client(id:{self.cid})")
|
self.log.debug(f"Update logger")
|
||||||
|
self.log = utils.get_logger(f"client({self.nick}:{self.cid})")
|
||||||
|
|
||||||
def is_disconnected(self):
|
def is_disconnected(self):
|
||||||
if not self.alive:
|
if not self.alive:
|
||||||
@ -157,7 +157,7 @@ class Core:
|
|||||||
|
|
||||||
def create_client(self, *args, **kwargs):
|
def create_client(self, *args, **kwargs):
|
||||||
cl = Client(*args, **kwargs)
|
cl = Client(*args, **kwargs)
|
||||||
self.clients_counter += 1
|
self.clients_counter = self.clients_counter + 1
|
||||||
cl.id = self.clients_counter
|
cl.id = self.clients_counter
|
||||||
cl._update_logger()
|
cl._update_logger()
|
||||||
return cl
|
return cl
|
||||||
|
@ -29,7 +29,9 @@ class Client:
|
|||||||
def is_disconnected(self) -> bool: ...
|
def is_disconnected(self) -> bool: ...
|
||||||
async def kick(self, reason: str) -> None: ...
|
async def kick(self, reason: str) -> None: ...
|
||||||
async def tcp_send(self, data: bytes) -> None: ...
|
async def tcp_send(self, data: bytes) -> None: ...
|
||||||
|
async def sync_resources(self) -> None: ...
|
||||||
async def recv(self) -> bytes: ...
|
async def recv(self) -> bytes: ...
|
||||||
|
async def last_handle(self) -> bytes: ...
|
||||||
|
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
|
@ -20,44 +20,10 @@ class TCPServer:
|
|||||||
self.port = port
|
self.port = port
|
||||||
self.loop = asyncio.get_event_loop()
|
self.loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
async def recv(self, client):
|
|
||||||
# if not client.is_disconnected():
|
|
||||||
# self.log.debug(f"Client with {client.nick}({client.cid}) disconnected")
|
|
||||||
# return
|
|
||||||
|
|
||||||
header = await client.reader.read(4) # header: 4 bytes
|
|
||||||
data = await client.reader.read(101 * MB)
|
|
||||||
|
|
||||||
int_header = 0
|
|
||||||
for i in range(len(header)):
|
|
||||||
int_header += header[i]
|
|
||||||
self.log.debug(f"header: `{header}`; int_header: `{int_header}`; data: `{data}`;")
|
|
||||||
|
|
||||||
if int_header <= 0:
|
|
||||||
await client.kick("Invalid packet - header negative")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not int_header < 100 * MB:
|
|
||||||
await client.kick("Header size limit exceeded")
|
|
||||||
self.log.warn(f"Client {client.nick}({client.cid}) sent header of >100MB - "
|
|
||||||
f"assuming malicious intent and disconnecting the client.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if len(data) != int_header:
|
|
||||||
self.log.debug(f"WARN Expected to read {int_header} bytes, instead got {len(data)}")
|
|
||||||
|
|
||||||
# TODO: ABG: DeComp(Data)
|
|
||||||
abg = b"ABG:"
|
|
||||||
if len(data) > len(abg) and data.startswith(abg):
|
|
||||||
data = data[len(abg):]
|
|
||||||
# return DeComp(Data);
|
|
||||||
return data
|
|
||||||
|
|
||||||
async def auth_client(self, reader, writer):
|
async def auth_client(self, reader, writer):
|
||||||
# TODO: Authentication
|
|
||||||
client = self.Core.create_client(reader, writer)
|
client = self.Core.create_client(reader, writer)
|
||||||
self.log.info(f"Identifying new ClientConnection...")
|
self.log.info(f"Identifying new ClientConnection...")
|
||||||
data = await self.recv(client)
|
data = await client.recv()
|
||||||
self.log.debug(f"recv1 data: {data}")
|
self.log.debug(f"recv1 data: {data}")
|
||||||
if len(data) > 50:
|
if len(data) > 50:
|
||||||
await client.kick("Too long data")
|
await client.kick("Too long data")
|
||||||
@ -67,9 +33,8 @@ class TCPServer:
|
|||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
await client.tcp_send(b"A") # Accepted client version
|
await client.tcp_send(b"A") # Accepted client version
|
||||||
# await client.tcp_send(b"S") # Ask client key
|
|
||||||
|
|
||||||
data = await self.recv(client)
|
data = await client.recv()
|
||||||
self.log.debug(f"recv2 data: {data}")
|
self.log.debug(f"recv2 data: {data}")
|
||||||
if len(data) > 50:
|
if len(data) > 50:
|
||||||
await client.kick("Invalid Key (too long)!")
|
await client.kick("Invalid Key (too long)!")
|
||||||
@ -87,11 +52,13 @@ class TCPServer:
|
|||||||
client.nick = res["username"]
|
client.nick = res["username"]
|
||||||
client.roles = res["roles"]
|
client.roles = res["roles"]
|
||||||
client.guest = res["guest"]
|
client.guest = res["guest"]
|
||||||
|
client._update_logger()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error(f"Auth error: {e}")
|
self.log.error(f"Auth error: {e}")
|
||||||
await client.kick('Invalid authentication data! Try to econnect in 5 minutes.')
|
await client.kick('Invalid authentication data! Try to connect in 5 minutes.')
|
||||||
|
|
||||||
# TODO: Password party
|
# TODO: Password party
|
||||||
|
# await client.tcp_send(b"S") # Ask client key
|
||||||
|
|
||||||
ev.call_event("on_auth", client)
|
ev.call_event("on_auth", client)
|
||||||
|
|
||||||
@ -113,8 +80,10 @@ class TCPServer:
|
|||||||
case "C":
|
case "C":
|
||||||
result, client = await self.auth_client(reader, writer)
|
result, client = await self.auth_client(reader, writer)
|
||||||
if result:
|
if result:
|
||||||
await client.kick("Authentication success! Server not ready.")
|
await client.sync_resources()
|
||||||
|
# await client.kick("Authentication success! Server not ready.")
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
case "D":
|
case "D":
|
||||||
return await self.handle_download(writer)
|
return await self.handle_download(writer)
|
||||||
case "P":
|
case "P":
|
||||||
@ -144,7 +113,8 @@ class TCPServer:
|
|||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
self.log.debug("Starting TCP server.")
|
self.log.debug("Starting TCP server.")
|
||||||
server = await asyncio.start_server(self.handle_client, self.host, self.port, backlog=config.Game["players"]+1)
|
server = await asyncio.start_server(self.handle_client, self.host, self.port,
|
||||||
|
backlog=config.Game["players"] + 1)
|
||||||
try:
|
try:
|
||||||
self.log.debug(f"TCP server started on {server.sockets[0].getsockname()!r}")
|
self.log.debug(f"TCP server started on {server.sockets[0].getsockname()!r}")
|
||||||
while True:
|
while True:
|
||||||
|
@ -20,7 +20,6 @@ class TCPServer:
|
|||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
self.loop = asyncio.get_event_loop()
|
self.loop = asyncio.get_event_loop()
|
||||||
async def recv(self, client: Client) -> bytes: ...
|
|
||||||
async def auth_client(self, reader: StreamReader, writer: StreamWriter) -> Tuple[bool, Client]: ...
|
async def auth_client(self, reader: StreamReader, writer: StreamWriter) -> Tuple[bool, Client]: ...
|
||||||
async def handle_download(self, writer: StreamWriter) -> bool: ...
|
async def handle_download(self, writer: StreamWriter) -> bool: ...
|
||||||
async def handle_code(self, code: str, reader: StreamReader, writer: StreamWriter) -> bool: ...
|
async def handle_code(self, code: str, reader: StreamReader, writer: StreamWriter) -> bool: ...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user