125 lines
4.0 KiB
Python
125 lines
4.0 KiB
Python
import asyncio
|
|
import logging
|
|
import socket
|
|
|
|
from .game import ConcurrentData, TableAlreadyExistException
|
|
from .message import parse_message, BiCommand
|
|
|
|
|
|
class Server:
|
|
def __init__(self) -> None:
|
|
self.__data = ConcurrentData()
|
|
|
|
async def handle_client(self, client: socket.socket) -> None:
|
|
loop = asyncio.get_event_loop()
|
|
|
|
logging.info("New client connected")
|
|
await loop.sock_sendall(client, b"HELLO\r\n")
|
|
|
|
try:
|
|
request = parse_message((await loop.sock_recv(client, 4096)).decode('utf8'))
|
|
except BrokenPipeError:
|
|
return
|
|
|
|
if len(request) != 2:
|
|
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
|
|
client.close()
|
|
return
|
|
|
|
if request[0] == BiCommand.NAME:
|
|
name = request[1]
|
|
else:
|
|
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
|
|
client.close()
|
|
return
|
|
|
|
if not await self.__data.has_table(name):
|
|
await loop.sock_sendall(client, b"ERROR: NO SUCH TABLE\r\nEND\r\n")
|
|
client.close()
|
|
return
|
|
|
|
table = await self.__data.get_table(name)
|
|
if await table.add_client(client, self.__data):
|
|
await loop.sock_sendall(client, b"OK\r\n")
|
|
else:
|
|
await loop.sock_sendall(client, b"ERROR: ROOM FULL\r\nEND\r\n")
|
|
client.close()
|
|
|
|
async def handle_croupier(self, client: socket.socket) -> None:
|
|
logging.debug("New croupier connected")
|
|
loop = asyncio.get_event_loop()
|
|
await loop.sock_sendall(client, b"HELLO\r\n")
|
|
|
|
try:
|
|
request = parse_message((await loop.sock_recv(client, 4096)).decode('utf8'))
|
|
except BrokenPipeError:
|
|
return
|
|
|
|
if len(request) != 2:
|
|
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
|
|
client.close()
|
|
return
|
|
|
|
if request[0] == BiCommand.NAME:
|
|
name = request[1]
|
|
await loop.sock_sendall(client, b"OK\r\n")
|
|
else:
|
|
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
|
|
client.close()
|
|
return
|
|
|
|
try:
|
|
request = parse_message((await loop.sock_recv(client, 4096)).decode('utf8'))
|
|
except BrokenPipeError:
|
|
return
|
|
|
|
if len(request) != 2:
|
|
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
|
|
client.close()
|
|
return
|
|
|
|
if request[0] == BiCommand.TIME:
|
|
time = request[1]
|
|
try:
|
|
await self.__data.add_table(name, int(time))
|
|
await loop.sock_sendall(client, b"OK\r\n")
|
|
except TableAlreadyExistException:
|
|
await loop.sock_sendall(client, b"ERROR: TABLE ALREADY EXIST\r\nEND\r\n")
|
|
else:
|
|
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
|
|
|
|
client.close()
|
|
|
|
async def listen_client(self) -> None:
|
|
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
listen_socket.bind(('0.0.0.0', 667))
|
|
listen_socket.listen(8)
|
|
listen_socket.setblocking(False)
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
while True:
|
|
client, _ = await loop.sock_accept(listen_socket)
|
|
loop.create_task(self.handle_client(client))
|
|
|
|
async def listen_croupier(self) -> None:
|
|
server_croupier = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
server_croupier.bind(('0.0.0.0', 668))
|
|
server_croupier.listen(8)
|
|
server_croupier.setblocking(False)
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
while True:
|
|
client, _ = await loop.sock_accept(server_croupier)
|
|
loop.create_task(self.handle_croupier(client))
|
|
|
|
async def run(self):
|
|
loop = asyncio.get_event_loop()
|
|
|
|
loop_client = loop.create_task(self.listen_client())
|
|
loop_croupier = loop.create_task(self.listen_croupier())
|
|
|
|
logging.info("Running server ...")
|
|
await asyncio.gather(loop_client, loop_croupier)
|