예제 #1
0
 def __init__(self, **kwargs):
     self._correct_answers_proportion = kwargs.pop(
         "correct_answers_proportions", 0.2)
     # all optional answers = optional_answers_bonus_proportion of correct answers
     self._optional_answers_bonus_proportion = kwargs.pop(
         "optional_answers_bonus_proportion", 0.5)
     self._voice_channel_description = ChannelCollection.get(
         kwargs.pop("voice_channel_description", "ROOM2_VOICE"))
     self._back_channel_description = ChannelCollection.get(
         kwargs.pop("back_channel_description", "AUDIO_BACK"))
     self._singer_role_description = RoleCollection.get(
         kwargs.pop("singer_role_description", "SINGER"))
     self._character_description = CharacterCollection.get(
         kwargs.pop("character_description", "CHARACTER2"))
     self._ignored_roles_descriptions = [
         RoleCollection.get(role_name) for role_name in kwargs.pop(
             "ignored_roles_descriptions", ["DEV", "MASTER"])
     ]
     super().__init__(**kwargs)
     self._simple_mode = None  # No simple mode
     self._channels = ChannelGameStatuses(AskWordsChannelStatus)
     self._nb_mandatory = len(self._messages["MANDATORY_ANSWERS"])
     self._nb_correct = len(self._messages["CORRECT_ANSWERS"])
     self._nb_optional = len(self._messages["OPTIONAL_ANSWERS"])
     if self._nb_optional:
         self._factor_optional = self._optional_answers_bonus_proportion * self._nb_correct / self._nb_optional
     else:
         self._factor_optional = 0
    def __init__(self, **kwargs):
        self._introduction_channel_d = ChannelCollection.get(kwargs.pop("introduction_channel", "WELCOME"))
        self._support_channel_d = ChannelCollection.get(kwargs.pop("support_channel", "SUPPORT"))
        self._master_role_description = RoleCollection.get(kwargs.pop("master_role_description", "MASTER"))
        self._default_role_description = RoleCollection.get(
            kwargs.pop("default_role_description", "DEFAULT"))  # no right
        self._visitor_role_description = RoleCollection.get(
            kwargs.pop("visitor_role_description", "VISITOR"))  # see/send
        self._emoji_to_team_role_key = OrderedDict([(k, RoleCollection.get(v)) for k, v in kwargs.pop(
            "emoji_to_team_role_key",
            OrderedDict([(Emojis.red_circle, "TEAM1"), (Emojis.blue_circle, "TEAM2"), (Emojis.white_circle, "TEAM3")])
        ).items()])
        self._character_role_descriptions_dict = {
            key: RoleCollection.get(role_key)
            for key, role_key in kwargs.pop("character_role_descriptions_dict",
                                            {"character_1": "CHARACTER1", "character_2": "CHARACTER2",
                                             "character_3": "CHARACTER3", "character_4": "CHARACTER4"}).items()}
        self._nb_teams = kwargs.pop("nb_teams", 3)
        self._max_number_per_team = kwargs.pop("max_number_per_team", 8)

        super().__init__(**kwargs)
        self._step = 0
        self._max_step = 5
        self._counter_2_to_3 = 0
        self._rolemenu_manager = None
        self._rules_msg_id = None
        self._choose_team_msg = None
        self._nb_players = None
        self._nb_teams_command = "!teams"
예제 #3
0
 def __init__(self, **kwargs):
     description_names = kwargs.pop("channel_descriptions", None)
     self._channel_descriptions = ChannelCollection.to_list() if description_names is None \
         else [ChannelCollection.get(name) for name in description_names]
     self._init_channel_description = ChannelCollection.get(kwargs.pop("init_channel_description", "WELCOME"))
     self._visitor_role_description = RoleCollection.get(kwargs.pop("visitor_role_description", "VISITOR"))
     super().__init__(**kwargs)
예제 #4
0
 def __init__(self, **kwargs):
     self._commands_channel_description = ChannelCollection.get(
         kwargs.pop("commands_channel_description", "COMMANDS"))
     self._init_channel_description = ChannelCollection.get(
         kwargs.pop("init_channel_description", "WELCOME"))
     self._visitor_role_description = RoleCollection.get(
         kwargs.pop("visitor_role_description", "VISITOR"))
     super().__init__(**kwargs)
     self._simple_mode = None
