sampy3/sampy/server.py

84 lines
2.4 KiB
Python
Raw Normal View History

2023-03-15 07:12:47 +01:00
from __future__ import annotations
import asyncio
from typing import TYPE_CHECKING, Tuple, Type
from sampy.client.player import Player
from sampy.config import Config
if TYPE_CHECKING:
from sampy.network.protocol import Protocol
class UDPProtocol:
transport: asyncio.transports.DatagramTransport
def __init__(self, protocol: Protocol, local_addr: Tuple[str, int]):
self.protocol = protocol
self.local_addr = local_addr
def start(self):
loop = asyncio.get_event_loop()
connect = loop.create_datagram_endpoint(
lambda: self,
local_addr=self.local_addr,
)
loop.run_until_complete(connect)
def stop(self): # TODO: Shutdown code
if self.transport is None:
raise Exception("Cannot stop a server that hasn't been started")
self.transport.close()
def connection_made(self, transport: asyncio.transports.DatagramTransport):
self.transport = transport
2023-03-15 07:27:33 +01:00
def connection_lost(self, exc: Exception | None):
pass
2023-03-15 07:12:47 +01:00
def datagram_received(self, data: bytes, addr: Tuple[str, int]):
raise NotImplementedError
def sendto(self, data: bytes | bytearray | memoryview, addr: Tuple[str, int]):
self.transport.sendto(data, addr)
class Server(UDPProtocol):
config: Config
def __init__(self, protocol: Type[Protocol], config: Config = Config()):
super().__init__(
protocol=protocol(),
local_addr=(
config.get("sampy", "host"),
config.getint("sampy", "port"),
),
)
self.config = config
def datagram_received(self, data: bytes, addr: Tuple[str, int]):
loop = asyncio.get_event_loop()
loop.create_task(self.protocol.on_packet(self, data, addr))
@property
def players(self) -> list[Player]: # TODO
return []
2023-03-15 07:27:33 +01:00
class InteractiveServer(Server):
def __init__(self, protocol: Type[Protocol], config: Config = Config()):
super().__init__(protocol=protocol, config=config)
loop = asyncio.get_event_loop()
loop.create_task(self.run_input_loop())
async def run_input_loop(self):
loop = asyncio.get_event_loop()
while True:
command = await loop.run_in_executor(None, input)
if command in ("quit", "exit", "stop"):
self.stop()
loop.stop()
return