tournament: add: TOURNAMENT CAN START
This commit is contained in:
		| @ -51,6 +51,7 @@ class Tourmanent | |||||||
| 		this.finished = response_data.finished; | 		this.finished = response_data.finished; | ||||||
| 		this.levels = response_data.levels; | 		this.levels = response_data.levels; | ||||||
| 		this.id = response_data.id | 		this.id = response_data.id | ||||||
|  | 		this.state = this.get_state(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	leave(event) | 	leave(event) | ||||||
| @ -66,10 +67,7 @@ class Tourmanent | |||||||
| 	{ | 	{ | ||||||
| 		if (!this.connected) | 		if (!this.connected) | ||||||
| 			return | 			return | ||||||
| 		console.log(this.isParticipating); | 		this._socket.send(JSON.stringify({participate: ""})); | ||||||
| 		this.isParticipating = !this.isParticipating; |  | ||||||
| 		console.log(this.isParticipating); |  | ||||||
| 		this._socket.send(JSON.stringify({participate: this.isParticipating})); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	async join(receive_func, disconnect_func) | 	async join(receive_func, disconnect_func) | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import {client} from "../index.js"; | import {client, navigateTo} from "../index.js"; | ||||||
| import AbstractAuthentifiedView from "./abstracts/AbstractAuthentifiedView.js"; | import AbstractAuthentifiedView from "./abstracts/AbstractAuthentifiedView.js"; | ||||||
|  |  | ||||||
| export default class extends AbstractAuthentifiedView | export default class extends AbstractAuthentifiedView | ||||||
| @ -12,13 +12,24 @@ export default class extends AbstractAuthentifiedView | |||||||
| 	pressButton() | 	pressButton() | ||||||
| 	{ | 	{ | ||||||
| 		this.tournament.toggle_participation(); | 		this.tournament.toggle_participation(); | ||||||
| 		document.getElementById("button").value = this.tournament.isParticipating ? "Leave tournament" : "Join tournament"; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	async receive(data) | 	async receive(data) | ||||||
| 	{ | 	{ | ||||||
| 		if (data.detail === "nb_participants" || data.detail === "update_participants") | 		if (data.detail === "nb_participants" || data.detail === "update_participants") | ||||||
| 			document.getElementById("nb_participants").innerText = `${data.nb_participants} / ${this.tournament.nb_players}` | 			document.getElementById("nb_participants").innerText = `${data.nb_participants} / ${this.tournament.nb_players}` | ||||||
|  | 		if (data.detail === "go_to") | ||||||
|  | 			navigateTo(data.url); | ||||||
|  | 		if (data.detail === "is_participant") | ||||||
|  | 			this.updateParticipating(data.is_participant) | ||||||
|  | 		if (data.detail === "error") | ||||||
|  | 			document.getElementById("display").innerText = data.error_message | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	async updateParticipating(state) | ||||||
|  | 	{ | ||||||
|  | 		document.getElementById("button").value = state ? `Leave ${this.tournament.name}` : `Join ${this.tournament.name}`; | ||||||
|  | 		document.getElementById("display").innerText = state ? "You are a particpant" : "You are not a participant"; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	async ondisconnect(event) | 	async ondisconnect(event) | ||||||
| @ -81,6 +92,7 @@ export default class extends AbstractAuthentifiedView | |||||||
| 				</tbody> | 				</tbody> | ||||||
| 			</table> | 			</table> | ||||||
| 			<input type="button" id="button" value="Join tournament" disabled> | 			<input type="button" id="button" value="Join tournament" disabled> | ||||||
| 		` | 			<span id="display"></span> | ||||||
|  | 			` | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								games/serializers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								games/serializers.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | from rest_framework import serializers | ||||||
|  | from .models import GameModel, GameMembersModel | ||||||
|  |  | ||||||
|  | class GameSerializer(serializers.ModelSerializer): | ||||||
|  |  | ||||||
|  | 	players_id = serializers.SerializerMethodField() | ||||||
|  | 	winner_id = serializers.ReadOnlyField() | ||||||
|  | 	state = serializers.SerializerMethodField() | ||||||
|  | 	started = serializers.ReadOnlyField() | ||||||
|  | 	finished = serializers.ReadOnlyField() | ||||||
|  |  | ||||||
|  | 	class Meta: | ||||||
|  | 		model = GameModel | ||||||
|  | 		fields = ["id", "winner_id", "state", "started", "finished", "players_id"] | ||||||
|  |  | ||||||
|  | 	def get_state(self, instance: GameModel): | ||||||
|  | 		if (instance.finished): | ||||||
|  | 			return "finished" | ||||||
|  | 		if (instance.started): | ||||||
|  | 			return "started" | ||||||
|  | 		return "waiting" | ||||||
|  |  | ||||||
|  | 	def get_players_id(self, instance: GameModel): | ||||||
|  | 		players_id = [player_game.member_id for player_game in GameMembersModel.objects.filter(game_id=instance.pk)] | ||||||
| @ -26,18 +26,18 @@ class TournamentWebConsumer(WebsocketConsumer): | |||||||
| 		self.tournament_id = int(self.scope['url_route']['kwargs']['tournament_id']) | 		self.tournament_id = int(self.scope['url_route']['kwargs']['tournament_id']) | ||||||
|  |  | ||||||
| 		self.room = tournament_manager.get(self.tournament_id) | 		self.room = tournament_manager.get(self.tournament_id) | ||||||
| 		self.participant = TournamentMember(self.user.pk, self, self.room) | 		self.member = TournamentMember(self.user.pk, self, self.room) | ||||||
|  |  | ||||||
| 		if (self.room is None): | 		if (self.room is None): | ||||||
| 			self.participant.send("Tournament not found") | 			self.member.send("Tournament not found") | ||||||
| 			self.disconnect(1017) | 			self.disconnect(1017) | ||||||
| 	 | 	 | ||||||
| 		self.room.append(self.participant) | 		self.room.append(self.member) | ||||||
|  |  | ||||||
| 	def receive(self, text_data: str = None, bytes_data: bytes = None): | 	def receive(self, text_data: str = None, bytes_data: bytes = None): | ||||||
| 		self.participant.receive(text_data, bytes_data) | 		self.member.receive(text_data, bytes_data) | ||||||
|  |  | ||||||
| 	def disconnect(self, close_code): | 	def disconnect(self, close_code): | ||||||
| 		member = self.room.get_member_by_socket(self) | 		member = self.room.get_member_by_socket(self) | ||||||
| 		if (member is not None): | 		if (member is not None): | ||||||
| 			self.room.remove(self.participant, close_code) | 			self.room.remove(self.member, close_code) | ||||||
| @ -20,22 +20,41 @@ class TournamentModel(models.Model): | |||||||
| 	started = models.BooleanField(default=False) | 	started = models.BooleanField(default=False) | ||||||
| 	finished = models.BooleanField(default=False) | 	finished = models.BooleanField(default=False) | ||||||
|  |  | ||||||
| 	def create_game(self, users_id): | 	def create_game(self, level, users_id): | ||||||
| 		game_id = GameModel.create(users_id=users_id) | 		game_id = GameModel().create(users_id=users_id) | ||||||
| 		TournamentGamesModel(game_id=game_id, tournament_id=self.pk).save() | 		TournamentGamesModel(game_id=game_id, tournament_id=self.pk, tournament_level=level).save() | ||||||
| 		return game_id | 		return game_id | ||||||
| 	 | 	 | ||||||
| 	def get_games_id_by_level(self, level): | 	def get_games_id_by_level(self, level): | ||||||
| 		return list(TournamentGamesModel.objects.filter(tournament_id=self.pk, tournament_level=level)) | 		tmp = TournamentGamesModel.objects.filter(tournament_id=self.pk, tournament_level=level) | ||||||
|  | 		return [instance.game_id for instance in tmp] | ||||||
|  |  | ||||||
| 	def get_games_id(self): | 	def get_games_id(self): | ||||||
| 		return list(TournamentGamesModel.objects.filter(tournament_id=self.pk)) | 		return list(TournamentGamesModel.objects.filter(tournament_id=self.pk)) | ||||||
| 	 | 	 | ||||||
| 	def get_players_id(self): | 	def get_players_id(self): | ||||||
| 		lst: [int] = [] | 		return [model.participant_id for model in TournamentParticipantsModel.objects.filter(tournament_id=self.pk)] | ||||||
| 		for game_id in self.get_games_id(): | 	 | ||||||
| 			lst.append(GameMembersModel.objects.filter(game_id=game_id)) | 	def is_a_participant(self, participant_id: int): | ||||||
| 		return lst | 		return TournamentParticipantsModel.objects.filter(participant_id=participant_id, tournament_id=self.pk).exists() | ||||||
|  |  | ||||||
|  | 	def add_participants(self, participants_id: [int]): | ||||||
|  | 		for participant_id in participants_id: | ||||||
|  | 			TournamentParticipantsModel(tournament_id=self.pk, participant_id=participant_id).save() | ||||||
|  |  | ||||||
|  | 	def start(self, participants_id: [int]): | ||||||
|  | 		self.started = True | ||||||
|  | 		self.add_participants(participants_id) | ||||||
|  | 		games_id = [int] | ||||||
|  | 		for i in range(0, len(participants_id), self.nb_players_by_game): | ||||||
|  | 			game_id = self.create_game(0, participants_id[i : i + self.nb_players_by_game]) | ||||||
|  | 			games_id.append(game_id) | ||||||
|  | 		self.save() | ||||||
|  | 		return games_id | ||||||
|  |  | ||||||
|  | class TournamentParticipantsModel(models.Model): | ||||||
|  | 	tournament_id = models.IntegerField() | ||||||
|  | 	participant_id = models.IntegerField() | ||||||
|  |  | ||||||
| class TournamentGamesModel(models.Model): | class TournamentGamesModel(models.Model): | ||||||
|  |  | ||||||
| @ -45,10 +64,10 @@ class TournamentGamesModel(models.Model): | |||||||
|  |  | ||||||
| class TournamentMember(AbstractRoomMember): | class TournamentMember(AbstractRoomMember): | ||||||
|  |  | ||||||
| 	def __init__(self, user_id: int, socket: WebsocketConsumer, tournament): | 	def __init__(self, user_id: int, socket: WebsocketConsumer, room): | ||||||
| 		super().__init__(user_id, socket) | 		super().__init__(user_id, socket) | ||||||
| 		self.participate = False | 		self.participate = False | ||||||
| 		self.tournament = tournament | 		self.room = room | ||||||
|  |  | ||||||
| 	def receive(self, text_data: str = None, byte_dates: bytes = None): | 	def receive(self, text_data: str = None, byte_dates: bytes = None): | ||||||
| 		 | 		 | ||||||
| @ -57,34 +76,46 @@ class TournamentMember(AbstractRoomMember): | |||||||
|  |  | ||||||
| 		data: dict = json.loads(text_data) | 		data: dict = json.loads(text_data) | ||||||
|  |  | ||||||
| 		self.update_participate(data.get("participate", self.participate)) | 		if (data.get("participate") is not None): | ||||||
|  | 			self.room.update_participants(self) | ||||||
|  |  | ||||||
| 	def update_participate(self, new_participate: bool): | 	def send_error_message(self, message: str): | ||||||
|  | 		self.send("error", {"error_message": message}) | ||||||
|  |  | ||||||
| 		if (self.participate == new_participate): | 	def go_to(self, url: str): | ||||||
| 			return | 		self.send("go_to", {"url": url}) | ||||||
| 		self.participate = new_participate | 	 | ||||||
| 		self.tournament.update_participants() | 	def send_participating(self): | ||||||
|  | 		self.send("is_participant", {"is_participant": self.participate}) | ||||||
|  |  | ||||||
| class TournamentRoom(AbstractRoom): | class TournamentRoom(AbstractRoom): | ||||||
|  |  | ||||||
| 	def __init__(self, room_manager, tournament_id: int): | 	def __init__(self, room_manager, tournament_id: int): | ||||||
| 		super().__init__(room_manager) | 		super().__init__(room_manager) | ||||||
| 		self.tournament_id = tournament_id | 		self.tournament_id = tournament_id | ||||||
| 		self.definitive_participant_list = [] | 		self.tournament = TournamentModel.objects.get(pk=tournament_id) | ||||||
| 		self.started = False |  | ||||||
| 		self.model = TournamentModel.objects.get(pk=tournament_id) |  | ||||||
|  |  | ||||||
| 	def start(self): | 	def start(self): | ||||||
| 		self.broadcast("tournament_start") | 		self.broadcast("tournament_start") | ||||||
|  | 		games_id = self.tournament.start(self.get_participants_id()) | ||||||
|  | 		for i, participant in enumerate(self.get_participants()): | ||||||
|  | 			participant: TournamentMember | ||||||
|  | 			participant.go_to(f"games/{games_id[i // self.tournament.nb_players_by_game]}") | ||||||
|  |  | ||||||
| 	def update_participants(self): | 	def update_participants(self, member: TournamentMember): | ||||||
|  | 		if (self.tournament.started): | ||||||
|  | 			member.send_error_message("Tournament already started") | ||||||
|  | 			return | ||||||
|  | 		member.participate = not member.participate | ||||||
| 		nb_participants = self.get_nb_participants() | 		nb_participants = self.get_nb_participants() | ||||||
| 		self.broadcast("update_participants", {"nb_participants": nb_participants}) | 		self.broadcast("update_participants", {"nb_participants": nb_participants}) | ||||||
| 		if (nb_participants == self.model.nb_players): | 		member.send_participating() | ||||||
|  | 		if (nb_participants == self.tournament.nb_players): | ||||||
| 			self.start() | 			self.start() | ||||||
|  |  | ||||||
| 	def get_nb_participants(self): | 	def get_nb_participants(self): | ||||||
|  | 		if (self.tournament.started): | ||||||
|  | 			return self.tournament.nb_players | ||||||
| 		nb_participants = 0 | 		nb_participants = 0 | ||||||
| 		for member in self._member_list: | 		for member in self._member_list: | ||||||
| 			member: TournamentMember | 			member: TournamentMember | ||||||
| @ -93,13 +124,16 @@ class TournamentRoom(AbstractRoom): | |||||||
| 		return nb_participants  | 		return nb_participants  | ||||||
|  |  | ||||||
| 	def get_participants(self): | 	def get_participants(self): | ||||||
| 		return [member.user_id for member in self._member_list if member.participate] | 		return [member for member in self._member_list if member.participate] | ||||||
|  |  | ||||||
| 	def start(self): | 	def get_participants_id(self): | ||||||
| 		self.started = True | 		return [member.user_id for member in self._member_list if member.participate] | ||||||
|  |  | ||||||
| 	def append(self, member: TournamentMember): | 	def append(self, member: TournamentMember): | ||||||
| 		super().append(member) | 		super().append(member) | ||||||
|  | 		if self.tournament.started: | ||||||
|  | 			member.participate = self.tournament.is_a_participant(member.user_id) | ||||||
|  | 		member.send_participating() | ||||||
| 		member.send("nb_participants", {"nb_participants": self.get_nb_participants()}) | 		member.send("nb_participants", {"nb_participants": self.get_nb_participants()}) | ||||||
|  |  | ||||||
| class TournamentRoomManager(AbstractRoomManager): | class TournamentRoomManager(AbstractRoomManager): | ||||||
| @ -110,7 +144,7 @@ class TournamentRoomManager(AbstractRoomManager): | |||||||
| 			if (room.tournament_id == tournament_id): | 			if (room.tournament_id == tournament_id): | ||||||
| 				return room | 				return room | ||||||
| 		 | 		 | ||||||
| 		if (TournamentModel.objects.filter(pk = tournament_id).exists()): | 		if (TournamentModel.objects.filter(pk = tournament_id, finished=False).exists()): | ||||||
| 			room = TournamentRoom(self, tournament_id) | 			room = TournamentRoom(self, tournament_id) | ||||||
| 			self.append(room) | 			self.append(room) | ||||||
| 			return room | 			return room | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| from rest_framework import serializers | from rest_framework import serializers | ||||||
| from .models import TournamentModel | from .models import TournamentModel | ||||||
|  | from games.serializers import GameSerializer | ||||||
|  |  | ||||||
| class TournamentSerializer(serializers.ModelSerializer): | class TournamentSerializer(serializers.ModelSerializer): | ||||||
|  |  | ||||||
| @ -13,13 +14,13 @@ class TournamentSerializer(serializers.ModelSerializer): | |||||||
| 		model = TournamentModel | 		model = TournamentModel | ||||||
| 		fields = ["name", "nb_players", "nb_players_by_game", "level", "started", "finished", "levels", "id"] | 		fields = ["name", "nb_players", "nb_players_by_game", "level", "started", "finished", "levels", "id"] | ||||||
|  |  | ||||||
| 	def get_levels(self, instance): | 	def get_levels(self, instance: TournamentModel): | ||||||
| 		levels: [[int]] = [] | 		levels: [[int]] = [] | ||||||
| 		for i in range(instance.level): | 		for i in range(instance.level): | ||||||
| 			level: [int] = instance.get_games_id_by_level(i) | 			games_id: [int] = instance.get_games_id_by_level(i) | ||||||
| 			if (level == []): | 			if (games_id == []): | ||||||
| 				break | 				break | ||||||
| 			levels.append(level) | 			levels.append(games_id) | ||||||
| 		return levels | 		return levels | ||||||
|  |  | ||||||
| 	def validate_nb_players(self, value: int): | 	def validate_nb_players(self, value: int): | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user