예제 #5
0
 async def plage_en_jungle(self, message, args):
     channels = [
         ChannelCollection.get("BOAT1").object_reference,
         ChannelCollection.get("BOAT2").object_reference,
         ChannelCollection.get("BOAT_VOICE1").object_reference,
         ChannelCollection.get("BOAT_VOICE2").object_reference
     ]
     for channel in channels:
         await channel.edit(name="La jungle")
     await self._memo_channel_description.object_reference.send(
         f"OK step {message.content}")
예제 #6
0
    def __init__(self, **kwargs):
        self._text_channel_d = ChannelCollection.get(
            kwargs.pop("text_channel_description", "MAIN_ROOM"))
        self._voice_channel_d = ChannelCollection.get(
            kwargs.pop("voice_channel_description", "RESTRICTED_ROOM"))

        super().__init__(**kwargs)
        self._simple_mode = None  # No simple mode
        self._text_channel: Optional[TextChannel] = None
        self._voice_channel: Optional[VoiceChannel] = None
        self._emojis_done = set()
        self._first_victory = False
예제 #7
0
 async def cacher_embarquement(self, message, args):
     channels = [
         ChannelCollection.get("WELCOME").object_reference,
         ChannelCollection.get("SUPPORT_VOICE").object_reference
     ]
     for channel in channels:
         await channel.edit(
             overwrites={
                 RoleCollection.get("DEFAULT").object_reference:
                 PermissionOverwrite(view_channel=False)
             })
     await self._memo_channel_description.object_reference.send(
         f"OK step {message.content}")
예제 #8
0
 async def plage_commune(self, message, args):
     channels = [
         ChannelCollection.get("MAIN_ROOM").object_reference,
         ChannelCollection.get("MAIN_ROOM_VOICE").object_reference
     ]
     for channel in channels:
         await channel.edit(
             overwrites={
                 RoleCollection.get("DEFAULT").object_reference:
                 PermissionOverwrite(view_channel=True)
             })
     await self._memo_channel_description.object_reference.send(
         f"OK step {message.content}")
def _check_guild(guild: Guild):
    """Check that the guild has a correct configuration. Some properties may not be tested."""
    logger.info("Checking game guild !")
    errors_bot_role = _check_bot_privileges(guild)
    if errors_bot_role:
        return errors_bot_role
    guild_channels = guild.channels
    errors = []
    for ch_descr in CategoryChannelCollection.to_list():
        check_channel_description(
            ch_descr,
            guild,
            guild_channels,
            errors,
            allowed_role_descriptions=RoleCollection.to_list())

    for ch_descr in ChannelCollection.to_list():
        check_channel_description(
            ch_descr,
            guild,
            guild_channels,
            errors,
            allowed_role_descriptions=RoleCollection.to_list())

    for r_descr in RoleCollection.to_list():
        check_role_description(r_descr, guild, errors)
    return errors
예제 #10
0
 def __init__(self, **kwargs):
     kwargs["prefix"] = kwargs.get("prefix", ">")
     self._log_webhook_description = CharacterCollection.get(kwargs.pop("log_webhook_description", "LOG"))
     self._events_channel_description = ChannelCollection.get(kwargs.pop("events_channel_description", "EVENTS"))
     super().__init__(**kwargs)
     self._logger_handler_added = False
     self._logging_handler = None
예제 #11
0
 def __init__(self, **kwargs):
     self._voice_channel_d = ChannelCollection.get(
         kwargs.pop("voice_channel_description", "RESTRICTED_ROOM"))
     super().__init__(**kwargs)
     self._simple_mode = None  # No simple mode
     self._sound_tools: SoundTools = None
     self._voice_channel: Optional[VoiceChannel] = None
