Archived
discord login
This commit is contained in:
Vendored
+2
-1
@@ -9,7 +9,8 @@
|
|||||||
"type": "debugpy",
|
"type": "debugpy",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "src/main.py",
|
"program": "src/main.py",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole",
|
||||||
|
"envFile": "${workspaceFolder}/.env"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"mypy-type-checker.reportingScope": "workspace"
|
||||||
|
}
|
||||||
@@ -1,11 +1,18 @@
|
|||||||
annotated-types==0.6.0
|
annotated-types==0.6.0
|
||||||
|
certifi==2024.2.2
|
||||||
|
charset-normalizer==3.3.2
|
||||||
gevent==24.2.1
|
gevent==24.2.1
|
||||||
greenlet==3.0.3
|
greenlet==3.0.3
|
||||||
|
idna==3.7
|
||||||
mypy==1.9.0
|
mypy==1.9.0
|
||||||
mypy-extensions==1.0.0
|
mypy-extensions==1.0.0
|
||||||
pydantic==2.6.4
|
pydantic==2.6.4
|
||||||
pydantic_core==2.16.3
|
pydantic_core==2.16.3
|
||||||
|
requests==2.31.0
|
||||||
|
setuptools==69.5.1
|
||||||
|
types-requests==2.31.0.20240406
|
||||||
typing_extensions==4.10.0
|
typing_extensions==4.10.0
|
||||||
|
urllib3==2.2.1
|
||||||
websockets==12.0
|
websockets==12.0
|
||||||
zope.event==5.0
|
zope.event==5.0
|
||||||
zope.interface==6.2
|
zope.interface==6.2
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import requests
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def discord_process_code(code: str) -> dict | None:
|
||||||
|
response = requests.post(
|
||||||
|
url="https://discord.com/api/oauth2/token",
|
||||||
|
headers={
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
},
|
||||||
|
data={
|
||||||
|
"client_id": os.environ["DISCORD_CLIENTID"],
|
||||||
|
"client_secret": os.environ["DISCORD_CLIENTSECRET"],
|
||||||
|
"code": code,
|
||||||
|
"grant_type": "authorization_code",
|
||||||
|
"redirect_uri": os.environ["FRONTEND_ENDPOINT"] + "/login",
|
||||||
|
"scope": "identify",
|
||||||
|
},
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
json_data = response.json()
|
||||||
|
if "error" in json_data:
|
||||||
|
print(json_data)
|
||||||
|
return None
|
||||||
|
|
||||||
|
token_type = json_data["token_type"]
|
||||||
|
access_token = json_data["access_token"]
|
||||||
|
|
||||||
|
response = requests.get(
|
||||||
|
url="https://discord.com/api/users/@me",
|
||||||
|
headers={
|
||||||
|
"authorization": token_type + " " + access_token,
|
||||||
|
},
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
return response.json()
|
||||||
+127
-69
@@ -4,11 +4,14 @@ from typing import Callable, Any, TYPE_CHECKING
|
|||||||
from pydantic import ValidationError
|
from pydantic import ValidationError
|
||||||
|
|
||||||
from websockets.server import WebSocketServerProtocol
|
from websockets.server import WebSocketServerProtocol
|
||||||
|
from websockets.exceptions import ConnectionClosedOK
|
||||||
|
|
||||||
from netcode.models import Message, LoginMessage
|
from netcode.models import Message, LoginMessage, MessageType
|
||||||
|
|
||||||
from model import Player
|
from model import Player
|
||||||
|
|
||||||
|
from .auth import discord_process_code
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from controller import GameController
|
from controller import GameController
|
||||||
|
|
||||||
@@ -55,7 +58,7 @@ class ClientController:
|
|||||||
"""Hooks the client to the correct listen callbacks"""
|
"""Hooks the client to the correct listen callbacks"""
|
||||||
await self.send(
|
await self.send(
|
||||||
Message(
|
Message(
|
||||||
type="context",
|
type=MessageType.CONTEXT,
|
||||||
data_type="game_context_id",
|
data_type="game_context_id",
|
||||||
data="login",
|
data="login",
|
||||||
)
|
)
|
||||||
@@ -68,15 +71,18 @@ class ClientController:
|
|||||||
|
|
||||||
async def send(self, message: Message) -> None:
|
async def send(self, message: Message) -> None:
|
||||||
"""Send a Message object to the connected client"""
|
"""Send a Message object to the connected client"""
|
||||||
|
try:
|
||||||
await self.websocket.send(message.model_dump_json())
|
await self.websocket.send(message.model_dump_json())
|
||||||
|
except ConnectionClosedOK:
|
||||||
|
print("Connection Closed")
|
||||||
|
|
||||||
async def send_error(self, error: str) -> None:
|
async def send_error(self, error: str) -> None:
|
||||||
"""Send an error string to the connected client"""
|
"""Send an error string to the connected client"""
|
||||||
await self.send(Message(type="error", data_type="error", data=error))
|
await self.send(Message(type=MessageType.ERROR, data_type="error", data=error))
|
||||||
|
|
||||||
async def send_announce_dict(
|
async def send_announce_dict(
|
||||||
self,
|
self,
|
||||||
notification_type: str,
|
notification_type: MessageType,
|
||||||
data: dict,
|
data: dict,
|
||||||
player_filter: Callable[[Player], Any] = lambda x: True,
|
player_filter: Callable[[Player], Any] = lambda x: True,
|
||||||
):
|
):
|
||||||
@@ -89,65 +95,15 @@ class ClientController:
|
|||||||
Message(type=notification_type, data_type="object", data=data)
|
Message(type=notification_type, data_type="object", data=data)
|
||||||
)
|
)
|
||||||
|
|
||||||
@vibe_check(Message)
|
|
||||||
async def game_context(self, message: Message) -> None:
|
|
||||||
"""Handles all messages related to when the current client is logged in
|
|
||||||
and connected to a running game"""
|
|
||||||
|
|
||||||
if message.type == "temp_action":
|
|
||||||
if message.data_type == "set_health":
|
|
||||||
self.player.team.health = message.data
|
|
||||||
return await self.game_controller.game.notify_controller(
|
|
||||||
"update", self.player.team.serialize_guest()
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.player.team != self.game_controller.game.current_turn:
|
|
||||||
return await self.send_error("it is not your turn to play!")
|
|
||||||
if message.type == "action":
|
|
||||||
# TODO : pydantic type check for message.data
|
|
||||||
match message.data_type:
|
|
||||||
case "play_card":
|
|
||||||
return await self.player.play_card(message.data)
|
|
||||||
|
|
||||||
case "discard":
|
|
||||||
return await self.player.turn.discard_card(message.data)
|
|
||||||
|
|
||||||
case "lock_card":
|
|
||||||
return await self.player.turn.lock_card(message.data)
|
|
||||||
|
|
||||||
case "use_effect":
|
|
||||||
return await self.player.turn.use_effect_with_check(
|
|
||||||
message.data.get("effect_id"), message.data.get("target")
|
|
||||||
)
|
|
||||||
|
|
||||||
case "buy":
|
|
||||||
return await self.player.turn.buy_card(message.data)
|
|
||||||
|
|
||||||
case "heal":
|
|
||||||
return await self.player.turn.heal(message.data)
|
|
||||||
|
|
||||||
case "damage_team":
|
|
||||||
return await self.player.turn.damage_team(message.data)
|
|
||||||
|
|
||||||
case "damage_champion":
|
|
||||||
return await self.player.turn.damage_champion(message.data)
|
|
||||||
|
|
||||||
case "end_turn":
|
|
||||||
return await self.player.turn.end_turn()
|
|
||||||
|
|
||||||
return await self.send_error(
|
|
||||||
"Couldn't process action with data_type : " + message.data_type
|
|
||||||
)
|
|
||||||
|
|
||||||
@vibe_check(LoginMessage)
|
@vibe_check(LoginMessage)
|
||||||
async def login_context(self, message: LoginMessage) -> None:
|
async def login_context(self, message: LoginMessage) -> None:
|
||||||
"""Handles all messages related to when the current client isn't yet logged in"""
|
"""Handles all messages related to when the current client isn't yet logged in"""
|
||||||
username = message.data
|
username = message.data
|
||||||
|
if message.type == MessageType.REGISTER:
|
||||||
if self.game_controller.game.started:
|
if self.game_controller.game.started:
|
||||||
return await self.send_error(
|
return await self.send_error(
|
||||||
"you cannot interact with a game that has already started"
|
"you cannot interact with a game that has already started"
|
||||||
)
|
)
|
||||||
if message.type == "register":
|
|
||||||
if len(username) < 3:
|
if len(username) < 3:
|
||||||
return await self.send_error(
|
return await self.send_error(
|
||||||
"username must be longer than 3 characters"
|
"username must be longer than 3 characters"
|
||||||
@@ -157,36 +113,81 @@ class ClientController:
|
|||||||
return await self.send_error("username already exists")
|
return await self.send_error("username already exists")
|
||||||
|
|
||||||
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 == MessageType.LOGIN:
|
||||||
player2 = self.game_controller.game.get_player(username)
|
player2 = self.game_controller.game.get_player(username)
|
||||||
|
|
||||||
if player2 is None:
|
if player2 is None:
|
||||||
return await self.send_error("player doesn't exists")
|
return await self.send_error("player doesn't exists")
|
||||||
|
|
||||||
player = player2
|
player = player2
|
||||||
|
elif message.type == MessageType.DISCORD_LOGIN:
|
||||||
|
user = discord_process_code(message.data)
|
||||||
|
if user is None:
|
||||||
|
await self.send_error("discord login not successful")
|
||||||
|
return
|
||||||
|
username = user["global_name"]
|
||||||
|
player = next(
|
||||||
|
(
|
||||||
|
p
|
||||||
|
for p in self.game_controller.game.players
|
||||||
|
if p.discord_id == user["id"]
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
if player is None:
|
||||||
|
if self.game_controller.game.started:
|
||||||
|
return await self.send_error(
|
||||||
|
"you cannot interact with a game that has already started"
|
||||||
|
)
|
||||||
|
player = await self.game_controller.game.create_player(username)
|
||||||
|
|
||||||
|
player.discord_id = user["id"]
|
||||||
|
player.image = (
|
||||||
|
"https://cdn.discordapp.com/avatars/"
|
||||||
|
+ user["id"]
|
||||||
|
+ "/"
|
||||||
|
+ user["avatar"]
|
||||||
|
+ ".webp"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return await self.send_error("invalid message type for context")
|
return await self.send_error("invalid message type for context")
|
||||||
|
|
||||||
self.player = player
|
self.player = player
|
||||||
self.player.team.listeners.append(self.send_announce_dict)
|
self.player.team.listeners.append(self.send_announce_dict)
|
||||||
|
if self.game_controller.game.started:
|
||||||
|
self.on_message = self.game_context
|
||||||
|
await self.send(
|
||||||
|
Message(
|
||||||
|
type=MessageType.CONTEXT, data_type="game_context_id", data="game"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for p in self.game_controller.game.players:
|
||||||
|
if p.team == player.team:
|
||||||
|
await self.send(
|
||||||
|
Message(
|
||||||
|
type=MessageType.UPDATE,
|
||||||
|
data_type="object",
|
||||||
|
data=player.serialize_team(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
self.on_message = self.pregame_context
|
self.on_message = self.pregame_context
|
||||||
|
await self.send(
|
||||||
|
Message(
|
||||||
|
type=MessageType.CONTEXT,
|
||||||
|
data_type="game_context_id",
|
||||||
|
data="pregame",
|
||||||
|
)
|
||||||
|
)
|
||||||
print("user logged in : " + username)
|
print("user logged in : " + username)
|
||||||
|
|
||||||
await self.send(
|
await self.send(
|
||||||
Message(
|
Message(
|
||||||
type="set",
|
type=MessageType.SET,
|
||||||
data_type="self",
|
data_type="self",
|
||||||
data=self.player.uuid,
|
data=self.player.uuid,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await self.send(
|
|
||||||
Message(
|
|
||||||
type="context",
|
|
||||||
data_type="game_context_id",
|
|
||||||
data="pregame",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
@vibe_check(Message)
|
@vibe_check(Message)
|
||||||
async def pregame_context(self, message: Message) -> None:
|
async def pregame_context(self, message: Message) -> None:
|
||||||
@@ -197,9 +198,66 @@ class ClientController:
|
|||||||
if all(p.ready for p in self.game_controller.game.players):
|
if all(p.ready for p in self.game_controller.game.players):
|
||||||
await self.game_controller.start_game()
|
await self.game_controller.start_game()
|
||||||
|
|
||||||
elif message.type == "temp_action":
|
@vibe_check(Message)
|
||||||
if message.data_type == "set_health":
|
async def game_context(self, message: Message) -> None:
|
||||||
self.player.team.health = message.data
|
"""Handles all messages related to when the current client is logged in
|
||||||
await self.game_controller.game.notify_controller(
|
and connected to a running game"""
|
||||||
"update", self.player.team.serialize_guest()
|
|
||||||
|
# if message.type == "temp_action":
|
||||||
|
# if message.data_type == "set_health":
|
||||||
|
# self.player.team.health = message.data
|
||||||
|
# return await self.game_controller.game.notify_controller(
|
||||||
|
# "update", self.player.team.serialize_guest()
|
||||||
|
# )
|
||||||
|
|
||||||
|
if self.player.team != self.game_controller.game.current_turn:
|
||||||
|
return await self.send_error("it is not your turn to play!")
|
||||||
|
if message.type == "action":
|
||||||
|
# TODO : pydantic type check for message.data
|
||||||
|
match message.data_type:
|
||||||
|
case "play_card":
|
||||||
|
if not isinstance(message.data, str):
|
||||||
|
return
|
||||||
|
return await self.player.play_card(message.data)
|
||||||
|
|
||||||
|
case "discard":
|
||||||
|
if not isinstance(message.data, str):
|
||||||
|
return
|
||||||
|
return await self.player.turn.discard_card(message.data)
|
||||||
|
|
||||||
|
case "lock_card":
|
||||||
|
if not isinstance(message.data, str):
|
||||||
|
return
|
||||||
|
return await self.player.turn.lock_card(message.data)
|
||||||
|
|
||||||
|
case "use_effect":
|
||||||
|
return await self.player.turn.use_effect_with_check(
|
||||||
|
message.data.get("effect_id"), message.data.get("target")
|
||||||
|
)
|
||||||
|
|
||||||
|
case "buy":
|
||||||
|
if not isinstance(message.data, str):
|
||||||
|
return
|
||||||
|
return await self.player.turn.buy_card(message.data)
|
||||||
|
|
||||||
|
case "heal":
|
||||||
|
if not isinstance(message.data, int):
|
||||||
|
return
|
||||||
|
return await self.player.turn.heal(message.data)
|
||||||
|
|
||||||
|
case "damage_team":
|
||||||
|
if not isinstance(message.data, str):
|
||||||
|
return
|
||||||
|
return await self.player.turn.damage_team(message.data)
|
||||||
|
|
||||||
|
case "damage_champion":
|
||||||
|
if not isinstance(message.data, str):
|
||||||
|
return
|
||||||
|
return await self.player.turn.damage_champion(message.data)
|
||||||
|
|
||||||
|
case "end_turn":
|
||||||
|
return await self.player.turn.end_turn()
|
||||||
|
|
||||||
|
return await self.send_error(
|
||||||
|
"Couldn't process action with data_type : " + message.data_type
|
||||||
)
|
)
|
||||||
|
|||||||
+14
-10
@@ -1,8 +1,9 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from typing import Callable, List, Any
|
from typing import Callable, List, Any
|
||||||
|
from websockets.exceptions import ConnectionClosedOK
|
||||||
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, MessageType
|
||||||
from model import Game, Player
|
from model import Game, Player
|
||||||
from controller import (
|
from controller import (
|
||||||
ClientController,
|
ClientController,
|
||||||
@@ -31,14 +32,17 @@ class GameController:
|
|||||||
self.clients.remove(client)
|
self.clients.remove(client)
|
||||||
|
|
||||||
async def send(self, message: Message, websocket: WebSocketServerProtocol):
|
async def send(self, message: Message, websocket: WebSocketServerProtocol):
|
||||||
|
try:
|
||||||
await websocket.send(message.model_dump_json())
|
await websocket.send(message.model_dump_json())
|
||||||
|
except ConnectionClosedOK:
|
||||||
|
print("Connection Closed")
|
||||||
|
|
||||||
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(
|
async def broadcast_announce_dict(
|
||||||
self,
|
self,
|
||||||
notification_type: str,
|
notification_type: MessageType,
|
||||||
data: dict,
|
data: dict,
|
||||||
player_filter: Callable[[Player], Any],
|
player_filter: Callable[[Player], Any],
|
||||||
):
|
):
|
||||||
@@ -58,7 +62,7 @@ class GameController:
|
|||||||
|
|
||||||
async def announce_dict(
|
async def announce_dict(
|
||||||
self,
|
self,
|
||||||
notification_type: str,
|
notification_type: MessageType,
|
||||||
data: dict,
|
data: dict,
|
||||||
websocket: WebSocketServerProtocol,
|
websocket: WebSocketServerProtocol,
|
||||||
):
|
):
|
||||||
@@ -74,39 +78,39 @@ class GameController:
|
|||||||
async def announce_game(self, websocket: WebSocketServerProtocol):
|
async def announce_game(self, websocket: WebSocketServerProtocol):
|
||||||
for effect in self.game.effects:
|
for effect in self.game.effects:
|
||||||
await self.announce_dict(
|
await self.announce_dict(
|
||||||
"create",
|
MessageType.CREATE,
|
||||||
effect.serialize(),
|
effect.serialize(),
|
||||||
websocket,
|
websocket,
|
||||||
)
|
)
|
||||||
|
|
||||||
for card in self.game.cards:
|
for card in self.game.cards:
|
||||||
await self.announce_dict(
|
await self.announce_dict(
|
||||||
"create",
|
MessageType.CREATE,
|
||||||
card.serialize(),
|
card.serialize(),
|
||||||
websocket,
|
websocket,
|
||||||
)
|
)
|
||||||
|
|
||||||
for team in self.game.teams:
|
for team in self.game.teams:
|
||||||
await self.announce_dict(
|
await self.announce_dict(
|
||||||
"create",
|
MessageType.CREATE,
|
||||||
team.serialize(),
|
team.serialize(),
|
||||||
websocket,
|
websocket,
|
||||||
)
|
)
|
||||||
|
|
||||||
for player in self.game.players:
|
for player in self.game.players:
|
||||||
await self.announce_dict(
|
await self.announce_dict(
|
||||||
"create",
|
MessageType.CREATE,
|
||||||
player.turn.serialize(),
|
player.turn.serialize(),
|
||||||
websocket,
|
websocket,
|
||||||
)
|
)
|
||||||
await self.announce_dict(
|
await self.announce_dict(
|
||||||
"create",
|
MessageType.CREATE,
|
||||||
player.serialize_guest(),
|
player.serialize_guest(),
|
||||||
websocket,
|
websocket,
|
||||||
)
|
)
|
||||||
|
|
||||||
await self.announce_dict(
|
await self.announce_dict(
|
||||||
"create",
|
MessageType.CREATE,
|
||||||
self.game.serialize_guest(),
|
self.game.serialize_guest(),
|
||||||
websocket,
|
websocket,
|
||||||
)
|
)
|
||||||
@@ -119,5 +123,5 @@ class GameController:
|
|||||||
for c in self.clients:
|
for c in self.clients:
|
||||||
c.on_message = c.game_context
|
c.on_message = c.game_context
|
||||||
await self.broadcast(
|
await self.broadcast(
|
||||||
Message(type="context", data_type="game_context_id", data="game")
|
Message(type=MessageType.CONTEXT, data_type="game_context_id", data="game")
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
from typing import List, Optional, Callable, TYPE_CHECKING, Union
|
from typing import List, Optional, Callable, TYPE_CHECKING, Union, Awaitable, Any
|
||||||
from model import Serializable, CardRole, CardType, CardFaction
|
from model import Serializable, CardRole, CardType, CardFaction
|
||||||
from model.card_validator import CardEffects, EffectType, EffectTimes
|
from model.card_validator import CardEffects, EffectType, EffectTimes
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@ class Effect(Serializable):
|
|||||||
effect_type: Optional[EffectType] = None
|
effect_type: Optional[EffectType] = None
|
||||||
times: Optional[EffectTimes] = None
|
times: Optional[EffectTimes] = None
|
||||||
card: "Card"
|
card: "Card"
|
||||||
activate: Callable[["Turn"], Union["Player", "Card"]]
|
activate: Callable[["Turn", str | None], Awaitable[Any]]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
effect: CardEffects,
|
effect: CardEffects,
|
||||||
amount: int,
|
amount: int,
|
||||||
activate: Callable[["Turn"], Union["Player", "Card"]],
|
activate: Callable[["Turn", str | None], Awaitable[Any]],
|
||||||
sub_effects: Optional[List["Effect"]] = None,
|
sub_effects: Optional[List["Effect"]] = None,
|
||||||
effect_type: Optional[EffectType] = None,
|
effect_type: Optional[EffectType] = None,
|
||||||
times: Optional[EffectTimes] = None,
|
times: Optional[EffectTimes] = None,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import TYPE_CHECKING, Awaitable, Optional
|
from typing import TYPE_CHECKING, Optional, Callable, Coroutine, Any
|
||||||
from model.card_validator import EffectParser
|
from model.card_validator import EffectParser
|
||||||
from model.card import Effect, EffectType, CardEffects, EffectTimes, CardType
|
from model.card import Effect, EffectType, CardEffects, EffectTimes, CardType
|
||||||
|
|
||||||
@@ -6,6 +6,8 @@ from model.card import Effect, EffectType, CardEffects, EffectTimes, CardType
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from model import Turn
|
from model import Turn
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument,missing-function-docstring
|
||||||
|
|
||||||
|
|
||||||
# Effect Types
|
# Effect Types
|
||||||
async def effect_type_suicide(effect: Effect, turn: "Turn"):
|
async def effect_type_suicide(effect: Effect, turn: "Turn"):
|
||||||
@@ -55,19 +57,20 @@ async def effect_heal(effect: Effect, turn: "Turn", _target: str):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def effect_prepare(_effect: Effect, turn: "Turn", target: str):
|
async def effect_prepare(effect: Effect, turn: "Turn", target: str):
|
||||||
|
|
||||||
return turn.prepare(target)
|
return turn.prepare(target)
|
||||||
|
|
||||||
|
|
||||||
async def effect_stun(_effect: Effect, turn: "Turn", target: str):
|
async def effect_stun(effect: Effect, turn: "Turn", target: str):
|
||||||
return await turn.player.stun(target)
|
return await turn.player.stun(target)
|
||||||
|
|
||||||
|
|
||||||
async def effect_sacrifice(_effect: Effect, turn: "Turn", target: str):
|
async def effect_sacrifice(effect: Effect, turn: "Turn", target: str):
|
||||||
return await turn.sacrifice_card(target)
|
return await turn.sacrifice_card(target)
|
||||||
|
|
||||||
|
|
||||||
async def effect_draw(_effect: Effect, turn: "Turn", _target: str):
|
async def effect_draw(effect: Effect, turn: "Turn", _target: str):
|
||||||
return await turn.player.draw_and_play(1)
|
return await turn.player.draw_and_play(1)
|
||||||
|
|
||||||
|
|
||||||
@@ -169,9 +172,11 @@ effect_times_all_behaviours = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def create_effect_behaviour(effect: EffectParser) -> Awaitable[None]:
|
def create_effect_behaviour(
|
||||||
|
effect: EffectParser,
|
||||||
|
) -> Callable[[Effect, "Turn", str | None], Coroutine[Any, Any, Any]]:
|
||||||
|
|
||||||
async def effect_type_behaviour(e: Effect, t: "Turn"):
|
async def effect_type_behaviour(effect: Effect, turn: "Turn"):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if effect.effect_type in effect_types_all_behaviours:
|
if effect.effect_type in effect_types_all_behaviours:
|
||||||
@@ -182,7 +187,7 @@ def create_effect_behaviour(effect: EffectParser) -> Awaitable[None]:
|
|||||||
|
|
||||||
card_effect_behaviour = card_effect_all_behaviours[effect.effect]
|
card_effect_behaviour = card_effect_all_behaviours[effect.effect]
|
||||||
|
|
||||||
def effect_times_behaviour(_e: Effect, _t: "Turn"):
|
def effect_times_behaviour(effect: Effect, turn: "Turn"):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
if effect.times in effect_times_all_behaviours:
|
if effect.times in effect_times_all_behaviours:
|
||||||
@@ -194,7 +199,7 @@ def create_effect_behaviour(effect: EffectParser) -> Awaitable[None]:
|
|||||||
return False
|
return False
|
||||||
times = effect_times_behaviour(self, turn)
|
times = effect_times_behaviour(self, turn)
|
||||||
for _ in range(times):
|
for _ in range(times):
|
||||||
effect_result = await card_effect_behaviour(self, turn, target)
|
effect_result = await card_effect_behaviour(self, turn, (target or ""))
|
||||||
if not effect_result:
|
if not effect_result:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from json import JSONDecodeError
|
from json import JSONDecodeError
|
||||||
from typing import List, Dict, Optional
|
from typing import List, Dict, Optional, TYPE_CHECKING, Union
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pydantic import BaseModel, ValidationError
|
from pydantic import BaseModel, ValidationError
|
||||||
|
|
||||||
@@ -8,6 +8,9 @@ from model.card_validator import CardParser, EffectParser
|
|||||||
from model.card import Effect, Card
|
from model.card import Effect, Card
|
||||||
from .card_behaviour import create_effect_behaviour
|
from .card_behaviour import create_effect_behaviour
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from model import Turn, Player
|
||||||
|
|
||||||
|
|
||||||
class CardContainerFile(BaseModel):
|
class CardContainerFile(BaseModel):
|
||||||
cards: List[CardParser]
|
cards: List[CardParser]
|
||||||
@@ -29,7 +32,7 @@ def load_cards() -> List[CardParser]:
|
|||||||
return cards
|
return cards
|
||||||
|
|
||||||
|
|
||||||
def create_card(card_parser: CardParser) -> tuple[Card, list[Effect], list[Effect]]:
|
def create_card(card_parser: CardParser) -> tuple[Card, list[Effect]]:
|
||||||
card_effects, all_effects = create_card_effects(card_parser)
|
card_effects, all_effects = create_card_effects(card_parser)
|
||||||
card = Card(
|
card = Card(
|
||||||
card_id=card_parser.id,
|
card_id=card_parser.id,
|
||||||
@@ -50,9 +53,14 @@ def create_card(card_parser: CardParser) -> tuple[Card, list[Effect], list[Effec
|
|||||||
|
|
||||||
def create_card_effects(
|
def create_card_effects(
|
||||||
card: CardParser, all_effects: Optional[List[Effect]] = None
|
card: CardParser, all_effects: Optional[List[Effect]] = None
|
||||||
) -> (List[Effect], List[Effect]):
|
) -> tuple[List[Effect], List[Effect]]:
|
||||||
|
|
||||||
if all_effects is None:
|
if all_effects is None:
|
||||||
all_effects: List[Effect] = []
|
all_effects = []
|
||||||
|
|
||||||
|
if all_effects is None:
|
||||||
|
raise RuntimeError("shut up MyPy")
|
||||||
|
|
||||||
combined: List[Effect] = []
|
combined: List[Effect] = []
|
||||||
mutexes: Dict[int, List[Effect]] = {}
|
mutexes: Dict[int, List[Effect]] = {}
|
||||||
for mutex in set([c.mutex for c in card.effects if c.mutex is not None]):
|
for mutex in set([c.mutex for c in card.effects if c.mutex is not None]):
|
||||||
@@ -76,9 +84,13 @@ def create_card_effects(
|
|||||||
|
|
||||||
def create_effect_and_subeffects(
|
def create_effect_and_subeffects(
|
||||||
effect: EffectParser, all_effects: Optional[List[Effect]] = None
|
effect: EffectParser, all_effects: Optional[List[Effect]] = None
|
||||||
) -> (Effect, List[Effect]):
|
) -> tuple[Effect, List[Effect]]:
|
||||||
|
|
||||||
if all_effects is None:
|
if all_effects is None:
|
||||||
all_effects: List[Effect] = []
|
all_effects = []
|
||||||
|
if all_effects is None:
|
||||||
|
raise RuntimeError("shut up MyPy")
|
||||||
|
|
||||||
sub_effects: List[Effect] = []
|
sub_effects: List[Effect] = []
|
||||||
mutexes: Dict[int, List[Effect]] = {}
|
mutexes: Dict[int, List[Effect]] = {}
|
||||||
for mutex in set([c.mutex for c in effect.sub_effects if c.mutex is not None]):
|
for mutex in set([c.mutex for c in effect.sub_effects if c.mutex is not None]):
|
||||||
@@ -97,15 +109,16 @@ def create_effect_and_subeffects(
|
|||||||
if s.mutex in mutexes:
|
if s.mutex in mutexes:
|
||||||
sub_effects[index].mutex = mutexes[s.mutex]
|
sub_effects[index].mutex = mutexes[s.mutex]
|
||||||
|
|
||||||
|
def activate(turn: "Turn", target: str | None):
|
||||||
|
return create_effect_behaviour(effect=effect)(actual_effect, turn, target)
|
||||||
|
|
||||||
actual_effect = Effect(
|
actual_effect = Effect(
|
||||||
effect=effect.effect,
|
effect=effect.effect,
|
||||||
amount=effect.amount,
|
amount=effect.amount,
|
||||||
effect_type=effect.effect_type,
|
effect_type=effect.effect_type,
|
||||||
sub_effects=sub_effects,
|
sub_effects=sub_effects,
|
||||||
times=effect.times,
|
times=effect.times,
|
||||||
activate=lambda *args, **kwargs: create_effect_behaviour(effect=effect)(
|
activate=activate,
|
||||||
actual_effect, *args, **kwargs
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return actual_effect, all_effects
|
return actual_effect, all_effects
|
||||||
|
|||||||
+11
-9
@@ -7,6 +7,8 @@ from model import Card, CardRole, CardParser, Player, Team, Serializable, Effect
|
|||||||
|
|
||||||
from model.card_loader import load_cards, create_card_effects, create_card
|
from model.card_loader import load_cards, create_card_effects, create_card
|
||||||
|
|
||||||
|
from netcode.models import MessageType
|
||||||
|
|
||||||
|
|
||||||
class Game(Serializable):
|
class Game(Serializable):
|
||||||
"""Instance of the game, with players and a market"""
|
"""Instance of the game, with players and a market"""
|
||||||
@@ -17,7 +19,7 @@ class Game(Serializable):
|
|||||||
cards: List[Card]
|
cards: List[Card]
|
||||||
effects: List[Effect]
|
effects: List[Effect]
|
||||||
market_stack: List[Card]
|
market_stack: List[Card]
|
||||||
market: List[Card]
|
market: List[Card | None]
|
||||||
gem_stack: List[Card]
|
gem_stack: List[Card]
|
||||||
players: List[Player]
|
players: List[Player]
|
||||||
teams: List[Team]
|
teams: List[Team]
|
||||||
@@ -26,7 +28,7 @@ class Game(Serializable):
|
|||||||
|
|
||||||
default_health = 50
|
default_health = 50
|
||||||
|
|
||||||
current_turn: Team
|
current_turn: Team | None
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -50,10 +52,10 @@ class Game(Serializable):
|
|||||||
card, all_effects = create_card(card_parser)
|
card, all_effects = create_card(card_parser)
|
||||||
for e in all_effects:
|
for e in all_effects:
|
||||||
self.effects.append(e)
|
self.effects.append(e)
|
||||||
await self.notify_controller("create", e.serialize())
|
await self.notify_controller(MessageType.CREATE, e.serialize())
|
||||||
|
|
||||||
self.cards.append(card)
|
self.cards.append(card)
|
||||||
await self.notify_controller("create", card.serialize())
|
await self.notify_controller(MessageType.CREATE, card.serialize())
|
||||||
return card
|
return card
|
||||||
|
|
||||||
async def init_cards(self):
|
async def init_cards(self):
|
||||||
@@ -91,15 +93,15 @@ class Game(Serializable):
|
|||||||
self.players.append(player)
|
self.players.append(player)
|
||||||
|
|
||||||
player.stack_pile = await self.create_base_deck("base")
|
player.stack_pile = await self.create_base_deck("base")
|
||||||
await self.notify_controller("create", player.turn.serialize())
|
await self.notify_controller(MessageType.CREATE, player.turn.serialize())
|
||||||
await self.notify_controller("create", player.serialize_guest())
|
await self.notify_controller(MessageType.CREATE, player.serialize_guest())
|
||||||
await self.notify_controller("update", self.serialize_guest())
|
await self.notify_controller(MessageType.UPDATE, self.serialize_guest())
|
||||||
return player
|
return player
|
||||||
|
|
||||||
async def create_team(self) -> Team:
|
async def create_team(self) -> Team:
|
||||||
team = Team(health=self.default_health)
|
team = Team(health=self.default_health)
|
||||||
self.teams.append(team)
|
self.teams.append(team)
|
||||||
await self.notify_controller("create", team.serialize_guest())
|
await self.notify_controller(MessageType.CREATE, team.serialize_guest())
|
||||||
|
|
||||||
return team
|
return team
|
||||||
|
|
||||||
@@ -169,7 +171,7 @@ class Game(Serializable):
|
|||||||
await p.start_turn()
|
await p.start_turn()
|
||||||
await self.notify_controller("update", self.serialize_guest())
|
await self.notify_controller("update", self.serialize_guest())
|
||||||
|
|
||||||
def search_card_in_pile(self, card_id: str, pile: List[Card]):
|
def search_card_in_pile(self, card_id: str, pile: list[Card | None] | list[Card]):
|
||||||
return next(
|
return next(
|
||||||
(m for m in [f for f in pile if f is not None] if str(m.uuid) == card_id),
|
(m for m in [f for f in pile if f is not None] if str(m.uuid) == card_id),
|
||||||
None,
|
None,
|
||||||
|
|||||||
+19
-7
@@ -6,6 +6,8 @@ from typing import List, Optional, TYPE_CHECKING
|
|||||||
|
|
||||||
from model import Card, Team, Serializable, Turn, CardType, CardRole
|
from model import Card, Team, Serializable, Turn, CardType, CardRole
|
||||||
|
|
||||||
|
from netcode.models import MessageType
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from model import Game
|
from model import Game
|
||||||
|
|
||||||
@@ -15,6 +17,8 @@ class Player(Serializable):
|
|||||||
|
|
||||||
object_type = "player"
|
object_type = "player"
|
||||||
username: str
|
username: str
|
||||||
|
image: Optional[str] = None
|
||||||
|
discord_id: Optional[int] = None
|
||||||
|
|
||||||
stack_pile: List[Card]
|
stack_pile: List[Card]
|
||||||
discard_pile: List[Card]
|
discard_pile: List[Card]
|
||||||
@@ -110,7 +114,7 @@ class Player(Serializable):
|
|||||||
|
|
||||||
await asyncio.gather(*notifies)
|
await asyncio.gather(*notifies)
|
||||||
|
|
||||||
def source_card(self, card_id: str, source: List[Card]) -> Card:
|
def source_card(self, card_id: str, source: List[Card]) -> Card | None:
|
||||||
card = self.game.search_card_in_pile(card_id, source)
|
card = self.game.search_card_in_pile(card_id, source)
|
||||||
if card is None:
|
if card is None:
|
||||||
return None
|
return None
|
||||||
@@ -184,7 +188,9 @@ class Player(Serializable):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.discard_pile.append(card)
|
self.discard_pile.append(card)
|
||||||
await self.game.notify_controller("update", self.game.serialize_guest())
|
await self.game.notify_controller(
|
||||||
|
MessageType.UPDATE, self.game.serialize_guest()
|
||||||
|
)
|
||||||
await self.notify_update()
|
await self.notify_update()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -199,7 +205,9 @@ class Player(Serializable):
|
|||||||
if card.card_role == CardRole.FIRE_GEM:
|
if card.card_role == CardRole.FIRE_GEM:
|
||||||
self.game.gem_stack.append(card)
|
self.game.gem_stack.append(card)
|
||||||
await self.notify_update()
|
await self.notify_update()
|
||||||
await self.game.notify_controller("update", self.game.serialize_guest())
|
await self.game.notify_controller(
|
||||||
|
MessageType.UPDATE, self.game.serialize_guest()
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def play_from_discard(self, card_id: str):
|
async def play_from_discard(self, card_id: str):
|
||||||
@@ -220,7 +228,7 @@ class Player(Serializable):
|
|||||||
self.stack_pile.append(card)
|
self.stack_pile.append(card)
|
||||||
else:
|
else:
|
||||||
print("Card not found in discard pile")
|
print("Card not found in discard pile")
|
||||||
return
|
return False
|
||||||
|
|
||||||
await self.notify_update()
|
await self.notify_update()
|
||||||
return True
|
return True
|
||||||
@@ -237,7 +245,9 @@ class Player(Serializable):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.board.append(card)
|
self.board.append(card)
|
||||||
await self.game.notify_controller("update", self.game.serialize_guest())
|
await self.game.notify_controller(
|
||||||
|
MessageType.UPDATE, self.game.serialize_guest()
|
||||||
|
)
|
||||||
await self.notify_update()
|
await self.notify_update()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -253,7 +263,9 @@ class Player(Serializable):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.stack_pile.append(card)
|
self.stack_pile.append(card)
|
||||||
await self.game.notify_controller("update", self.game.serialize_guest())
|
await self.game.notify_controller(
|
||||||
|
MessageType.UPDATE, self.game.serialize_guest()
|
||||||
|
)
|
||||||
await self.notify_update()
|
await self.notify_update()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -286,5 +298,5 @@ class Player(Serializable):
|
|||||||
print("player has already too many discard markers!")
|
print("player has already too many discard markers!")
|
||||||
return False
|
return False
|
||||||
p.turn.fuck_u_markers += 1
|
p.turn.fuck_u_markers += 1
|
||||||
await self.game.notify_controller("update", p.turn.serialize())
|
await self.game.notify_controller(MessageType.UPDATE, p.turn.serialize())
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
from typing import List, Callable, Awaitable, Any
|
from typing import List, Callable, Awaitable, Any
|
||||||
from uuid import uuid4, UUID
|
from uuid import uuid4, UUID
|
||||||
|
|
||||||
|
from netcode.models import MessageType
|
||||||
|
|
||||||
|
|
||||||
class Serializable:
|
class Serializable:
|
||||||
object_type = "serializable"
|
object_type = "serializable"
|
||||||
|
|
||||||
uuid: UUID
|
uuid: UUID
|
||||||
|
|
||||||
listeners: List[Callable[[str, dict, Callable], Awaitable[Any]]]
|
listeners: List[Callable[[MessageType, dict, Callable], Awaitable[Any]]]
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.uuid = uuid4()
|
self.uuid = uuid4()
|
||||||
@@ -24,7 +26,7 @@ class Serializable:
|
|||||||
|
|
||||||
async def notify_controller(
|
async def notify_controller(
|
||||||
self,
|
self,
|
||||||
notification_type: str,
|
notification_type: MessageType,
|
||||||
game_object: dict,
|
game_object: dict,
|
||||||
# TODO : Player interface to typing
|
# TODO : Player interface to typing
|
||||||
player_filter: Callable[[Any], bool] = lambda _: True,
|
player_filter: Callable[[Any], bool] = lambda _: True,
|
||||||
|
|||||||
+20
-11
@@ -13,6 +13,7 @@ from model import (
|
|||||||
Team,
|
Team,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from netcode.models import MessageType
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from model import Player
|
from model import Player
|
||||||
@@ -64,9 +65,9 @@ class Turn(Serializable):
|
|||||||
for p in self.player.game.players:
|
for p in self.player.game.players:
|
||||||
p.turn.champions_health = {}
|
p.turn.champions_health = {}
|
||||||
for c in p.board:
|
for c in p.board:
|
||||||
if c.card_type == CardType.CHAMPION:
|
if c.card_type == CardType.CHAMPION and c.defense is not None:
|
||||||
p.turn.champions_health[str(c.uuid)] = c.defense
|
p.turn.champions_health[str(c.uuid)] = c.defense
|
||||||
await p.game.notify_controller("update", p.turn.serialize())
|
await p.game.notify_controller(MessageType.UPDATE, p.turn.serialize())
|
||||||
|
|
||||||
await self.player.end_turn()
|
await self.player.end_turn()
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ class Turn(Serializable):
|
|||||||
for _ in range(effect.amount):
|
for _ in range(effect.amount):
|
||||||
self.effects_availables.append(effect)
|
self.effects_availables.append(effect)
|
||||||
|
|
||||||
await self.player.game.notify_controller("update", self.serialize())
|
await self.player.game.notify_controller(MessageType.UPDATE, self.serialize())
|
||||||
|
|
||||||
async def discard_card(self, card_id: str):
|
async def discard_card(self, card_id: str):
|
||||||
card = self.player.game.search_card_in_pile(card_id, self.cards_locked)
|
card = self.player.game.search_card_in_pile(card_id, self.cards_locked)
|
||||||
@@ -113,7 +114,7 @@ class Turn(Serializable):
|
|||||||
return print("you don't have any discard or fuck_u markers")
|
return print("you don't have any discard or fuck_u markers")
|
||||||
|
|
||||||
await self.player.discard_card(card_id)
|
await self.player.discard_card(card_id)
|
||||||
await self.player.game.notify_controller("update", self.serialize())
|
await self.player.game.notify_controller(MessageType.UPDATE, self.serialize())
|
||||||
|
|
||||||
def sacrifice_card(self, card_id: str):
|
def sacrifice_card(self, card_id: str):
|
||||||
card = self.player.game.search_card_in_pile(card_id, self.cards_locked)
|
card = self.player.game.search_card_in_pile(card_id, self.cards_locked)
|
||||||
@@ -168,7 +169,7 @@ class Turn(Serializable):
|
|||||||
else:
|
else:
|
||||||
for _ in range(e.amount):
|
for _ in range(e.amount):
|
||||||
self.effects_availables.append(e)
|
self.effects_availables.append(e)
|
||||||
await self.player.game.notify_controller("update", self.serialize())
|
await self.player.game.notify_controller(MessageType.UPDATE, self.serialize())
|
||||||
|
|
||||||
def prepare(self, card_id: str) -> bool:
|
def prepare(self, card_id: str) -> bool:
|
||||||
card = next(
|
card = next(
|
||||||
@@ -243,14 +244,18 @@ class Turn(Serializable):
|
|||||||
|
|
||||||
if await buy_function(card):
|
if await buy_function(card):
|
||||||
self.gold_reserve -= card.cost
|
self.gold_reserve -= card.cost
|
||||||
await self.player.game.notify_controller("update", self.serialize())
|
await self.player.game.notify_controller(
|
||||||
|
MessageType.UPDATE, self.serialize()
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def heal(self, amount: int):
|
async def heal(self, amount: int):
|
||||||
self.player.team.health += amount
|
self.player.team.health += amount
|
||||||
await self.player.game.notify_controller("update", self.player.team.serialize())
|
await self.player.game.notify_controller(
|
||||||
|
MessageType.UPDATE, self.player.team.serialize()
|
||||||
|
)
|
||||||
|
|
||||||
def check_for_guard(self, team: "Team"):
|
def check_for_guard(self, team: "Team"):
|
||||||
for p in self.player.game.players:
|
for p in self.player.game.players:
|
||||||
@@ -277,8 +282,8 @@ class Turn(Serializable):
|
|||||||
self.damage_reserve -= 1
|
self.damage_reserve -= 1
|
||||||
team.health -= 1
|
team.health -= 1
|
||||||
|
|
||||||
await self.player.game.notify_controller("update", self.serialize())
|
await self.player.game.notify_controller(MessageType.UPDATE, self.serialize())
|
||||||
await self.player.game.notify_controller("update", team.serialize())
|
await self.player.game.notify_controller(MessageType.UPDATE, team.serialize())
|
||||||
|
|
||||||
async def damage_champion(self, target: str):
|
async def damage_champion(self, target: str):
|
||||||
if self.damage_reserve <= 0:
|
if self.damage_reserve <= 0:
|
||||||
@@ -301,8 +306,12 @@ class Turn(Serializable):
|
|||||||
self.damage_reserve -= p.turn.champions_health[str(c.uuid)]
|
self.damage_reserve -= p.turn.champions_health[str(c.uuid)]
|
||||||
await self.player.stun(str(c.uuid))
|
await self.player.stun(str(c.uuid))
|
||||||
|
|
||||||
await self.player.game.notify_controller("update", self.serialize())
|
await self.player.game.notify_controller(
|
||||||
await self.player.game.notify_controller("update", p.turn.serialize())
|
MessageType.UPDATE, self.serialize()
|
||||||
|
)
|
||||||
|
await self.player.game.notify_controller(
|
||||||
|
MessageType.UPDATE, p.turn.serialize()
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
print("card not found")
|
print("card not found")
|
||||||
|
|||||||
+24
-2
@@ -1,9 +1,31 @@
|
|||||||
from typing import Any
|
from enum import Enum
|
||||||
|
from typing import Any, Literal
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class MessageType(str, Enum):
|
||||||
|
ACTION = "action"
|
||||||
|
REGISTER = "register"
|
||||||
|
LOGIN = "login"
|
||||||
|
READY = "ready"
|
||||||
|
DISCORD_LOGIN = "discord_login"
|
||||||
|
|
||||||
|
CONTEXT = "context"
|
||||||
|
CREATE = "create"
|
||||||
|
ERROR = "error"
|
||||||
|
UPDATE = "update"
|
||||||
|
SET = "set"
|
||||||
|
|
||||||
|
|
||||||
|
class CreateMessageType(BaseModel):
|
||||||
|
type: Literal[MessageType.CREATE]
|
||||||
|
data_type: "object"
|
||||||
|
data: dict
|
||||||
|
|
||||||
|
|
||||||
class Message(BaseModel):
|
class Message(BaseModel):
|
||||||
type: str
|
type: MessageType
|
||||||
data: Any | str | int | None = None
|
data: Any | str | int | None = None
|
||||||
data_type: str
|
data_type: str
|
||||||
|
|
||||||
|
|||||||
@@ -9,20 +9,21 @@ class WSServer:
|
|||||||
|
|
||||||
connections: Set[WebSocketServerProtocol]
|
connections: Set[WebSocketServerProtocol]
|
||||||
on_new_connection_callback: Callable[
|
on_new_connection_callback: Callable[
|
||||||
[WebSocketServerProtocol, Callable[[Any], Awaitable[None]]], Awaitable[None]
|
[WebSocketServerProtocol, Callable[[], Any]], Awaitable[None]
|
||||||
]
|
]
|
||||||
|
|
||||||
port: int
|
port: int
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.connections = set()
|
self.connections = set()
|
||||||
self.message_callbacks = []
|
self.message_callbacks: list[Callable] = []
|
||||||
|
|
||||||
async def handler(self, websocket: WebSocketServerProtocol):
|
async def handler(self, websocket: WebSocketServerProtocol):
|
||||||
"""Is called everytime a client connects to the websocket"""
|
"""Is called everytime a client connects to the websocket"""
|
||||||
self.connections.add(websocket)
|
self.connections.add(websocket)
|
||||||
|
|
||||||
async def track_connection():
|
async def track_connection():
|
||||||
|
"""Keeps track of connected clients in the connections property"""
|
||||||
try:
|
try:
|
||||||
await websocket.wait_closed()
|
await websocket.wait_closed()
|
||||||
finally:
|
finally:
|
||||||
@@ -30,9 +31,6 @@ class WSServer:
|
|||||||
|
|
||||||
await self.on_new_connection_callback(websocket, track_connection)
|
await self.on_new_connection_callback(websocket, track_connection)
|
||||||
|
|
||||||
async def track_connection(self, websocket: WebSocketServerProtocol):
|
|
||||||
"""Keeps track of connected clients in the connections property"""
|
|
||||||
|
|
||||||
async def serve(self, address="0.0.0.0", port=8765):
|
async def serve(self, address="0.0.0.0", port=8765):
|
||||||
"""Call to start the websocket"""
|
"""Call to start the websocket"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user