working on clientController : register POC

This commit is contained in:
2024-03-27 18:43:58 +01:00
parent 85308a8007
commit 34c519345e
8 changed files with 136 additions and 26 deletions
+3
View File
@@ -1,7 +1,10 @@
annotated-types==0.6.0
gevent==24.2.1
greenlet==3.0.3
mypy==1.9.0
mypy-extensions==1.0.0
pydantic==2.6.4
pydantic_core==2.16.3
typing_extensions==4.10.0
websockets==12.0
zope.event==5.0
+4 -1
View File
@@ -1,2 +1,5 @@
from controller.client import Client
"""controller handles the translation between
netcode messages and model functions"""
from controller.game import GameController
from controller.client import ClientController
+77 -3
View File
@@ -1,15 +1,89 @@
from pydantic import ValidationError
from controller import GameController
from websockets.server import WebSocketServerProtocol
from netcode.models import Message, LoginMessage, MessageData
from game import Player
class Client:
def vibe_check(t):
"""Enforces the selected type for the message"""
def decorator(func):
async def new_f(self, message):
try:
message = t.model_validate_json(message)
return await func(self, message)
except ValidationError as e:
await self.send_error(e.errors())
return new_f
return decorator
class ClientController:
websocket: WebSocketServerProtocol
def __init__(self, websocket: WebSocketServerProtocol):
game_controller: GameController
player: Player
def __init__(
self, game_controller: GameController, websocket: WebSocketServerProtocol
):
self.websocket = websocket
self.on_message = self.login_context
self.game_controller = game_controller
async def listen(self):
"""Initializes the client controller"""
await self.send(Message(type="context", data=MessageData(message="login")))
async for message in self.websocket:
await self.on_message(message)
async def on_message(self, message):
async def send(self, message: Message):
await self.websocket.send(message.model_dump_json())
async def send_error(self, error: str):
await self.send(Message(type="error", data=MessageData(message=error)))
@vibe_check(Message)
async def game_context(self, message: Message):
"""Handles messages when the client is logged in"""
print(message)
@vibe_check(LoginMessage)
async def login_context(self, message: LoginMessage):
"""Handles messages when the client isn't logged in"""
if message.type == "register":
username = message.data.username
if len(username) < 3:
await self.send_error("username must be longer than 3 characters")
return
if self.game_controller.get_player(username) is not None:
await self.send_error("username already exists")
return
player = self.game_controller.create_player(username)
elif message.type == "login":
username = message.data.username
player = self.game_controller.get_player(username)
if player is None:
await self.send_error("player doesn't exists")
return
else:
await self.send_error("invalid message type for context")
return
self.player = player
self.on_message = self.game_context
print("user logged in : " + username)
await self.send(Message(type="context", data=MessageData(message="game")))
+14 -1
View File
@@ -1,11 +1,24 @@
from typing import Optional
from netcode import WSServer
from game import Game, Player
class GameController:
server: WSServer
game: Game
def __init__(self, server: WSServer):
def __init__(self, game: Game, server: WSServer):
self.server = server
self.game = game
def get_player(self, username: str) -> Optional[Player]:
players = [p for p in self.game.players if p.username == username]
if players and len(players) > 0:
return players[0]
return None
def create_player(self, username: str) -> Player:
return self.game.create_player(username)
def start_game(self):
pass
+10 -16
View File
@@ -1,8 +1,7 @@
#!/usr/bin/env python
from typing import List, Callable, Coroutine, Any
from typing import List
from game import Card, Team
from controller import GameController
from game import Card, Player, Team
class Game:
@@ -11,28 +10,23 @@ class Game:
market_stack: List[Card]
market: List[Card]
gem_stack: List[Card]
teams: List[Team]
players: List[Player]
started: bool
default_health = 80
controller: GameController
def __init__(self, controller):
def __init__(self):
self.market_stack = []
self.market = []
self.gem_stack = []
self.teams = []
self.players = []
self.started = False
self.controller = controller
def create_team(self):
if self.started:
return False
team = Team(health=self.default_health)
self.teams.append(team)
def start_game(self):
pass
def create_player(self, username: str, team=Team()) -> Player:
player = Player(username, team)
self.players.append(player)
return player
+4 -1
View File
@@ -5,6 +5,8 @@ from game import Card, Team
class Player:
"""Game player, controller by a Client"""
username: str
stack_pile: List[Card]
discard_pile: List[Card]
team: Team
@@ -12,9 +14,10 @@ class Player:
hand: List[Card]
board: List[Card]
def __init__(self, team: Team):
def __init__(self, username: str, team: Team):
self.stack_pile = []
self.discard_pile = []
self.hand = []
self.board = []
self.team = team
self.username = username
+5 -4
View File
@@ -4,17 +4,18 @@ from game import Game
from netcode.ws_server import WebSocketServerProtocol
from netcode import WSServer
from controller import Client, GameController
from controller import ClientController, GameController
gameServer = WSServer()
controller = GameController(gameServer)
hero_game = Game(controller)
hero_game = Game()
game_controller = GameController(hero_game, gameServer)
playerServer = WSServer()
async def handler(websocket: WebSocketServerProtocol):
client = Client(websocket)
client = ClientController(game_controller, websocket)
await client.listen()
+19
View File
@@ -0,0 +1,19 @@
from typing import Optional, Any
from pydantic import BaseModel
class MessageData(BaseModel):
message: Optional[Any] = None
class Message(BaseModel):
type: str
data: MessageData
class LoginData(MessageData):
username: str
class LoginMessage(Message):
data: LoginData