async def _analyze_message(self, message): if not self._active or not self._channels[message.channel].active: if message.content == Emojis.fork_and_knife: return await self.start_channel(message.channel) return if message.content == Emojis.fork_and_knife: await message.channel.send(self._messages["REPEAT"]) return if message.author.bot: return if not self._channels[message.channel].active: # game already ended logger.debug(f"Game {self.__class__.__name__} already ended") return for key, solution in self._messages["SOLUTIONS"].items(): # check the presence of the key if not check_answer(message.content, possible_answers=[key]): continue # check the presence of the solution possible_answers = solution["solution"] forbidden_answers = solution.get("forbidden", None) if check_answer(message.content, possible_answers=possible_answers, forbidden_answers=forbidden_answers): if self._channels[ message.channel].statuses[key] is Status.ANSWERED: await message.channel.send( random.choice(GeneralMessages["ALREADY_SAID"])) break self._channels[message.channel].statuses[key] = Status.ANSWERED await message.channel.send( random.choice(GeneralMessages["GOOD_ANSWERS"])) break else: if self._channels[ message.channel].statuses[key] is not Status.ANSWERED: self._channels[ message.channel].statuses[key] = Status.TENTATIVE await message.channel.send( random.choice(GeneralMessages["BAD_ANSWERS"])) self._channels[message.channel].count_bad_answers += 1 if self._channels[message.channel].count_bad_answers % 10 == 3: await message.channel.send(self._messages["REPEAT"]) break if self._check_victory(message.channel): await self.on_channel_victory(message.channel) logger.debug( f"Game {self.__class__.__name__} ended in channel {message.channel}" )
async def _analyze_message(self, message: discord.Message): if not self._active: return if message.channel != self._text_channel: return if message.author.bot: return if not message.channel_mentions: return if len(message.channel_mentions) > 1: self._webhook.send(self._messages["ONE_ROOM_AT_A_TIME"]) return # search an answer: for room_key, match_values in self._matches.items(): if check_answer(message.content, possible_answers=match_values["answers"]): # TODO: add forbidden answers ? self._webhook.send(random.choice( self._messages["OK_MESSAGES"])) self._webhook.send( self._messages["SIGN"].format(emoji=match_values["emoji"])) self._matches_done[room_key] = True self.current_room = None return await self._check_victory() # If a room has been asked to Tintin and a bad answer (len(msg)>1) is given if self.current_room and len(message.content.strip().split()) > 1: self._webhook.send(random.choice(self._messages["NO_MESSAGES"])) self.current_room = None self._webhook.send(self._messages["ASK_TO_REPEAT"]) return # Else: no research at the moment: create a new research. search_channel = message.channel_mentions[0] channel_key = getattr(search_channel, self._matching_key) matches_value = self._matches.get(channel_key, None) if not matches_value: logger.debug( f"No message associated to channel {search_channel.name} (with attr key '{channel_key}')" ) self._webhook.send(self._messages["NO_ANSWER"].format( channel_mention=search_channel.mention)) return self.current_room = channel_key # Play even if something is already playing self._webhook.send(self._messages["LISTENING_TO_ANSWER"].format( channel_mention=search_channel.mention)) await self._sound_tools.play(self._voice_channel, matches_value["file"], force=True)
async def _analyze_message(self, message: discord.Message): if not self._active or not self._channels[message.channel].active: return if message.author.bot: return if check_answer(message.content, self._messages["FINAL_CODES"]): if not self._channels[message.channel].success: await self.on_channel_victory(message.channel) return elif len(message.content) in [ len(code) for code in self._messages["FINAL_CODES"] ]: await message.channel.send( self._messages["ERROR_MESSAGE"].format(code=message.content))
async def _analyze_message(self, message: discord.Message): if not self._active or not self._channels[message.channel].active: return if message.author.bot: return if check_answer(message.content, [self._messages["FINAL_CODE"]]): await self.on_channel_victory(message.channel) return code_found = check_answer_and_return_it( message.content, self._messages["INTERMEDIATE_CODES"]) if code_found is not None: await message.channel.send( self._messages["INTERMEDIATE_ANSWER"].format(code=code_found))
async def _analyze_message(self, message: discord.Message): if not self._active or not self._channels[message.channel].active: if message.content == Emojis.anchor: return await self.start_channel(message.channel) return if message.author.bot: return if not self._channels[message.channel].active: # game already ended logger.debug("Game already ended") return if ((not message.author.voice or message.author.voice.channel != self._voice_channel_description.object_reference) and not any( role_descr.has_the_role(message.author) for role_descr in self._ignored_roles_descriptions)): msg = self._messages["STAY_IN_AUDIO"].format( salle_marine_mention=self._voice_channel_description. object_reference.mention) await message.channel.send(msg) return channel = message.channel # Send a webhook message from character if self._channels[channel].count_messages % 10 == 2: if not self._channels[channel].webhook: self._channels[ channel].webhook = await self._character_description.get_instance( channel) try: self._channels[channel].webhook.send( random.choice(self._messages["CHARACTER_MESSAGES"])) if self._count_nb_correct(channel): self._channels[channel].webhook.send( random.choice( self._messages["CHARACTER_MESSAGES_2"]).format( nb_correct=self._count_nb_correct(channel))) except NotFound as err: logger.exception(err) self._channels[channel].webhook = None if self._channels[channel].count_messages == 10: self._channels[channel].webhook.send( file=File(self._messages["CHARACTER_MESSAGE_FILE"])) self._channels[channel].count_messages += 1 # Check forbidden answers (exact word check) if check_answer(message.content, self._messages["FORBIDDEN_ANSWERS"], options=[TextAnalysisOptions.STRICT_EQUAL]): await message.add_reaction(Emojis.interrobang) await channel.send(random.choice(self._messages["BAD_ANSWERS"])) self.reset_counter(channel) await message.add_reaction(Emojis.face_with_symbols_over_mouth) await asyncio.sleep(5) await message.add_reaction(Emojis.name_badge) await message.delete(delay=2) return # Check correct messages messages_to_check = (self._messages["MANDATORY_ANSWERS"], self._messages["CORRECT_ANSWERS"], self._messages["OPTIONAL_ANSWERS"]) answers_to_update = (self._channels[channel].mandatory_answers, self._channels[channel].correct_answers, self._channels[channel].optional_answers) answers_to_send = (self._messages["GOOD_ANSWERS"], self._messages["GOOD_ANSWERS"], None) for msg_to_check, dict_to_update, answer_list_to_send in zip( messages_to_check, answers_to_update, answers_to_send): ans = check_answer_and_return_it(message.content, msg_to_check) if ans is not None and ans not in dict_to_update: # mandatory/correct/optional answer detected if answer_list_to_send: await channel.send(random.choice(answer_list_to_send)) dict_to_update.add(ans) return await self._check_and_handle_victory(channel)
async def _analyze_message(self, message: discord.Message): if not self._active or not self._channels[message.channel].active: return if message.author.bot: return channel = message.channel # Help from master if self._master_role_description.has_the_role(message.author): if message.content == LightActions.flashlight: # Flashlight for normal images await self._send_next_image(message.channel) elif message.content == LightActions.candle: # Candle for special images self._channels[channel].special = True await self._send_next_image(message.channel) for key, has_been_found in self._channels[channel].objects_found.items( ): words_to_find, answer = self._channels[channel].data["objects"][ key] if check_answer(message.content, words_to_find): if has_been_found: if self._simple_mode: await channel.send(self._messages["ALREADY_FOUND"]) continue if key == GameActions.map and not self._channels[ channel].objects_found[GameActions.handbag]: continue # handbag must be found before the map await channel.send( answer.format(**self._format_max_uses(channel))) self._channels[channel].objects_found[key] = True if len(message.content) > 2: # only emojis (length 1 or 2) are actions return # Check LightActions emojis for key, _count_light_actions in self._channels[ channel].light_actions.items(): if message.content != key: continue if not self._channels[channel].objects_found[key]: continue if not self._master_role_description.has_the_role(message.author) \ and message.author not in self._channels[channel].members: # user joined the channel too late ! The count of objects cannot be done # because members are initialized at channel game start. await channel.send(self._messages["LATE_USER_JOINED"].format( user_mention=message.author.display_name)) return # Only one use of flashlight, at the beginning (after, only the battery emoji can make it light up again) if key == LightActions.flashlight and not sum( self._channels[channel].light_actions[key].values()): self._channels[channel].current_light = LightType.flashlight self._channels[channel].light_actions[key][message.author] += 1 await self._send_next_image(channel) break # Candle + matches (fire) together / level STANDARD candle_uses = self._channels[channel].light_actions[ LightActions.candle] fire_uses = self._channels[channel].light_actions[ LightActions.fire] # Check that the number of use is under the limit if not self._simple_mode and key in (LightActions.candle, LightActions.fire): if (key == LightActions.candle and self._is_ge_than_max_uses( fire_uses, LightType.candle, message.author)): await channel.send(self._messages["NO_MORE_CANDLE"].format( todo_next=self._format_to_do_next( channel, LightType.candle))) break if (key == LightActions.fire and self._is_ge_than_max_uses( candle_uses, LightType.fire, message.author)): await channel.send( self._messages["NO_MORE_MATCHES"].format( todo_next=self._format_to_do_next( channel, LightType.candle))) break # Check that both candle and fire have been sent self._channels[channel].light_actions[key][message.author] += 1 nb_candle_uses = sum(candle_uses.values()) nb_fire_uses = sum(fire_uses.values()) if ((key == LightActions.candle and nb_candle_uses < nb_fire_uses) or (key == LightActions.fire and nb_candle_uses > nb_fire_uses)): self._channels[channel].current_light = LightType.candle await self._send_next_image(channel) else: # register the action, but do nothing (wait for the second emoji) if candle_uses and not fire_uses: # first use of an emoji candle await channel.send(self._messages["CANDLE_TIP"]) elif not candle_uses and fire_uses: # first use of an emoji candle await channel.send(self._messages["FIRE_TIP"]) break # Candle / level SIMPLE if self._simple_mode and key == LightActions.candle: if self._is_ge_than_max_uses(candle_uses, LightType.candle, message.author): await channel.send(self._messages["NO_MORE_CANDLE"].format( todo_next=self._format_to_do_next( channel, LightType.candle))) break self._channels[channel].light_actions[key][message.author] += 1 self._channels[channel].current_light = LightType.candle await self._send_next_image(channel) # Fire / level SIMPLE if self._simple_mode and key == LightActions.fire: if self._is_ge_than_max_uses(fire_uses, LightType.fire, message.author): await channel.send( self._messages["NO_MORE_MATCHES"].format( todo_next=self._format_to_do_next( channel, LightType.fire))) break self._channels[channel].light_actions[key][message.author] += 1 self._channels[channel].current_light = LightType.fire await self._send_next_image(channel) # Battery (+ flashlight already present) / levels SIMPLE, STANDARD battery_uses = self._channels[channel].light_actions[ LightActions.battery] if key == LightActions.battery: if self._is_ge_than_max_uses(battery_uses, LightType.flashlight, message.author): await channel.send( self._messages["NO_MORE_BATTERY"].format( todo_next=self._format_to_do_next( channel, LightType.flashlight))) break self._channels[channel].light_actions[key][message.author] += 1 self._channels[channel].current_light = LightType.flashlight await self._send_next_image(channel) # Check GameActions emojis for key, has_been_done in self._channels[channel].actions_done.items(): if message.content != key: continue if has_been_done or not self._channels[channel].objects_found[key]: continue self._channels[channel].actions_done[key] = True if key == GameActions.handbag: self._channels[channel].special = True await channel.send(self._messages["SPECIAL"]) elif key == GameActions.map: await self.on_map_found(message.channel) elif key == GameActions.chest: await self.on_chest_found(message.channel) # Check victory: chest and map found if (self._channels[channel].actions_done[GameActions.map] and self._channels[channel].actions_done[GameActions.chest]): await self.on_channel_victory(channel)