Initial game setup when starting

This commit is contained in:
2024-04-04 21:48:23 +02:00
parent 63d5a53701
commit c068143422
3 changed files with 105 additions and 34 deletions
+42 -22
View File
@@ -1,7 +1,8 @@
from typing import Callable, Any
from pydantic import ValidationError from pydantic import ValidationError
from websockets.server import WebSocketServerProtocol from websockets.server import WebSocketServerProtocol
from controller import GameController from controller import GameControllerInterface, ClientControllerInterface
from netcode.models import Message, LoginMessage from netcode.models import Message, LoginMessage
@@ -25,15 +26,19 @@ def vibe_check(t):
return decorator return decorator
class ClientController: class ClientController(ClientControllerInterface):
websocket: WebSocketServerProtocol websocket: WebSocketServerProtocol
game_controller: GameController game_controller: GameControllerInterface
player: Player player: Player
track_connection: Callable
def __init__( def __init__(
self, game_controller: GameController, websocket: WebSocketServerProtocol self,
game_controller: GameControllerInterface,
websocket: WebSocketServerProtocol,
): ):
self.websocket = websocket self.websocket = websocket
self.on_message = self.login_context self.on_message = self.login_context
@@ -41,7 +46,6 @@ class ClientController:
self.game_controller = game_controller self.game_controller = game_controller
async def listen(self): async def listen(self):
"""Initializes the client controller"""
await self.send( await self.send(
Message( Message(
type="context", type="context",
@@ -50,6 +54,8 @@ class ClientController:
) )
) )
await self.game_controller.announce_game(self.websocket)
async for message in self.websocket: async for message in self.websocket:
await self.on_message(message) await self.on_message(message)
@@ -59,17 +65,25 @@ class ClientController:
async def send_error(self, error: str): async def send_error(self, error: str):
await self.send(Message(type="error", data_type="error", data=error)) await self.send(Message(type="error", data_type="error", data=error))
async def send_announce_dict(self, notification_type: str, data: dict): async def send_announce_dict(
await self.send(Message(type=notification_type, data_type="object", data=data)) self,
notification_type: str,
data: dict,
client_filter: Callable[["ClientController"], Any] = lambda x: True,
):
if client_filter(self):
await self.send(
Message(type=notification_type, data_type="object", data=data)
)
@vibe_check(Message) @vibe_check(Message)
async def game_context(self, message: Message): async def game_context(self, message: Message):
"""Handles messages when the client is logged in"""
print(message) print(message)
@vibe_check(LoginMessage) @vibe_check(LoginMessage)
async def login_context(self, message: LoginMessage): async def login_context(self, message: LoginMessage):
"""Handles messages when the client isn't logged in"""
username = message.data username = message.data
if message.type == "register": if message.type == "register":
@@ -83,11 +97,12 @@ class ClientController:
player = await self.game_controller.game.create_player(username) player = await self.game_controller.game.create_player(username)
elif message.type == "login": elif message.type == "login":
player = self.game_controller.game.get_player(username) player2 = self.game_controller.game.get_player(username)
if player is None: if player2 is None:
await self.send_error("player doesn't exists") await self.send_error("player doesn't exists")
return return
player = player2
else: else:
await self.send_error("invalid message type for context") await self.send_error("invalid message type for context")
@@ -98,8 +113,6 @@ class ClientController:
self.on_message = self.pregame_context self.on_message = self.pregame_context
print("user logged in : " + username) print("user logged in : " + username)
await self.game_controller.announce_game(self.websocket)
await self.send( await self.send(
Message( Message(
type="set", type="set",
@@ -107,19 +120,26 @@ class ClientController:
data=self.player.uuid, data=self.player.uuid,
) )
) )
await self.send(
for player in self.game_controller.game.players: Message(
if player.team != self.player.team: type="context",
continue data_type="game_context_id",
data="pregame",
await self.send(
Message(type="update", data_type="object", data=player.serialize_team())
) )
)
# for player in self.game_controller.game.players:
# if player.team != self.player.team:
# continue
# await self.send(
# Message(type="update", data_type="object", data=player.serialize_team())
# )
@vibe_check(Message) @vibe_check(Message)
async def pregame_context(self, message: Message): async def pregame_context(self, message: Message):
"""Waits for players"""
if message.type == "ready": if message.type == "ready":
self.player.ready = bool(message.data) self.player.ready = bool(message.data)
if all(p.ready for p in self.game_controller.game.players): if all(p.ready for p in self.game_controller.game.players):
self.game_controller.start_game() await self.game_controller.start_game()
+38 -12
View File
@@ -1,18 +1,29 @@
import asyncio
from typing import Callable, List, Any
from netcode import WSServer from netcode import WSServer
from netcode.ws_server import WebSocketServerProtocol from netcode.ws_server import WebSocketServerProtocol
from netcode.models import Message from netcode.models import Message
from model import Game from model import Game
from controller import ClientController, GameControllerInterface
class GameController: class GameController(GameControllerInterface):
server: WSServer server: WSServer
game: Game game: Game
clients: List[ClientController]
def __init__(self, game: Game, server: WSServer): def __init__(self, game: Game, server: WSServer):
self.server = server self.server = server
self.game = game self.game = game
self.server.message_callbacks.append(self.guest_handler) self.server.on_new_connection_callback = self.on_new_connection
self.game.listeners.append(self.broadcast_announce_dict) self.game.listeners.append(self.broadcast_announce_dict)
self.clients = []
async def on_new_connection(self, websocket, callback: Callable):
client = ClientController(self, websocket)
self.clients.append(client)
await asyncio.gather(client.listen(), callback())
async def send(self, message: Message, websocket: WebSocketServerProtocol): async def send(self, message: Message, websocket: WebSocketServerProtocol):
await websocket.send(message.model_dump_json()) await websocket.send(message.model_dump_json())
@@ -20,14 +31,26 @@ class GameController:
async def broadcast(self, message: Message): async def broadcast(self, message: Message):
await self.server.broadcast(message.model_dump_json()) await self.server.broadcast(message.model_dump_json())
async def broadcast_announce_dict(self, notification_type: str, data: dict): async def broadcast_announce_dict(
await self.broadcast( self,
Message( notification_type: str,
type=notification_type, data: dict,
data_type="object", client_filter: Callable[["ClientController"], Any],
data=data, ):
) messages = []
) for c in self.clients:
if client_filter(c):
messages.append(
c.send(
Message(
type=notification_type,
data_type="object",
data=data,
)
)
)
await asyncio.gather(*messages)
async def announce_dict( async def announce_dict(
self, self,
@@ -75,5 +98,8 @@ class GameController:
async def guest_handler(self, websocket: WebSocketServerProtocol): async def guest_handler(self, websocket: WebSocketServerProtocol):
await self.announce_game(websocket) await self.announce_game(websocket)
def start_game(self): async def start_game(self):
pass await self.game.start_game()
await self.broadcast(
Message(type="context", data_type="game_context_id", data="game")
)
+25
View File
@@ -1,3 +1,4 @@
import asyncio
from typing import List from typing import List
import random import random
from model import ( from model import (
@@ -41,6 +42,8 @@ class Game(Serializable):
self.started = False self.started = False
self.turn: Team = None
async def init_game(self): async def init_game(self):
await self.init_cards() await self.init_cards()
await self.distribute_market_cards() await self.distribute_market_cards()
@@ -163,4 +166,26 @@ class Game(Serializable):
"teams": [team.uuid for team in self.teams], "teams": [team.uuid for team in self.teams],
"started": self.started, "started": self.started,
"default_health": self.default_health, "default_health": self.default_health,
"turn": None if self.turn is None else self.turn.uuid,
} }
async def start_game(self):
self.started = True
self.turn = random.choice(self.teams)
await self.notify_controller("update", self.serialize_guest())
draws = []
for p in [p for p in self.players if p.team == self.turn]:
draws.append(p.draw(3))
for p in [p for p in self.players if p.team != self.turn]:
draws.append(p.draw(5))
await asyncio.gather(*draws)
print(
"start game with "
+ str(len(self.players))
+ " players : "
+ ", ".join([p.username for p in self.players])
)