예제 #12
0
async def init_guild(guild_wrapper) -> bool:
    """Coroutine to initialize a new a guild or to reset it when the version has changed."""
    # Print information on the guild
    logger.info(get_guild_info(BOT, guild_wrapper))
    logger.info(get_members_info(guild_wrapper))
    logger.info(get_roles_info(guild_wrapper))
    logger.info(get_channels_info(guild_wrapper))

    # Get existing channels and roles, but do not set/create/update anything
    await fetch_roles(guild_wrapper, RoleCollection.to_list())
    await fetch_channels(guild_wrapper, CategoryChannelCollection.to_list())
    await fetch_channels(guild_wrapper, ChannelCollection.to_list())

    # Add guild listeners and show the control panel
    await guild_wrapper.add_listeners(UtilsList(guild_wrapper))  # add utils
    await guild_wrapper.add_listeners(
        MinigameCollection.get_guild_instances(guild_wrapper))  # add minigames
    if VERBOSE >= 10:
        await guild_wrapper.listener_manager.show_control_panel(
            guild_wrapper.guild)  # show control panel

    # Send a success message
    try:
        channel = await get_safe_text_channel(guild_wrapper.guild,
                                              "BOARD",
                                              create=False)
        if VERBOSE >= 10:
            await channel.send("Bot redémarré !")
    except discord.DiscordException as err:
        logger.error(f"Failed to send reboot message: {err}")
        return False
    else:
        logger.info("Guild initialized successfully")
        return True
예제 #13
0
 async def coins_de_plage(self, message, args):
     strings = [f"ROOM{i}{j}" for i in (1, 2) for j in (1, 2, 3, 4, 5, 6)]
     channels = [
         ChannelCollection.get(string).object_reference
         for string in strings
     ]
     for channel in channels:
         await channel.edit(sync_permissions=True)
     await self._memo_channel_description.object_reference.send(
         f"OK step {message.content}")
예제 #14
0
 def __init__(self, **kwargs):
     self._next_minigame_class_d = MinigameCollection.get(
         kwargs.pop("next_minigame_class", None))
     self._next_channel_description = ChannelCollection.get(
         kwargs.pop("next_channel_description", "ATTIC1"))
     self._master_role_description = RoleCollection.get(
         kwargs.pop("master_role_description", "MASTER"))
     super().__init__(**kwargs)
     self._channels: ChannelGameStatuses = ChannelGameStatuses(
         FTRGameStatus)
예제 #15
0
async def update_guild_channels(guild: Guild,
                                delete_old=False,
                                clear_references=True) -> bool:
    logger.info("Doing: update server channels")
    upd_ok = await update_channels(guild,
                                   CategoryChannelCollection.to_list() +
                                   ChannelCollection.to_list(),
                                   delete_old=delete_old,
                                   clear_references=clear_references)
    logger.info(
        f"Done{'' if upd_ok else ' with errors'}: update server channels")
    return upd_ok
예제 #16
0
    async def update_guild(guild, origin_channel: TextChannel = None, force=False, clear_references=True):
        force_str = ' (forced update)' if force else ''
        logger.debug(f"Updating roles and channels!{force_str}")
        bot_msg = None
        try:
            bot_msg = await origin_channel.send(f"Updating roles and channels{force_str}...")
        except NotFound:
            pass
        errors = []

        # Roles + ensure the bot has the BOT role
        # (necessary for role hierarchy, because the automatic bot role has bad position (bug in discord.py ?))
        if RoleCollection.BOT.object_reference and not RoleCollection.BOT.has_the_role(guild.me):
            await guild.me.edit(roles=guild.me.roles + [RoleCollection.BOT.object_reference])
        if not await update_guild_roles(guild, delete_old=force, clear_references=clear_references):
            errors.append("guild roles")
        if RoleCollection.BOT.object_reference and not RoleCollection.BOT.has_the_role(guild.me):
            await guild.me.edit(roles=guild.me.roles + [RoleCollection.BOT.object_reference])

        # Channels + ensure the board is always present
        board_channel_reference = getattr(getattr(ChannelCollection.get("BOARD"), "object_reference", None), "id", None)
        if not await update_guild_channels(guild, delete_old=force, clear_references=clear_references):
            errors.append("guild channels")
        new_board_channel_reference = getattr(getattr(ChannelCollection.get("BOARD"), "object_reference", None), "id",
                                              None)
        if board_channel_reference != new_board_channel_reference:
            logger.info("Board channel has just changed! Creating a new board...")
            await GuildManager().get_guild(guild).show_control_panel()

        # Guild + bot + webhooks
        if not await update_guild_properties(guild):
            errors.append("guild properties")

        errors_str = "" if not errors else "\nERRORS (please check the server with ✅): " + ", ".join(errors)
        try:
            if bot_msg:
                await bot_msg.edit(content=f"Roles and channels updated!{force_str}{errors_str}")
        except discord.NotFound:
            pass
        logger.debug(f"Roles and channels updated!{force_str}{errors_str}")
