moved game management into own class serverside
This commit is contained in:
parent
d9b367dd42
commit
8f90633b16
@ -4,10 +4,11 @@ import random
|
|||||||
class Player:
|
class Player:
|
||||||
__id:int
|
__id:int
|
||||||
__hp:int
|
__hp:int
|
||||||
|
__mana:int
|
||||||
__name:str
|
__name:str
|
||||||
__handCards:list
|
__handCards:list
|
||||||
|
|
||||||
def __init__(self, name:str, hp:int=1000):
|
def __init__(self, name:str, hp:int=1000, mana:int=0):
|
||||||
self.__hp = hp
|
self.__hp = hp
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__handCards = []
|
self.__handCards = []
|
||||||
@ -28,6 +29,13 @@ class Player:
|
|||||||
def getHand(self) -> list:
|
def getHand(self) -> list:
|
||||||
return self.__handCards
|
return self.__handCards
|
||||||
|
|
||||||
|
def getMana(self) -> int:
|
||||||
|
return self.__mana
|
||||||
|
|
||||||
|
def addMana(self, amount) -> int:
|
||||||
|
self.__mana + amount
|
||||||
|
return self.__mana
|
||||||
|
|
||||||
def AddToHand(self, card) -> list:
|
def AddToHand(self, card) -> list:
|
||||||
self.__handCards.append(card)
|
self.__handCards.append(card)
|
||||||
return self.__handCards
|
return self.__handCards
|
||||||
|
BIN
Game Server/Classes/Game/__pycache__/Player.cpython-311.pyc
Normal file
BIN
Game Server/Classes/Game/__pycache__/Player.cpython-311.pyc
Normal file
Binary file not shown.
89
Game Server/Classes/System/GameManager.py
Normal file
89
Game Server/Classes/System/GameManager.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import socket
|
||||||
|
from Classes.Game.Player import Player
|
||||||
|
|
||||||
|
|
||||||
|
class GameManager:
|
||||||
|
__players:dict
|
||||||
|
__playingPlayer:Player
|
||||||
|
__state:str
|
||||||
|
__round:str
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.__players = {}
|
||||||
|
self.__playingPlayer = None
|
||||||
|
self.__state = "waiting"
|
||||||
|
self.__round = "none"
|
||||||
|
pass
|
||||||
|
|
||||||
|
# game round management
|
||||||
|
# this section manages the flow of rounds this should inherit itself
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# this function iterates all
|
||||||
|
def progressRound(self):
|
||||||
|
# phases
|
||||||
|
# - playerPrep => playing player switches, gets a mana point and gets verified
|
||||||
|
if self.__playingPlayer != None:
|
||||||
|
for player in self.__players:
|
||||||
|
if self.__playingPlayer != player:
|
||||||
|
self.__playingPlayer = player
|
||||||
|
else:
|
||||||
|
self.__playingPlayer = next(iter(self.__players))
|
||||||
|
# - playerDraw => player draws a card
|
||||||
|
# - playerPlay => player can place cards and active effects
|
||||||
|
# - playerEnd => player ends his turn and the code reiterates with the remaining player
|
||||||
|
pass
|
||||||
|
|
||||||
|
# game state management
|
||||||
|
# this section mostly only used by the networking and event handling classes
|
||||||
|
# other parts should never need to interface with this unless really required
|
||||||
|
# =============================================================================
|
||||||
|
def startGame(self):
|
||||||
|
self.__state = "running"
|
||||||
|
|
||||||
|
print("game starts")
|
||||||
|
for userAddr in self.__users.keys():
|
||||||
|
try:
|
||||||
|
user = self.__serverWorld.getPlayers[userAddr]
|
||||||
|
user.addMana(1000)
|
||||||
|
user.adjustHP(1000)
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"event":"startgame",
|
||||||
|
"mana": user.getMana(),
|
||||||
|
"hp": user.getHP()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.send(payload, userAddr)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"failed to start game due to error: {e}")
|
||||||
|
break
|
||||||
|
# handles notifying all players that the game starts
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stopGame(self):
|
||||||
|
# handles notifying all players that the game stops
|
||||||
|
# handles stoping the game itself and notifies server to stop itself
|
||||||
|
pass
|
||||||
|
|
||||||
|
# player management
|
||||||
|
# the network manager will create a player instance
|
||||||
|
# =============================================================
|
||||||
|
|
||||||
|
# gets all player known to the game manager and returns them
|
||||||
|
def getPlayers(self) -> dict:
|
||||||
|
return self.__players
|
||||||
|
|
||||||
|
# creates a player and handles counting all players and if conditions met starting the game
|
||||||
|
# returns the new dict in which the new player now is added
|
||||||
|
def addPlayers(self, player:Player, socket:socket, clientAddr) -> dict:
|
||||||
|
self.__players[clientAddr] = {
|
||||||
|
player: player,
|
||||||
|
socket:socket
|
||||||
|
}
|
||||||
|
|
||||||
|
# counts participating players and starts the game if enough have joined
|
||||||
|
if len(self.__players) == 2:
|
||||||
|
self.startGame()
|
||||||
|
|
||||||
|
return self.__players
|
@ -1,4 +1,8 @@
|
|||||||
import socket
|
import socket
|
||||||
|
from Classes.Game.Player import Player
|
||||||
|
from Classes.System.GameManager import GameManager
|
||||||
|
|
||||||
|
from Classes.System.World import World
|
||||||
|
|
||||||
|
|
||||||
class TCPEventHandler:
|
class TCPEventHandler:
|
||||||
@ -8,13 +12,13 @@ class TCPEventHandler:
|
|||||||
self.__tcpSocket = socket
|
self.__tcpSocket = socket
|
||||||
|
|
||||||
# handles passing of event data to the right functions
|
# handles passing of event data to the right functions
|
||||||
def handleTCPEvents(self, event):
|
def handleTCPEvents(self, event, gameManager:GameManager, address):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class UDPEventHandler:
|
class UDPEventHandler:
|
||||||
__udpSocket:socket
|
__udpSocket:socket
|
||||||
|
|
||||||
def __init__(self, socket:socket):
|
def __init__(self, socket:socket, gameManager:GameManager):
|
||||||
self.__udpSocket = socket
|
self.__udpSocket = socket
|
||||||
|
|
||||||
def handleUDPEvents(self, event):
|
def handleUDPEvents(self, event):
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
import threading
|
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.Network.EventHandler import UDPEventHandler, TCPEventHandler
|
||||||
|
from Classes.System.World import World
|
||||||
|
|
||||||
class NetworkManager:
|
class NetworkManager:
|
||||||
|
|
||||||
@ -11,24 +14,28 @@ class NetworkManager:
|
|||||||
__Port:str
|
__Port:str
|
||||||
__BufferSize:int = 1024
|
__BufferSize:int = 1024
|
||||||
__udpSocket:socket
|
__udpSocket:socket
|
||||||
__users:list
|
__users:dict
|
||||||
__eventHandler: UDPEventHandler
|
__eventHandler: UDPEventHandler
|
||||||
__UDPClientThread:threading.Thread
|
__UDPClientThread:threading.Thread
|
||||||
|
__gameManager:GameManager
|
||||||
def __init__(self, Addr:str, Port:str):
|
|
||||||
|
def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
||||||
self.__Addr = Addr
|
self.__Addr = Addr
|
||||||
self.__Port = int(Port)
|
self.__Port = int(Port)
|
||||||
|
self.__gameManager = gameManager
|
||||||
self.__users = {}
|
self.__users = {}
|
||||||
self.__eventHandler = {}
|
self.__eventHandler = {}
|
||||||
self.__udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
self.__udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
self.__udpSocket.bind((self.__Addr, self.__Port))
|
|
||||||
|
try:
|
||||||
# Starten eines Threads für das Empfangen von UDP-Daten
|
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 = threading.Thread(target=self.receive)
|
||||||
self.__UDPClientThread.start()
|
self.__UDPClientThread.start()
|
||||||
|
|
||||||
# handles incomming udp data
|
# handles incoming udp data
|
||||||
def receive(self):
|
def receive(self):
|
||||||
while True:
|
while True:
|
||||||
data, address = self.__udpSocket.recvfrom(self.__BufferSize)
|
data, address = self.__udpSocket.recvfrom(self.__BufferSize)
|
||||||
@ -40,7 +47,7 @@ class NetworkManager:
|
|||||||
self.__users[user] = address # Storing new user in dictionary
|
self.__users[user] = address # Storing new user in dictionary
|
||||||
|
|
||||||
# Process the message and handle accordingly
|
# Process the message and handle accordingly
|
||||||
self.__eventHandler.handleUDPEvents(messageJson)
|
self.__eventHandler.handleUDPEvents(messageJson, self.__serverWorld)
|
||||||
print(f"Received message from {address}: {message}")
|
print(f"Received message from {address}: {message}")
|
||||||
|
|
||||||
def broadcast(self, payload:dict):
|
def broadcast(self, payload:dict):
|
||||||
@ -56,15 +63,14 @@ class NetworkManager:
|
|||||||
__Port:str
|
__Port:str
|
||||||
__BufferSize:int = 1024
|
__BufferSize:int = 1024
|
||||||
__tcpSocket:socket
|
__tcpSocket:socket
|
||||||
__users:list
|
__eventHandler: dict
|
||||||
__eventHandler: TCPEventHandler
|
|
||||||
__TCPClientThread:threading.Thread
|
__TCPClientThread:threading.Thread
|
||||||
|
__gameManager:GameManager
|
||||||
|
|
||||||
def __init__(self, Addr:str, Port:str):
|
def __init__(self, Addr:str, Port:str, gameManager:GameManager):
|
||||||
self.__Addr = Addr
|
self.__Addr = Addr
|
||||||
self.__Port = int(Port)
|
self.__Port = int(Port)
|
||||||
|
self.__gameManager = gameManager
|
||||||
self.__users = {}
|
|
||||||
self.__eventHandler = {}
|
self.__eventHandler = {}
|
||||||
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))
|
||||||
@ -95,16 +101,20 @@ class NetworkManager:
|
|||||||
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.")
|
print(f"Connection with {client_address} closed.")
|
||||||
break # Verbindung geschlossen, Schleife beenden
|
break
|
||||||
|
|
||||||
message = data.decode()
|
message = data.decode()
|
||||||
messageJson = json.loads(message)
|
messageJson = json.loads(message)
|
||||||
user = messageJson.get("user")
|
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.__users:
|
if user not in self.__users:
|
||||||
self.__users[user] = client_address
|
if messageJson["event"] == "login":
|
||||||
|
self.__gameManager.addPlayers(Player(messageJson["username"]), self.__tcpSocket, client_address)
|
||||||
|
print(f"connected users {len(self.__users)}")
|
||||||
|
|
||||||
self.__eventHandler[client_address].handleTCPEvents(messageJson)
|
self.__eventHandler[client_address].handleTCPEvents(messageJson, self.__gameManager, client_address)
|
||||||
print(f"Received message from {client_address}: {message}")
|
print(f"Received message from {client_address}: {message}")
|
||||||
|
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
@ -118,16 +128,20 @@ class NetworkManager:
|
|||||||
print(f"Error receiving data from {client_address}: {e}")
|
print(f"Error receiving data from {client_address}: {e}")
|
||||||
|
|
||||||
def broadcast(self, payload:dict):
|
def broadcast(self, payload:dict):
|
||||||
for user_socket in self.__users.values():
|
for user in self.__gameManager.getPlayers().values():
|
||||||
user_socket.send(json.dumps(payload).encode())
|
user["socket"].send(json.dumps(payload).encode())
|
||||||
|
|
||||||
def send(self, payload:dict, user:str):
|
def send(self, payload: dict, user: str):
|
||||||
if user in self.__users:
|
players = self.__gameManager.getPlayers()
|
||||||
self.__users[user].send(json.dumps(payload).encode())
|
|
||||||
|
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
|
tcp: TCP
|
||||||
udp: UDP
|
udp: UDP
|
||||||
|
|
||||||
def __init__(self, Addr:str, TCPPort:str, UDPPort:str):
|
def __init__(self, Addr:str, TCPPort:str, UDPPort:str, gameManager:GameManager):
|
||||||
self.tcp = self.TCP(Addr, TCPPort)
|
self.tcp = self.TCP(Addr, TCPPort, gameManager)
|
||||||
self.udp = self.UDP(Addr, UDPPort)
|
self.udp = self.UDP(Addr, UDPPort, gameManager)
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -1,12 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
from Classes.Objects.Player import Player
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
__users:list
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.__users = []
|
|
||||||
|
|
||||||
def createUser(self, user:json):
|
def createUser(self, user:json):
|
||||||
self.__users.append(user)
|
self.__users.append(user)
|
||||||
|
|
||||||
@ -23,12 +17,7 @@ class Player:
|
|||||||
def getUsers(self) -> list:
|
def getUsers(self) -> list:
|
||||||
return self.__users
|
return self.__users
|
||||||
|
|
||||||
def getUser(self, user:int) -> (any | None):
|
def getUser(self, user:int):
|
||||||
for user in self.__users:
|
for user in self.__users:
|
||||||
if int(user["id"]) == user:
|
if int(user["id"]) == user:
|
||||||
return user
|
|
||||||
|
|
||||||
def getUser(self, user:str) -> (any | None):
|
|
||||||
for user in self.__users:
|
|
||||||
if user["name"] == user:
|
|
||||||
return user
|
return user
|
@ -1,25 +1,32 @@
|
|||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
|
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.World import World
|
||||||
|
|
||||||
class Server:
|
class Server:
|
||||||
|
|
||||||
__address:str
|
__address:str
|
||||||
__tcpPort:str
|
__tcpPort:str
|
||||||
__udpPort:str
|
__udpPort:str
|
||||||
|
__world:World
|
||||||
|
__gameManager:GameManager
|
||||||
|
|
||||||
networkManager:NetworkManager
|
networkManager:NetworkManager
|
||||||
|
|
||||||
def __init__(self, address:str, tcpPort:str, udpPort:str):
|
def __init__(self, address:str, tcpPort:str, udpPort:str):
|
||||||
self.__address = address
|
self.__address = address
|
||||||
self.__tcpPort = tcpPort
|
self.__tcpPort = tcpPort
|
||||||
self.__udpPort = udpPort
|
self.__udpPort = udpPort
|
||||||
|
self.__world = World()
|
||||||
|
self.__gameManager = GameManager()
|
||||||
|
|
||||||
|
|
||||||
self.startServer()
|
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):
|
def startServer(self, gameManager:GameManager):
|
||||||
self.__networkManager = NetworkManager(self.__address, self.__tcpPort, self.__udpPort)
|
self.__networkManager = NetworkManager(self.__address, self.__tcpPort, self.__udpPort, gameManager)
|
20
Game Server/Classes/System/World.py
Normal file
20
Game Server/Classes/System/World.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import socket
|
||||||
|
from Classes.Game.Player import Player
|
||||||
|
|
||||||
|
|
||||||
|
class World:
|
||||||
|
__players:dict
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.__players = {}
|
||||||
|
|
||||||
|
def getPlayers(self) -> list:
|
||||||
|
return self.__players
|
||||||
|
|
||||||
|
def addPlayers(self, player:Player, socket:socket, clientAddr) -> list:
|
||||||
|
self.__players[clientAddr] = {
|
||||||
|
player: player,
|
||||||
|
socket:socket
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.__players
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Game Server/Classes/System/__pycache__/World.cpython-311.pyc
Normal file
BIN
Game Server/Classes/System/__pycache__/World.cpython-311.pyc
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user