fixed issue crashing connections and added system logger
This commit is contained in:
parent
677552a617
commit
15cce52aea
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"cSpell.ignoreWords": [
|
||||||
|
"posx"
|
||||||
|
]
|
||||||
|
}
|
@ -9,13 +9,17 @@ class GameManager:
|
|||||||
__state:str
|
__state:str
|
||||||
__round:str
|
__round:str
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, logger):
|
||||||
self.__players = {}
|
self.__players = {}
|
||||||
self.__playingPlayer = None
|
self.__playingPlayer = None
|
||||||
self.__state = "waiting"
|
self.__state = "waiting"
|
||||||
self.__round = "none"
|
self.__round = "none"
|
||||||
|
self.logger = logger
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def getLogger(self):
|
||||||
|
return self.logger
|
||||||
|
|
||||||
# game round management
|
# game round management
|
||||||
# this section manages the flow of rounds this should inherit itself
|
# this section manages the flow of rounds this should inherit itself
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
18
Game Server/Classes/System/Logger.py
Normal file
18
Game Server/Classes/System/Logger.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
class Logger:
|
||||||
|
def __init__(self, filename):
|
||||||
|
logging.basicConfig(filename=filename,
|
||||||
|
filemode='a',
|
||||||
|
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
|
||||||
|
datefmt='%H:%M:%S',
|
||||||
|
level=logging.DEBUG)
|
||||||
|
|
||||||
|
def info(self, message):
|
||||||
|
print(message)
|
||||||
|
logging.info(message)
|
||||||
|
|
||||||
|
def error(self, message):
|
||||||
|
print(message)
|
||||||
|
logging.error(message)
|
@ -13,15 +13,7 @@ class TCPEventHandler:
|
|||||||
|
|
||||||
# handles passing of event data to the right functions
|
# handles passing of event data to the right functions
|
||||||
def handleTCPEvents(self, event, gameManager:GameManager, address):
|
def handleTCPEvents(self, event, gameManager:GameManager, address):
|
||||||
pass
|
gameManager.getLogger().info(f"incommingevent {event}")
|
||||||
|
|
||||||
class UDPEventHandler:
|
|
||||||
__udpSocket:socket
|
|
||||||
|
|
||||||
def __init__(self, socket:socket, gameManager:GameManager):
|
|
||||||
self.__udpSocket = socket
|
|
||||||
|
|
||||||
def handleUDPEvents(self, event):
|
|
||||||
if event["event"] == "PlaceCard":
|
if event["event"] == "PlaceCard":
|
||||||
pass
|
pass
|
||||||
elif event["event"] == "MoveCard":
|
elif event["event"] == "MoveCard":
|
||||||
@ -36,3 +28,4 @@ class UDPEventHandler:
|
|||||||
pass
|
pass
|
||||||
elif event["event"] == "ActivateMonsterCard":
|
elif event["event"] == "ActivateMonsterCard":
|
||||||
pass
|
pass
|
||||||
|
pass
|
@ -1,4 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
|
import signal
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
@ -9,56 +10,6 @@ from Classes.System.Network.EventHandler import UDPEventHandler, TCPEventHandler
|
|||||||
from Classes.System.World import World
|
from Classes.System.World import World
|
||||||
|
|
||||||
class NetworkManager:
|
class NetworkManager:
|
||||||
|
|
||||||
#class UDP:
|
|
||||||
# __Addr:str
|
|
||||||
# __Port:str
|
|
||||||
# __BufferSize:int = 1024
|
|
||||||
# __udpSocket:socket
|
|
||||||
# __users:dict
|
|
||||||
# __eventHandler: UDPEventHandler
|
|
||||||
# __UDPClientThread:threading.Thread
|
|
||||||
# __gameManager:GameManager
|
|
||||||
#
|
|
||||||
# def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
|
||||||
# self.__Addr = Addr
|
|
||||||
# self.__Port = int(Port)
|
|
||||||
# self.__gameManager = gameManager
|
|
||||||
# self.__users = {}
|
|
||||||
# self.__eventHandler = {}
|
|
||||||
# self.__udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
#
|
|
||||||
# try:
|
|
||||||
# self.__udpSocket.bind((self.__Addr, self.__Port))
|
|
||||||
# except OSError as e:
|
|
||||||
# print(f"Error binding UDP socket: {e}")
|
|
||||||
#
|
|
||||||
# self.__UDPClientThread = threading.Thread(target=self.receive)
|
|
||||||
# self.__UDPClientThread.start()
|
|
||||||
#
|
|
||||||
# # handles incoming udp data
|
|
||||||
# def receive(self):
|
|
||||||
# while True:
|
|
||||||
# data, address = self.__udpSocket.recvfrom(self.__BufferSize)
|
|
||||||
# message = data.decode()
|
|
||||||
# messageJson = json.loads(message)
|
|
||||||
# user = messageJson.get("user")
|
|
||||||
#
|
|
||||||
# if user not in self.__users:
|
|
||||||
# self.__users[user] = address # Storing new user in dictionary
|
|
||||||
#
|
|
||||||
# # Process the message and handle accordingly
|
|
||||||
# self.__eventHandler.handleUDPEvents(messageJson, self.__serverWorld)
|
|
||||||
# print(f"Received message from {address}: {message}")
|
|
||||||
#
|
|
||||||
# def broadcast(self, payload:dict):
|
|
||||||
# for user_address in self.__users.values():
|
|
||||||
# self.__udpSocket.sendto(json.dumps(payload).encode(), user_address)
|
|
||||||
#
|
|
||||||
# def send(self, payload:dict, user:str):
|
|
||||||
# if user in self.__users:
|
|
||||||
# self.__udpSocket.sendto(json.dumps(payload).encode(), self.__users[user])
|
|
||||||
#
|
|
||||||
class TCP:
|
class TCP:
|
||||||
__Addr:str
|
__Addr:str
|
||||||
__Port:str
|
__Port:str
|
||||||
@ -70,40 +21,49 @@ class NetworkManager:
|
|||||||
__gameManager:GameManager
|
__gameManager:GameManager
|
||||||
|
|
||||||
def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
||||||
|
gameManager.getLogger().info("starting up network manager")
|
||||||
|
|
||||||
self.running = True
|
self.running = True
|
||||||
self.__Addr = Addr
|
self.__Addr = Addr
|
||||||
self.__Port = int(Port)
|
self.__Port = int(Port)
|
||||||
self.__gameManager = gameManager
|
self.__gameManager = gameManager
|
||||||
self.__eventHandler = {}
|
self.__eventHandler = {}
|
||||||
|
|
||||||
|
gameManager.getLogger().info("starting up tcp server")
|
||||||
self.__tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.__tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.__tcpSocket.bind((self.__Addr, self.__Port))
|
self.__tcpSocket.bind((self.__Addr, self.__Port))
|
||||||
self.__tcpSocket.listen()
|
self.__tcpSocket.listen()
|
||||||
|
|
||||||
|
gameManager.getLogger().info("starting up thread for client socket accepting")
|
||||||
self.__TCPClientThread = threading.Thread(target=self.accept_connections)
|
self.__TCPClientThread = threading.Thread(target=self.accept_connections)
|
||||||
|
self.__TCPClientThread.daemon = True
|
||||||
self.__TCPClientThread.start()
|
self.__TCPClientThread.start()
|
||||||
|
|
||||||
def accept_connections(self):
|
def accept_connections(self):
|
||||||
while self.running:
|
while self.running:
|
||||||
try:
|
try:
|
||||||
client_tcp_socket, client_address = self.__tcpSocket.accept()
|
client_tcp_socket, client_address = self.__tcpSocket.accept()
|
||||||
print(f"Connected with {client_address}")
|
self.__gameManager.getLogger().info(f"Connected with {client_address}")
|
||||||
self.__gameManager.getPlayers()[client_address] = client_tcp_socket
|
self.__gameManager.getPlayers()[client_address] = client_tcp_socket
|
||||||
self.__eventHandler[client_address] = TCPEventHandler(client_tcp_socket)
|
self.__eventHandler[client_address] = TCPEventHandler(client_tcp_socket)
|
||||||
client_handler_thread = threading.Thread(
|
client_handler_thread = threading.Thread(
|
||||||
target=self.receive,
|
target=self.receive,
|
||||||
args=(client_tcp_socket, client_address)
|
args=(client_tcp_socket, client_address)
|
||||||
)
|
)
|
||||||
|
self.__gameManager.getLogger().info(f"starting client handler thread for client at address {client_address}")
|
||||||
|
client_handler_thread.daemon = True
|
||||||
client_handler_thread.start()
|
client_handler_thread.start()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"tcp socket failed to accept connection due to error: {e}")
|
self.__gameManager.getLogger().error(f"tcp socket failed to accept connection due to error: {e}")
|
||||||
pass
|
pass
|
||||||
|
client_handler_thread.join()
|
||||||
|
|
||||||
def receive(self, client_socket, client_address):
|
def receive(self, client_socket, client_address):
|
||||||
while self.running:
|
while self.running:
|
||||||
try:
|
try:
|
||||||
data = client_socket.recv(self.__BufferSize)
|
data = client_socket.recv(self.__BufferSize)
|
||||||
if not data:
|
if not data:
|
||||||
print(f"Connection with {client_address} closed.")
|
self.__gameManager.getLogger().info(f"Connection with {client_address} closed.")
|
||||||
break
|
break
|
||||||
|
|
||||||
message = data.decode()
|
message = data.decode()
|
||||||
@ -114,21 +74,23 @@ class NetworkManager:
|
|||||||
# if enough users for a round are connected the server has to start the game
|
# if enough users for a round are connected the server has to start the game
|
||||||
if user not in self.__gameManager.getPlayers():
|
if user not in self.__gameManager.getPlayers():
|
||||||
if messageJson["event"] == "login":
|
if messageJson["event"] == "login":
|
||||||
|
self.logger.__gameManager.getLogger().info("user logging in")
|
||||||
|
self.logger.__gameManager.getLogger().info("task passed off to gameManager")
|
||||||
self.__gameManager.addPlayers(Player(messageJson["username"], messageJson["deck"]), client_socket, client_address)
|
self.__gameManager.addPlayers(Player(messageJson["username"], messageJson["deck"]), client_socket, client_address)
|
||||||
print(f"connected users {len(self.__gameManager.getPlayers())}")
|
self.__gameManager.getLogger().info(f"connected users {len(self.__gameManager.getPlayers())}")
|
||||||
|
|
||||||
self.__eventHandler[client_address].handleTCPEvents(messageJson, self.__gameManager, client_address)
|
self.__eventHandler[client_address].handleTCPEvents(messageJson, self.__gameManager, client_address)
|
||||||
print(f"Received message from {client_address}: {message}")
|
self.__gameManager.getLogger().info(f"Received message from {client_address}: {message}")
|
||||||
|
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
if e.errno == 10054:
|
if e.errno == 10054:
|
||||||
print(f"Connection with {client_address} forcibly closed by remote host.")
|
self.__gameManager.getLogger().error(f"Connection with {client_address} forcibly closed by remote host.")
|
||||||
break
|
break
|
||||||
print(f"Socket error receiving data from {client_address}: {e}")
|
self.__gameManager.getLogger().error(f"Socket error receiving data from {client_address}: {e}")
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
print(f"JSON decoding error receiving data from {client_address}: {e}")
|
self.__gameManager.getLogger().error(f"JSON decoding error receiving data from {client_address}: {e}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error receiving data from {client_address}: {e}")
|
self.__gameManager.getLogger().error(f"Error receiving data from {client_address}: {e}")
|
||||||
|
|
||||||
def broadcast(self, payload:dict):
|
def broadcast(self, payload:dict):
|
||||||
for user in self.__gameManager.getPlayers().values():
|
for user in self.__gameManager.getPlayers().values():
|
||||||
@ -140,11 +102,19 @@ class NetworkManager:
|
|||||||
if user in players and "socket" in players[user]:
|
if user in players and "socket" in players[user]:
|
||||||
players[user]["socket"].send(json.dumps(payload).encode())
|
players[user]["socket"].send(json.dumps(payload).encode())
|
||||||
else:
|
else:
|
||||||
print(f"user '{user}' or socket was not found 'socket' failed to send data.")
|
self.__gameManager.getLogger().error(f"user '{user}' or socket was not found 'socket' failed to send data.")
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.__TCPClientThread.join() # Wait for the thread to finish before exiting
|
||||||
|
|
||||||
tcp: TCP
|
tcp: TCP
|
||||||
# udp: UDP
|
# udp: UDP
|
||||||
|
|
||||||
def __init__(self, Addr:str, TCPPort:str, UDPPort:str, gameManager:GameManager):
|
def __init__(self, Addr:str, TCPPort:str, UDPPort:str, gameManager:GameManager):
|
||||||
self.tcp = self.TCP(Addr, TCPPort, gameManager)
|
self.tcp = self.TCP(Addr, TCPPort, gameManager)
|
||||||
# self.udp = self.UDP(Addr, UDPPort, gameManager)
|
signal.signal(signal.SIGINT, self.handle_interrupt) # Register the signal handler
|
||||||
|
|
||||||
|
def handle_interrupt(self, signum, frame):
|
||||||
|
self.__gameManager.getLogger().info("Received keyboard interrupt. Stopping the server.")
|
||||||
|
self.tcp().stop()
|
||||||
|
sys.exit(0)
|
Binary file not shown.
Binary file not shown.
@ -6,6 +6,7 @@ from Classes.System.GameManager import GameManager
|
|||||||
from Classes.System.Network.NetworkManger import NetworkManager
|
from Classes.System.Network.NetworkManger import NetworkManager
|
||||||
from Classes.System.PlayerManager import Player
|
from Classes.System.PlayerManager import Player
|
||||||
from Classes.System.World import World
|
from Classes.System.World import World
|
||||||
|
from Classes.System.Logger import Logger
|
||||||
|
|
||||||
class Server:
|
class Server:
|
||||||
|
|
||||||
@ -17,16 +18,23 @@ class Server:
|
|||||||
|
|
||||||
networkManager:NetworkManager
|
networkManager:NetworkManager
|
||||||
|
|
||||||
def __init__(self, address:str, tcpPort:str, udpPort:str):
|
def __init__(self, address:str, tcpPort:str, udpPort:str, logger:Logger):
|
||||||
self.__address = address
|
self.__address = address
|
||||||
self.__tcpPort = tcpPort
|
self.__tcpPort = tcpPort
|
||||||
self.__udpPort = udpPort
|
self.__udpPort = udpPort
|
||||||
self.__world = World()
|
self.__world = World()
|
||||||
self.__gameManager = GameManager()
|
self.logger = logger
|
||||||
|
|
||||||
|
self.logger.info("starting up game manager")
|
||||||
|
self.__gameManager = GameManager(logger)
|
||||||
|
|
||||||
|
self.logger.info("preparing to start server")
|
||||||
self.startServer(self.__gameManager)
|
self.startServer(self.__gameManager)
|
||||||
|
|
||||||
# handles starting the server and assigning socket values to the local reference
|
# handles starting the server and assigning socket values to the local reference
|
||||||
def startServer(self, gameManager:GameManager):
|
def startServer(self, gameManager:GameManager):
|
||||||
|
self.logger.info("starting up network manager")
|
||||||
self.__networkManager = NetworkManager(self.__address, self.__tcpPort, self.__udpPort, gameManager)
|
self.__networkManager = NetworkManager(self.__address, self.__tcpPort, self.__udpPort, gameManager)
|
||||||
|
|
||||||
|
def getNetworkManager(self) -> NetworkManager:
|
||||||
|
return self.__networkManager
|
Binary file not shown.
BIN
Game Server/Classes/System/__pycache__/Logger.cpython-311.pyc
Normal file
BIN
Game Server/Classes/System/__pycache__/Logger.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
@ -1,7 +1,18 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import random
|
||||||
|
import string
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from Classes.System.Server import Server
|
from Classes.System.Server import Server
|
||||||
|
from Classes.System.Logger import Logger
|
||||||
|
|
||||||
|
def get_random_string(length) -> str:
|
||||||
|
# choose from all lowercase letter
|
||||||
|
letters = string.ascii_lowercase
|
||||||
|
result_str = ''.join(random.choice(letters) for i in range(length))
|
||||||
|
print("Random string of length", length, "is:", result_str)
|
||||||
|
return result_str
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# retrieves host data from environment
|
# retrieves host data from environment
|
||||||
@ -9,9 +20,11 @@ def main():
|
|||||||
TCPPORT = "54322"
|
TCPPORT = "54322"
|
||||||
UDPPORT = "54323"
|
UDPPORT = "54323"
|
||||||
|
|
||||||
Server(HOST, TCPPORT, UDPPORT)
|
logger = Logger("log/"+get_random_string(8)+".log")
|
||||||
|
logger.info("starting up server")
|
||||||
|
server = Server(HOST, TCPPORT, UDPPORT, logging)
|
||||||
|
server.getNetworkManager().tcp.stop()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
@ -13,7 +13,8 @@ def PlaceCard(tcpClient, card):
|
|||||||
"event":"placecard",
|
"event":"placecard",
|
||||||
"card": card.getID(),
|
"card": card.getID(),
|
||||||
"type": card.getType(),
|
"type": card.getType(),
|
||||||
"pos": card.getPos(),
|
"posx": card.getPos().x,
|
||||||
|
"posy": card.getPos().y,
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpClient.send(payload)
|
tcpClient.send(payload)
|
||||||
@ -27,7 +28,7 @@ def CardPlaced(world:World, card:int, type:str, owner:str, pos:pygame.Vector2, i
|
|||||||
world.spawnSpellCard(f"Assets/Cards/{card}/", pos, inputHandler, owner)
|
world.spawnSpellCard(f"Assets/Cards/{card}/", pos, inputHandler, owner)
|
||||||
pass
|
pass
|
||||||
elif type == "TrapCard":
|
elif type == "TrapCard":
|
||||||
world.spawmTrapCard(f"Assets/Cards/{card}/", pos, inputHandler, owner)
|
world.spawnTrapCard(f"Assets/Cards/{card}/", pos, inputHandler, owner)
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
Binary file not shown.
@ -117,7 +117,7 @@ class App:
|
|||||||
if event.button == 1: # Wenn linke Maustaste losgelassen wird
|
if event.button == 1: # Wenn linke Maustaste losgelassen wird
|
||||||
for card in self.__world.getCards():
|
for card in self.__world.getCards():
|
||||||
card.setDragging(False)
|
card.setDragging(False)
|
||||||
card.setState("placed")
|
# card.setState("placed")
|
||||||
# TODO: send place card event to server
|
# TODO: send place card event to server
|
||||||
# resets the currently selected card in order to prevent it getting moved
|
# resets the currently selected card in order to prevent it getting moved
|
||||||
try:
|
try:
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user