Archived
working on clientController : register POC
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user