예제 #1
0
    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}"
            )
예제 #2
0
    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)
예제 #3
0
    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))
예제 #4
0
    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))
예제 #5
0
    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)
예제 #6
0
    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)