tournament in coming

This commit is contained in:
2024-04-18 20:08:13 +02:00
parent 630ef709ab
commit ae0a5abfcd
11 changed files with 265 additions and 287 deletions

View File

@ -1,36 +1,168 @@
from __future__ import annotations
from channels.generic.websocket import WebsocketConsumer
from django.contrib.auth.models import User
from django.db.models import QuerySet
from django.utils.translation import gettext as _
from games.models import GameModel
from profiles.models import ProfileModel
from profiles.serializers.ProfileSerializer import ProfileSerializer
from .models import TournamentModel
import json
from .models import tournament_manager, TournamentPlayer, TournamentSpectator, TournamentRoom, TournamentRoomManager
class TournamentMember:
def __init__(self, socket: TournamentWebConsumer, room: TournamentRoom, is_participating: bool = False) -> None:
self._socket: TournamentWebConsumer = socket
self._room: TournamentRoom = room
self.is_participating: bool = is_participating
def send(self, detail: str, data: dict = {}):
data_to_send: dict = {"detail": detail}
data_to_send.update(data)
self._socket.send(json.dumps(data_to_send))
def send_error(self, error_message: str, data: dict = {}):
data_to_send: dict = {"error_message": error_message}
data_to_send.update(data)
self.send("error", data_to_send)
def _receive_participating(self, data: dict) -> None:
is_participating: bool | None = data.get("is_participating")
if (is_participating is None):
self.send_error(_("Missing is_participating statement."))
return
self._room.set_participation()
def receive(self, data: dict):
if self.is_participating == False:
return
detail: str | None = data.get("detail")
if (detail is None):
return
match(detail):
case "update_particapating":
self._receive_participating()
case _:
print("bozo_send")
class TournamentRoomManager:
def __init__(self):
self._room_list: list[TournamentRoom] = []
def get(self, tournament: TournamentModel) -> TournamentRoom:
for room in self._room_list:
if room._model is tournament:
return room
room: TournamentRoom = TournamentRoom(self, tournament)
self._room_list.append(room)
return room
def remove(self, room: TournamentRoom) -> None:
self._room_list.remove(room)
class TournamentRoom:
def __init__(self, room_manager: TournamentRoomManager, tournament: TournamentModel):
self._room_manager: TournamentRoomManager = room_manager
self._member_list: list[TournamentMember] = []
self._model: TournamentModel = tournament
def join(self, socket: TournamentWebConsumer) -> TournamentMember:
member: TournamentMember = TournamentMember(socket, self)
self._member_list.append(member)
return member
def leave(self, member: TournamentMember) -> None:
# Delete room if nobody connected, no cringe memory leak
if (len(self._member_list) == 1):
self._room_manager.remove(self)
return
self._member_list.remove(member)
self.set_participation(member, False)
def broadcast(self, detail: str, data: dict, excludes: list[TournamentMember] = []) -> None:
member_list: list[TournamentMember] = [member for member in self._member_list if member not in excludes]
for member in member_list:
member.send(detail, data)
def get_participants(self) -> list[TournamentMember]:
return [member for member in self._member_list if member.is_participating]
def set_participation(self, member: TournamentMember, is_participating: bool) -> None:
if (self._model.started):
return
if (member.is_participating == is_participating):
return
if (is_participating == True):
self.broadcast("add_participant", {"profile", ProfileSerializer(member._socket.user.profilemodel).data})
else:
self.broadcast("del_participant", {"profile", ProfileSerializer(member._socket.user.profilemodel).data})
member.is_participating = is_participating
tournament_manager: TournamentRoomManager = TournamentRoomManager()
class TournamentWebConsumer(WebsocketConsumer):
def connect(self):
self.user: User = self.scope["user"]
if (self.user.is_anonymous or not self.user.is_authenticated):
if (not self.user.is_authenticated):
return
self.tournament_id = int(self.scope['url_route']['kwargs']['tournament_id'])
tournament_id: int = int(self.scope['url_route']['kwargs']['tournament_id'])
self.room = tournament_manager.get(self.tournament_id)
self.member: TournamentPlayer | TournamentSpectator = self.room(self.user.pk, self, self.room)
query: QuerySet = TournamentModel.objects.filter(pk=tournament_id)
if (self.room is None):
self.member.send("Tournament not found")
self.disconnect(1017)
if (not query.exists()):
return
tournament: TournamentModel = query[0]
self.room.append(self.member)
self.room = tournament_manager.get(tournament)
self.member: TournamentMember = self.room.join(self)
self.accept()
def receive(self, text_data: str = None, bytes_data: bytes = None):
self.member.receive(text_data, bytes_data)
user: User = self.scope["user"]
if (user != self.user):
return
data: dict = json.loads(text_data)
self.member.receive(data)
def disconnect(self, close_code):
member = self.room.get_member_by_socket(self)
if (member is not None):
self.room.remove(self.member, close_code)
self.room.leave(self.member)
super().disconnect(close_code) # proutman à encore frappé