From ae0a5abfcddaa97e5a43dcb6793fe7bd7c6239f7 Mon Sep 17 00:00:00 2001 From: starnakin Date: Thu, 18 Apr 2024 20:08:13 +0200 Subject: [PATCH] tournament in coming --- .../static/js/api/tournament/Tournament.js | 123 ++++++-------- .../static/js/api/tournament/Tournaments.js | 18 +- .../views/tournament/TournamentCreateView.js | 4 + .../js/views/tournament/TournamentPageView.js | 27 +-- .../views/tournament/TournamentsListView.js | 46 +---- tournament/consumers.py | 160 ++++++++++++++++-- tournament/models.py | 96 ++++------- tournament/serializers.py | 63 ++----- tournament/viewset.py | 5 +- transcendence/abstract/AbstractRoom.py | 2 +- transcendence/abstract/AbstractRoomMember.py | 8 +- 11 files changed, 265 insertions(+), 287 deletions(-) diff --git a/frontend/static/js/api/tournament/Tournament.js b/frontend/static/js/api/tournament/Tournament.js index e0b044c..634ee11 100644 --- a/frontend/static/js/api/tournament/Tournament.js +++ b/frontend/static/js/api/tournament/Tournament.js @@ -1,71 +1,53 @@ +import { AExchangeable } from "../AExchangable.js"; import { Client } from "../Client.js"; +import { Profile } from "../Profile.js"; -class Tourmanent +class Tourmanent extends AExchangeable { /** * * @param {Client} client * @param {Number} id the id of the tournament - * @param {Number} name - * @param {Number} nb_players - * @param {Number} nb_players_by_game - * @param {Number} round - * @param {Boolean} started - * @param {Boolean} finished - * @param {[]} rounds - * @param {String} state */ - constructor(client, id, name = undefined, nb_players = undefined, round = undefined, started = undefined, finished = undefined, rounds = undefined, state = undefined) + constructor(client, id) { - /** - * @type {Client} - */ - this.client = client; + super(); - /** - * @type {String} the name of the tournament - */ - this.name = name || `${nb_players_by_game}x1, ${nb_players} players`; - - /** - * @type {Number} - */ - this.nb_players = nb_players; - - /** - * @type {Number} - */ - this.round = round; - - /** - * @type {Number} - */ - this.started = started; - - /** - * @type {Number} - */ - this.finished = finished; - - /** - * @type {[]} - */ - this.rounds = rounds; - - /** - * @type {String} must be "finished", or "started", or "waiting". Any other return all elements - */ - this.state = state; - /** * @type {Number} */ this.id = id; /** - * @type {Boolean} if a websocket connection is enabled + * @type {Client} */ - this.connected = false; + this.client = client; + + /** + * @type {Number} + */ + this.nb_participants; + + /** + * @type {[Profile]} proutman à encore frappé + */ + this.participantList = [] + + /** + * @type {Boolean} + */ + this.started; + + /** + * @type {Number} + */ + this.finished; + + + /** + * @type {"finished" | "started" | "waiting"} must be "finished", or "started", or "waiting". Any other return all elements + */ + this.state; } /** @@ -81,13 +63,7 @@ class Tourmanent let response_data = await response.json(); - this.name = response_data.name || `${response_data.nb_players} players tournament`; - this.nb_players = response_data.nb_players; - this.round = response_data.round; - this.started = response_data.started; - this.finished = response_data.finished; - this.rounds = response_data.rounds; - this.state = response_data.state; + this.import(response_data); } leave(event) @@ -99,18 +75,12 @@ class Tourmanent this.disconnectHandler(event); } - toggle_participation() + /** + * @param {Object} data + */ + async _receiveParticipantUpdate(data) { - if (!this.connected) - return; - this._socket.send(JSON.stringify({participate: ""})); - } - - async onPlayersUpdate(data) - { - oldPlayerList = this.par - - await this.playersUpdateHandler(); + this.par } async onError(data) @@ -126,20 +96,22 @@ class Tourmanent { const data = JSON.parse(event.data); - if (data?.detail === "error") + if (data.detail === "error") this.onError(data); - else if (data?.detail === "players_update") - this.onPlayersUpdate(data); + else if (["del_participant", "add_participant"].includes(data.detail)) + this._receiveParticipantUpdate(data); } /** * Join the tournament Websocket * @param {CallableFunction} errorHandler - * @param {CallableFunction} playersUpdateHandler + * @param {CallableFunction} addParticipantHandler called when a participants join the tournament + * @param {CallableFunction} delParticipantHandler called when a participants leave the tournament * @param {CallableFunction} disconnectHandler + * @param {CallableFunction} goToHandler called when the next game will start * @returns {?} */ - async join(playersUpdateHandler, errorHandler, disconnectHandler) + async join(participantsUpdateHandler, errorHandler, goToHandler, disconnectHandler) { if (!await this.client.isAuthenticated()) return null; @@ -151,9 +123,10 @@ class Tourmanent this.connected = true; this.isParticipating = false; - this.playersUpdateHandler = playersUpdateHandler; + this.participantsUpdateHandler = participantsUpdateHandler; this.errorHandler = errorHandler; this.disconnectHandler = disconnectHandler; + this.goToHandler = goToHandler; this._socket.onmessage = this.onReceive.bind(this); diff --git a/frontend/static/js/api/tournament/Tournaments.js b/frontend/static/js/api/tournament/Tournaments.js index 2e261b4..688cc82 100644 --- a/frontend/static/js/api/tournament/Tournaments.js +++ b/frontend/static/js/api/tournament/Tournaments.js @@ -29,13 +29,13 @@ class Tourmanents /** * - * @param {Number} nb_players + * @param {Number} nb_participants * @param {String} name * @returns {Response} */ - async createTournament(nb_players, name = "") + async createTournament(nb_participants, name = "") { - let response = await this.client._post("/api/tournaments/", {nb_players: nb_players, name: name}); + let response = await this.client._post("/api/tournaments/", {nb_participants: nb_participants, name: name}); return response; } @@ -58,15 +58,9 @@ class Tourmanents let tournaments = [];`` response_data.forEach(tournament_data => { - tournaments.push(new Tourmanent(this.client, - tournament_data.name, - tournament_data.nb_players, - tournament_data.round, - tournament_data.started, - tournament_data.finished, - tournament_data.rounds, - tournament_data.id, - tournament_data.state)); + let tournament = new Tourmanent(this.client, tournament_data.id); + tournament.import(tournament_data); + tournaments.push(tournament); }); return tournaments; diff --git a/frontend/static/js/views/tournament/TournamentCreateView.js b/frontend/static/js/views/tournament/TournamentCreateView.js index e57cdcb..6565520 100644 --- a/frontend/static/js/views/tournament/TournamentCreateView.js +++ b/frontend/static/js/views/tournament/TournamentCreateView.js @@ -13,6 +13,10 @@ export default class extends AbstractAuthenticatedView async create() { let name = document.getElementById("name-input").value; + if (name.length == 0) + name = lang.get("TournamentCreateTournamentName"); + + console.log(name); let nb_players = document.getElementById("nb-players-input").value; let response = await client.tournaments.createTournament(nb_players, name); diff --git a/frontend/static/js/views/tournament/TournamentPageView.js b/frontend/static/js/views/tournament/TournamentPageView.js index 20a52a1..a43c84e 100644 --- a/frontend/static/js/views/tournament/TournamentPageView.js +++ b/frontend/static/js/views/tournament/TournamentPageView.js @@ -25,7 +25,7 @@ export default class extends AbstractAuthenticatedView document.getElementById("app").appendChild(tournament_tree); - for (let round_id = 0; round_id < this.tournament.levels.length; round_id++) + for (let round_id = 0; round_id < this.tournament.round.length; round_id++) { let current_round = document.createElement("ul"); @@ -33,7 +33,7 @@ export default class extends AbstractAuthenticatedView current_round.className = `round round-${round_id}`; - for (let participant_i = 0; participant_i < this.tournament.levels[round_id].length; participant_i += 2) + for (let participant_i = 0; participant_i < this.tournament.round[round_id].length; participant_i += 2) { let spacer = document.createElement("li"); @@ -45,7 +45,7 @@ export default class extends AbstractAuthenticatedView let game_top = document.createElement("li"); game_top.className = "game game-top"; - game_top.innerText = `${this.tournament.levels[round_id][participant_i]}`; + game_top.innerText = `${this.tournament.round[round_id][participant_i]}`; current_round.appendChild(game_top); @@ -59,7 +59,7 @@ export default class extends AbstractAuthenticatedView let game_bottom = document.createElement("li"); game_bottom.className = "game game-bottom"; - game_bottom.innerText = `${this.tournament.levels[round_id][participant_i + 1]}`; + game_bottom.innerText = `${this.tournament.round[round_id][participant_i + 1]}`; current_round.appendChild(game_bottom); } @@ -70,7 +70,7 @@ export default class extends AbstractAuthenticatedView async receive(data) { if (data.detail === "update_participants") - document.getElementById("nb_participants").innerText = `${data.participants} / ${this.tournament.nb_players}`; + document.getElementById("nb_participants").innerText = `${data.participants} / ${this.tournament.nb_participants}`; if (data.detail === "go_to") navigateTo(data.url); if (data.detail === "is_participant") @@ -121,9 +121,8 @@ export default class extends AbstractAuthenticatedView button.onclick = this.pressButton.bind(this); document.getElementById("name").innerText = this.tournament.name; - document.getElementById("nb_participants").innerText = this.tournament.nb_players; - document.getElementById("nb_players_by_game").innerText = this.tournament.nb_players_by_game; - document.getElementById("level").innerText = this.tournament.level; + document.getElementById("nb_participants").innerText = this.tournament.nb_participants; + document.getElementById("round").innerText = this.tournament.round; document.getElementById("state").innerText = this.tournament.state; if (this.tournament.started === false) @@ -142,20 +141,12 @@ export default class extends AbstractAuthenticatedView - - Number of players - Loading... - - - Number of players by game - Loading... - Number of round - Loading... + Loading... - Number of player + Number of participants Loading... diff --git a/frontend/static/js/views/tournament/TournamentsListView.js b/frontend/static/js/views/tournament/TournamentsListView.js index 5ce9559..bc6b553 100644 --- a/frontend/static/js/views/tournament/TournamentsListView.js +++ b/frontend/static/js/views/tournament/TournamentsListView.js @@ -13,41 +13,14 @@ export default class extends AbstractAuthenticatedView { let state = document.getElementById("state-select").value; this.tournaments = await client.tournaments.search(state); - } - - add_nb_player_by_game_selector() - { - let nb_players_by_game_list = new Set(); - this.tournaments.forEach(tournament => { - nb_players_by_game_list.add(tournament.nb_players_by_game); - }); - - let select = document.getElementById("nb-players-by-game-select"); - - let new_children = []; - - const opt = document.createElement("option"); - opt.value = "all"; - opt.text = "All"; - - new_children.push(opt); - - nb_players_by_game_list.forEach(nb_players_by_game => { - const opt = document.createElement("option"); - opt.value = nb_players_by_game; - opt.text = nb_players_by_game; - new_children.push(opt); - }); - select.replaceChildren(...new_children); + //console.log(this.tournaments); } internal_search() { - let nb_players_by_game = document.getElementById("nb-players-by-game-select").value; this.display_tournaments = []; this.tournaments.forEach(tournament => { - if (nb_players_by_game === "all" || nb_players_by_game == tournament.nb_players_by_game) this.display_tournaments.push(tournament); }); } @@ -58,6 +31,7 @@ export default class extends AbstractAuthenticatedView const new_children = []; + console.log(this.display_tournaments); this.display_tournaments.forEach(tournament => { let tr = document.createElement("tr"); @@ -72,14 +46,9 @@ export default class extends AbstractAuthenticatedView td.innerText = tournament.state; tr.appendChild(td); - // nb_players + // nb_participants td = document.createElement("td"); - td.innerText = tournament.nb_players; - tr.appendChild(td); - - // nb_players_by_game - td = document.createElement("td"); - td.innerText = tournament.nb_players_by_game; + td.innerText = tournament.nb_participants; tr.appendChild(td); new_children.push(tr); @@ -96,7 +65,6 @@ export default class extends AbstractAuthenticatedView async update_search() { await this.external_search(); - this.add_nb_player_by_game_selector(); this.update_query(); } @@ -104,7 +72,6 @@ export default class extends AbstractAuthenticatedView { await this.update_search(); document.getElementById("state-select").onchange = this.update_search.bind(this); - document.getElementById("nb-players-by-game-select").onchange = this.update_query.bind(this); } async getHtml() @@ -116,14 +83,11 @@ export default class extends AbstractAuthenticatedView - - - + diff --git a/tournament/consumers.py b/tournament/consumers.py index 12a0854..cb99d9c 100644 --- a/tournament/consumers.py +++ b/tournament/consumers.py @@ -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) \ No newline at end of file + + self.room.leave(self.member) + + super().disconnect(close_code) # proutman à encore frappé \ No newline at end of file diff --git a/tournament/models.py b/tournament/models.py index 1366e35..176fdfc 100644 --- a/tournament/models.py +++ b/tournament/models.py @@ -1,8 +1,5 @@ from __future__ import annotations -from django.db import models - - from transcendence.abstract.AbstractRoomMember import AbstractRoomMember from transcendence.abstract.AbstractRoom import AbstractRoom from transcendence.abstract.AbstractRoomManager import AbstractRoomManager @@ -13,59 +10,52 @@ from games.models import GameModel from django.contrib.auth.models import User from django.db.models import CASCADE from channels.generic.websocket import WebsocketConsumer +from django.db import models + +import json # Create your models here.tu class TournamentModel(models.Model): name = models.CharField(max_length = 100) - nb_players = models.IntegerField() - rounds = models.IntegerField() + nb_participants = models.IntegerField() + round = models.IntegerField() started = models.BooleanField(default = False) finished = models.BooleanField(default = False) - winner = models.ForeignKey(ProfileModel, on_delete=CASCADE) + winner = models.ForeignKey(ProfileModel, on_delete=CASCADE, blank=True, null=True) - def _add_player(self, player: ProfileModel) -> None: - TournamentPlayerModel(player=player, tournament=self).save() + def _register_participant(self, participant: ProfileModel) -> None: + TournamentParticipantModel(participant=participant, tournament=self).save() - def start(self, players: list[ProfileModel]) -> None: + def start(self, participants: list[ProfileModel]) -> None: - self.started = False + self.started = True - for player in players: - self._add_player(player) + for player in participants: + self._register_participant(player) + + for (participant1, participant2) in zip(participants[0::2], participants[1::2]): + self.create_game([participant1, participant2], round=1) - for (player1, player2) in zip(players[0::2], players[1::2]): - self.create_game([player1, player2], round=1) - self.save() - def create_game(self, players: list[ProfileModel], round: int) -> GameModel: + def create_game(self, participants: list[ProfileModel], round: int) -> GameModel: if (self.started == False): return None - - if (len(players) != 2): + + if (len(participants) != 2): return None - + from games.models import GameModel - game: GameModel = GameModel().create(players=players) + game: GameModel = GameModel().create(participants) TournamentGameModel(tournament=self, game=game, round=round).save() return game - def start(self, players: list[ProfileModel]) -> int: - - if (len(players) != self.nb_players): - return 1 - - for player in players: - TournamentPlayerModel(tournament=self, player=player).save() - - return 0 - def get_games(self) -> list[GameModel]: return [tournament_game.game for tournament_game in TournamentGameModel.objects.filter(tournament=self)] @@ -78,50 +68,22 @@ class TournamentModel(models.Model): def get_winners_by_round(self, round: int) -> list[ProfileModel]: return [game.winner for game in self.get_games_by_round(round)] - def get_players(self) -> list[TournamentPlayerModel]: - return TournamentPlayerModel.objects.filter(tournament=self.pk) + def get_participants(self) -> list[TournamentParticipantModel]: + return TournamentParticipantModel.objects.filter(tournament=self.pk) def get_state(self) -> str: return ("waiting to start", "in progress", "finish")[self.started + self.finished] - def is_player(self, profile: ProfileModel) -> bool: - return TournamentPlayerModel.objects.filter(player=profile, tournament=self).exists() + def is_participanting(self, profile: ProfileModel) -> bool: + return TournamentParticipantModel.objects.filter(participant=profile, tournament=self).exists() -class TournamentPlayerModel(models.Model): - player = models.ForeignKey(ProfileModel, on_delete=CASCADE) +class TournamentParticipantModel(models.Model): + participant = models.ForeignKey(ProfileModel, on_delete=CASCADE) tournament = models.ForeignKey(TournamentModel, on_delete=CASCADE) - + #prout à encore frappé + class TournamentGameModel(models.Model): tournament = models.ForeignKey(TournamentModel, on_delete=CASCADE, null=True, blank=True) round = models.IntegerField() - game = models.ForeignKey(GameModel, on_delete=CASCADE) - -class TournamentSpectator(AbstractRoomMember): - pass - -class TournamentPlayer(TournamentSpectator): - pass - -class TournamentRoom(AbstractRoom): - - def __init__(self, room_manager: TournamentRoomManager, tournament_id: int): - super().__init__(room_manager) - self.room_manager: TournamentRoomManager - self.id: int = id - self.model: TournamentModel = TournamentModel.objects.get(pk=tournament_id) - - - def join(self, profile: ProfileModel, socket: WebsocketConsumer) -> TournamentPlayer | TournamentSpectator: - if (self.model.started): - if (self.model.is_player(profile)): - return TournamentPlayer(profile.pk, socket) - else: - return TournamentSpectator(profile.pk, socket) - else: - return TournamentSpectator(profile.pk, socket) - -class TournamentRoomManager(AbstractRoomManager): - pass - -tournament_manager: TournamentRoomManager = TournamentRoomManager() \ No newline at end of file + game = models.ForeignKey(GameModel, on_delete=CASCADE) \ No newline at end of file diff --git a/tournament/serializers.py b/tournament/serializers.py index 1538ef3..18b4f13 100644 --- a/tournament/serializers.py +++ b/tournament/serializers.py @@ -4,7 +4,7 @@ from django.db.models.query import QuerySet from django.contrib.auth.models import User -from .models import TournamentModel, tournament_manager +from .models import TournamentModel from profiles.models import ProfileModel from profiles.serializers.ProfileSerializer import ProfileSerializer @@ -12,9 +12,8 @@ from games.serializers import GameSerializer class TournamentSerializer(serializers.ModelSerializer): - rounds = serializers.SerializerMethodField(read_only=True, required=False) state = serializers.SerializerMethodField(read_only=True, required=False) - players = serializers.SerializerMethodField(read_only=True, required=False) + participants = serializers.SerializerMethodField(read_only=True, required=False) round = serializers.ReadOnlyField() started = serializers.ReadOnlyField() finished = serializers.ReadOnlyField() @@ -22,57 +21,25 @@ class TournamentSerializer(serializers.ModelSerializer): class Meta: model = TournamentModel - fields = ["name", "nb_players", "nb_players_by_game", "round", "started", "finished", "rounds", "id", "state", "players"] - - def get_players(self, instance: TournamentModel): - - players_id: list[ProfileModel] - - if (instance.started): - players_id = instance.get_players_id() - else: - players_id = tournament_manager.get(instance.pk).get_players_id() - - players_profile: list[ProfileModel] = [] - for player_id in players_id: - query: QuerySet = ProfileModel.objects.filter(user_id = player_id) - profile_data: dict - if query.exists(): - profile_data = ProfileSerializer(query[0]).data - else: - profile_data = { - "username": "deleted_user", - "avatar": "/static/avatars/default.avif", - "user_id": players_id - } - players_profile.append(profile_data) - - return players_profile - + fields = ["name", "nb_participants", "round", "started", "finished", "id", "state", "participants"] + + def get_participants(self, instance: TournamentModel): + return ProfileSerializer(instance.get_participants(), many=True).data def get_state(self, instance: TournamentModel): return ["waiting", "started", "finished"][instance.started + instance.finished] - def get_rounds(self, instance: TournamentModel): - rounds: list[list[int]] = [] - for i in range(instance.round): - games_id: list[int] = instance.get_games_id_by_round(i) - if (games_id == []): - break - rounds.append(games_id) - return rounds - - def validate_nb_players(self, value: int): + def validate_nb_participants(self, value: int): if (value < 2): - raise serializers.ValidationError("The numbers of players must be greather than 2.") + raise serializers.ValidationError("The numbers of participants must be greather than 2.") return value - def validate_nb_players_by_game(self, value: int): + def validate_nb_participants_by_game(self, value: int): if (value < 2): - raise serializers.ValidationError("The numbers of players by game must be greather than 2.") - nb_players: str = self.initial_data.get("nb_players") - if (nb_players is not None and nb_players.isnumeric()): - nb_players: int = int(nb_players) - if (value > nb_players): - raise serializers.ValidationError("The numbers of players by game must be smaller than the numbers of players.") + raise serializers.ValidationError("The numbers of participants by game must be greather than 2.") + nb_participants: str = self.initial_data.get("nb_participants") + if (nb_participants is not None and nb_participants.isnumeric()): + nb_participants: int = int(nb_participants) + if (value > nb_participants): + raise serializers.ValidationError("The numbers of participants by game must be smaller than the numbers of participants.") return value \ No newline at end of file diff --git a/tournament/viewset.py b/tournament/viewset.py index b19cc0a..dcec5a4 100644 --- a/tournament/viewset.py +++ b/tournament/viewset.py @@ -19,10 +19,7 @@ class TournamentViewSet(viewsets.ModelViewSet): authentication_classes = (SessionAuthentication,) def perform_create(self, serializer: TournamentSerializer): - - nb_players = serializer.validated_data["nb_players"] - name = serializer.validated_data["name"] - tournament = serializer.save(name=name, nb_players=nb_players, round=1) + tournament = serializer.save(round=1) return Response(self.serializer_class(tournament).data, status=status.HTTP_201_CREATED) diff --git a/transcendence/abstract/AbstractRoom.py b/transcendence/abstract/AbstractRoom.py index ba0e414..afdad42 100644 --- a/transcendence/abstract/AbstractRoom.py +++ b/transcendence/abstract/AbstractRoom.py @@ -5,7 +5,7 @@ from .AbstractRoomMember import AbstractRoomMember class AbstractRoom: def __init__(self, room_manager): - self._member_list: [AbstractRoomMember] = [] + self._member_list: list[AbstractRoomMember] = [] self.room_manager = room_manager def broadcast(self, detail: str, data: dict = {}): diff --git a/transcendence/abstract/AbstractRoomMember.py b/transcendence/abstract/AbstractRoomMember.py index 2dd161b..e0e701e 100644 --- a/transcendence/abstract/AbstractRoomMember.py +++ b/transcendence/abstract/AbstractRoomMember.py @@ -11,10 +11,4 @@ class AbstractRoomMember: def send(self, detail: str, data: dict = {}): raw_data: dict = {"detail": detail} raw_data.update(data) - self.socket.send(text_data=json.dumps(raw_data)) - - def accept(self): - self.socket.accept() - - def disconnect(self, code: int = 1000): - self.socket.disconnect(code) \ No newline at end of file + self.socket.send(text_data=json.dumps(raw_data)) \ No newline at end of file
Name StatusMax numbers of playersMax numbers of players by gameMax numbers of participants