예제 #17
0
    def __init__(self, **kwargs):
        self._minimum_rooms_to_explore: Optional[int] = kwargs.pop(
            "minimum_rooms_to_explore", None)  # None for maximum
        self._text_channel_d = ChannelCollection.get(
            kwargs.pop("text_channel_description", "ROOM3"))
        self._voice_channel_d = ChannelCollection.get(
            kwargs.pop("voice_channel_description", "ROOM4_VOICE"))
        self._matching_key = kwargs.pop(
            "matching_key",
            "name")  # change not recommended: key must be unique !

        super().__init__(**kwargs)
        self._simple_mode = None  # No simple mode
        self._text_channel: Optional[TextChannel] = None
        self._voice_channel: Optional[VoiceChannel] = None
        self._matches_done = {}
        self._correct_room = None
        self.current_room = None
        # noinspection PyTypeChecker
        self._sound_tools: SoundTools = None
        self._character_description = CharacterCollection.get(
            kwargs.pop("character_description", "CHARACTER3"))
    def __init__(self, **kwargs):
        self._master_channel_description = ChannelCollection.get(
            kwargs.pop("master_channel_description", "MEMO"))
        self._music_channel_description = ChannelCollection.get(
            kwargs.pop("music_channel_description", "MUSIC"))

        self._allowed_channels: Optional[
            Collection[ChannelDescription]] = self._get_collection_args(
                kwargs, "allowed_channels", self._default_allowed_channels,
                ChannelCollection)
        self._forbidden_channels: Optional[
            Collection[ChannelDescription]] = self._get_collection_args(
                kwargs, "forbidden_channels", self._default_forbidden_channels,
                ChannelCollection)
        self._allowed_roles: Optional[
            Collection[RoleDescription]] = self._get_collection_args(
                kwargs, "allowed_roles", self._default_allowed_roles,
                RoleCollection)
        self._forbidden_roles: Optional[
            Collection[RoleDescription]] = self._get_collection_args(
                kwargs, "forbidden_roles", self._default_forbidden_roles,
                RoleCollection)
        super().__init__(**kwargs)
예제 #19
0
 def __init__(self, **kwargs):
     self._image_remaining_duration = kwargs.pop("image_remaining_duration",
                                                 10)
     self._interval_between_messages = kwargs.pop(
         "interval_between_messages", 15)
     self._max_use_flashlight = kwargs.pop("max_use_flashlight", 4)
     self._max_use_candle = kwargs.pop("max_use_candle", 3)
     self._max_use_matches = kwargs.pop("max_use_matches", 3)
     self._master_role_description = RoleCollection.get(
         kwargs.pop("master_role_description", "MASTER"))
     self._map_channel_description = ChannelCollection.get(
         kwargs.pop("map_channel_description", "MAP_ROOM1"))
     self._map_channel_minigame_d = MinigameCollection.get(
         kwargs.pop("map_channel_minigame", "MAP"))
     self._map_channel_minigame_simple_d = MinigameCollection.get(
         kwargs.pop("map_channel_minigame_simple", "MAP2"))
     self._chest_channel_description = ChannelCollection.get(
         kwargs.pop("chest_channel_description", "CHEST_ROOM1"))
     self._chest_channel_minigame_d = MinigameCollection.get(
         kwargs.pop("chest_channel_minigame", "CHEST"))
     self._max_uses_type = MaxUsesType[kwargs.pop("max_uses_type",
                                                  "GLOBAL")]
     super().__init__(**kwargs)
     self._channels = ChannelGameStatuses(AtticGameChannelStatus)
