diff --git a/commands/command.py b/commands/command.py index 3ebbc03b..e68c3b1e 100644 --- a/commands/command.py +++ b/commands/command.py @@ -70,11 +70,11 @@ async def parse_command(client, game, message): if not game.is_started(): # prevent user uses command before game starts await message.reply(text_templates.generate_text("game_not_started_text")) - return None + return if not game.is_in_play_time(): await message.reply(text_templates.generate_text("game_not_playing_text")) - return None + return is_valid_channel = \ (cmd == "vote" and message.channel.name == config.GAMEPLAY_CHANNEL) or\ @@ -123,6 +123,15 @@ async def parse_command(client, game, message): message.guild, text_templates.generate_text( "invalid_channel_text", channel=real_channel), message.channel.name ) + elif cmd == "selfcheck": + if not game.is_started(): + await message.reply(text_templates.generate_text("game_not_started_text")) + return + if message.channel.name not in (config.GAMEPLAY_CHANNEL, config.LOBBY_CHANNEL): # Only use in common channels, no spamming + await message.reply(text_templates.generate_text("invalid_channel_text", channel=f"#{config.LOBBY_CHANNEL} #{config.GAMEPLAY_CHANNEL}")) + return + msg = await game.self_check_channel() + await message.reply(msg) elif cmd == "status": if game.is_ended(): @@ -169,7 +178,7 @@ async def parse_command(client, game, message): # Check if any timer phase is too short (<= 5 seconds): if not timer_phase or any(map(lambda x: x <= 5, timer_phase)): await message.reply("Config must greater than 5s") - return None + return await message.reply( text_templates.generate_text( "timer_settings_text", diff --git a/game/__init__.py b/game/__init__.py index 206b8ee7..6a5684d3 100644 --- a/game/__init__.py +++ b/game/__init__.py @@ -37,6 +37,7 @@ def __init__(self, guild, interface): self.play_time_start = datetime.time(0, 0, 0) # in UTC self.play_time_end = datetime.time(0, 0, 0) # in UTC self.play_zone = "UTC+7" + self.async_lock = asyncio.Lock() self.reset_game_state() # Init other game variables every end game. def reset_game_state(self): @@ -239,21 +240,32 @@ async def delete_channel(self): except Exception as e: print(e) + async def self_check_channel(self): + try: + await asyncio.gather( + *[player.create_personal_channel(self_check=True) for player in self.players.values()] + ) + + return text_templates.generate_text('self_check_text') + except Exception as e: + print(e) + async def add_player(self, id_, player_name): - if id_ in self.players: - return -1 + async with self.async_lock: + if id_ in self.players: + return -1 - if id_ in self.watchers: - print("Player", id_, "unwatched and joined") - self.watchers.remove(id_) - else: - print("Player", id_, "joined") + if id_ in self.watchers: + print("Player", id_, "unwatched and joined") + self.watchers.remove(id_) + else: + print("Player", id_, "joined") - self.players[id_] = None - self.playersname[id_] = player_name - await self.interface.add_user_to_channel(id_, config.GAMEPLAY_CHANNEL, is_read=True, is_send=True) - await self.interface.send_action_text_to_channel("gameplay_join_text", config.GAMEPLAY_CHANNEL, player_id=id_) - return len(self.players) # Return number of current players + self.players[id_] = None + self.playersname[id_] = player_name + await self.interface.add_user_to_channel(id_, config.GAMEPLAY_CHANNEL, is_read=True, is_send=True) + await self.interface.send_action_text_to_channel("gameplay_join_text", config.GAMEPLAY_CHANNEL, player_id=id_) + return len(self.players) # Return number of current players async def remove_player(self, id_): if id_ not in self.players: diff --git a/game/roles/character.py b/game/roles/character.py index ec83babe..37d9f9ac 100644 --- a/game/roles/character.py +++ b/game/roles/character.py @@ -64,13 +64,14 @@ def on_use_mana(self): def get_mana(self): return self.mana - async def create_personal_channel(self): + async def create_personal_channel(self, self_check = False): await self.interface.create_channel(self.channel_name) await self.interface.add_user_to_channel(self.player_id, self.channel_name, is_read=True, is_send=True) - await self.interface.send_action_text_to_channel( - "personal_channel_welcome_text", self.channel_name, - player_id=self.player_id, player_role=self.__class__.__name__ - ) + if not self_check: + await self.interface.send_action_text_to_channel( + "personal_channel_welcome_text", self.channel_name, + player_id=self.player_id, player_role=self.__class__.__name__ + ) print("Created channel", self.channel_name) async def send_to_personal_channel(self, text): diff --git a/json/command_info.json b/json/command_info.json index 3bb65924..5b4915e2 100644 --- a/json/command_info.json +++ b/json/command_info.json @@ -96,6 +96,14 @@ "exclusive_roles": [], "required_params": [] }, + "selfcheck": { + "description": { + "vi": "Kiểm tra lại tất cả channel người chơi.", + "en": "Re-check all player channels." + }, + "exclusive_roles": [], + "required_params": [] + }, "next": { "description": { "vi": "Nhảy đến phase sau (cần đủ số lượng vote).", @@ -192,4 +200,4 @@ "exclusive_roles": [], "required_params": [] } -} \ No newline at end of file +} diff --git a/json/text_template.json b/json/text_template.json index 4968ff68..1fdce547 100644 --- a/json/text_template.json +++ b/json/text_template.json @@ -216,6 +216,13 @@ "en": ["All players are ready. The system will assign roles and the game will begin soon!"] } }, + "self_check_text": { + "params": [], + "template": { + "vi": ["Tất cả channel người chơi đã được kiểm tra!"], + "en": ["Player channels have been checked!"] + } + }, "end_text": { "params": [], "template": {