150 lines
6.2 KiB
Python

import json
import socket
import sys
import threading
from Classes.Game.Player import Player
from Classes.System.GameManager import GameManager
from Classes.System.Network.EventHandler import UDPEventHandler, TCPEventHandler
from Classes.System.World import World
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:
__Addr:str
__Port:str
__BufferSize:int = 1024
__tcpSocket:socket
__eventHandler: dict
__users: dict
__TCPClientThread:threading.Thread
__gameManager:GameManager
def __init__(self, Addr:str, Port:str, gameManager:GameManager):
self.running = True
self.__Addr = Addr
self.__Port = int(Port)
self.__gameManager = gameManager
self.__eventHandler = {}
self.__tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.__tcpSocket.bind((self.__Addr, self.__Port))
self.__tcpSocket.listen()
self.__TCPClientThread = threading.Thread(target=self.accept_connections)
self.__TCPClientThread.start()
def accept_connections(self):
while self.running:
try:
client_tcp_socket, client_address = self.__tcpSocket.accept()
print(f"Connected with {client_address}")
self.__gameManager.getPlayers()[client_address] = client_tcp_socket
self.__eventHandler[client_address] = TCPEventHandler(client_tcp_socket)
client_handler_thread = threading.Thread(
target=self.receive,
args=(client_tcp_socket, client_address)
)
client_handler_thread.start()
except Exception as e:
print(f"tcp socket failed to accept connection due to error: {e}")
pass
def receive(self, client_socket, client_address):
while self.running:
try:
data = client_socket.recv(self.__BufferSize)
if not data:
print(f"Connection with {client_address} closed.")
break
message = data.decode()
messageJson = json.loads(message)
user = messageJson.get("user")
# creates a user and counts how many currently are connected to the server
# if enough users for a round are connected the server has to start the game
if user not in self.__gameManager.getPlayers():
if messageJson["event"] == "login":
self.__gameManager.addPlayers(Player(messageJson["username"], messageJson["deck"]), client_socket, client_address)
print(f"connected users {len(self.__gameManager.getPlayers())}")
self.__eventHandler[client_address].handleTCPEvents(messageJson, self.__gameManager, client_address)
print(f"Received message from {client_address}: {message}")
except socket.error as e:
if e.errno == 10054:
print(f"Connection with {client_address} forcibly closed by remote host.")
break
print(f"Socket error receiving data from {client_address}: {e}")
except json.JSONDecodeError as e:
print(f"JSON decoding error receiving data from {client_address}: {e}")
except Exception as e:
print(f"Error receiving data from {client_address}: {e}")
def broadcast(self, payload:dict):
for user in self.__gameManager.getPlayers().values():
user["socket"].send(json.dumps(payload).encode())
def send(self, payload: dict, user: str):
players = self.__gameManager.getPlayers()
if user in players and "socket" in players[user]:
players[user]["socket"].send(json.dumps(payload).encode())
else:
print(f"user '{user}' or socket was not found 'socket' failed to send data.")
tcp: TCP
# udp: UDP
def __init__(self, Addr:str, TCPPort:str, UDPPort:str, gameManager:GameManager):
self.tcp = self.TCP(Addr, TCPPort, gameManager)
# self.udp = self.UDP(Addr, UDPPort, gameManager)