예제 #20
0
 def __init__(self, **kwargs):
     self._next_minigame_class_d = MinigameCollection.get(
         kwargs.pop("next_minigame_class", "KITCHEN"))
     self._next_channel_description = ChannelCollection.get(
         kwargs.pop("next_channel_description", "KITCHEN1"))
     self._ignored_role_descriptions = [
         RoleCollection.get(item)
         for item in kwargs.pop("ignored_role_descriptions", ["MASTER"])
     ]
     self._allowed_role_descriptions = [
         RoleCollection.get(item)
         for item in kwargs.pop("allowed_role_descriptions", ["VISITOR"])
     ]
     super().__init__(**kwargs)
     self._channels = ChannelGameStatuses(CountEveryoneChannelStatus)
예제 #21
0
async def clean_channels(channels, limit=None, ignore="default", force=None):
    if ignore == "default":
        ignore = [CategoryChannelCollection.MASTER.value, CategoryChannelCollection.DEV.value]
    ignore = ignore or []
    force = force or []
    filtered_channels = filter_channels(channels, ignore, force)
    logger.info(f"Cleaning channels {filtered_channels}")
    result = True
    for channel_enum in ChannelCollection.to_list():
        channel = channel_enum.value.object_reference
        if channel is None or channel not in filtered_channels:
            continue
        if not await clean_channel(channel, limit):
            result = False
    logger.info("Channels cleared!")
    return result
async def get_safe_text_channel(guild: Guild,
                                name_key="MEMO",
                                create=True) -> Optional[TextChannel]:
    # If create: prefer create a new channel instead of joining an existing one.
    # First: check if a channel with the corresponding name_key is available
    channel_description: ChannelDescription = ChannelCollection.get(
        name_key, None)
    if channel_description and channel_description.channel_type is ChannelType.text:
        channel = channel_description.object_reference
        if channel and channel.guild.id == guild.id and channel.permissions_for(
                guild.me).send_messages:
            return channel
        elif create:  # If create, create a channel corresponding to the description
            if await channel_description.create_object(
                    guild, raises_on_category_error=False):
                return channel_description.object_reference

    # If not found and not create, look for a random channel with send_messages rights
    if not create:
        for channel in [
                _channel for _channel in guild.channels
                if isinstance(_channel, TextChannel)
        ]:
            if channel.permissions_for(guild.me).send_messages:
                return channel
        logger.warning("No safe channel with send_messages available!")
        return None

    # If create, create a channel with the name_key
    channel_description = ChannelDescription(name=name_key,
                                             channel_type=ChannelType.text)
    try:
        return await guild.create_text_channel(name=channel_description.name,
                                               reason="No existing channel")
    except Exception as err:
        logger.error(err)
        return None
예제 #23
0
 def __init__(self, **kwargs):
     self._music_channel_description = ChannelCollection.get(
         kwargs.pop("music_channel_description", "MUSIC"))
     super().__init__(**kwargs)
예제 #24
0
 def __init__(self, **kwargs):
     self._events_channel_description = ChannelCollection.get(kwargs.pop("events_channel_description", "COMMANDS"))
     super().__init__(**kwargs)
예제 #25
0
async def show_channels(channel: TextChannel):
    await long_send(channel, CategoryChannelCollection.to_str() + "\n" + ChannelCollection.to_str(), quotes=True)
예제 #26
0
 def __init__(self, **kwargs):
     self._memo_channel_description = ChannelCollection.get(
         kwargs.pop("memo_channel_description", "MEMO"))
     super().__init__(**kwargs)
     self._simple_mode = None
예제 #27
0
async def fetch(guild):
    await fetch_roles(guild, RoleCollection.to_list())
    await fetch_channels(guild, CategoryChannelCollection.to_list())
    await fetch_channels(guild, ChannelCollection.to_list())
    logger.debug("Channels fetched")
예제 #28
0
def clear_object_references():
    RoleCollection.reset_object_references()
    ChannelCollection.reset_object_references()
    CategoryChannelCollection.reset_object_references()
    CharacterCollection.reset_object_references()
    GuildCollection.reset_object_references()