Files
sampy/sampy/server/__init__.py
2020-04-04 16:04:40 +02:00

65 lines
2.4 KiB
Python

import socket
import asyncio
from select import select # This is straight up magic
from ..struct.server import ServerConfig
from ..client import Client
from .compression import Compressor
import logging
logger = logging.getLogger(__name__)
class Server:
def __init__(self, config: ServerConfig):
self.config = config
self.clients = {}
self.rcon_clients = {}
self.compressor = Compressor(self.config)
async def create_socket(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind((self.config.host, self.config.port))
self.socket.setblocking(0) # TODO: Check if needed? I dont fully understand this "feature"
logger.debug("Socket created")
async def on_command(self, cmd: str):
logger.debug("on_command(%s)" % cmd)
# TODO: When commands return a reponse we also want to forward this to potential rcon clients
async def get_online_players(self): # TODO: Get data from server's client objects
return [
{"nick": b"Sunpy", "score": 64, "ping": 8, "id": 1} # replace id with function to get player's id
]
async def get_rules(self): # TODO
return {b"Rule name sample": b"Rule value", b"weburl": b"https://git.osufx.com/Sunpy/sampy"}
async def get_players_scores(self): # TODO
return {b"Sunpy": 64, b"username": 123}
async def main(self):
await self.create_socket()
while True:
(incomming, _, _) = select([self.socket], [], [], 0) # How this works is beyond me, but this sets `incomming` to be true~y if socket has awaiting data
if incomming:
data, addr = self.socket.recvfrom(0xFFFF)
if addr not in self.clients:
ip, port = addr
self.clients[addr] = Client(self, ip, port)
await (self.clients[addr].onpacket(data)) #await self.clients[addr].on_packet(data)
disconnected = [c for c in self.clients.values() if c.connected == False]
for c in disconnected: # Remove dead connections
addr = (c.ip, c.port)
if addr in self.clients:
del self.clients[addr]
logger.debug("free(%s)" % c)
await asyncio.sleep(0)