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"
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)
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
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}")
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
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}")
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
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
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
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
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}")
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)
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
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}")
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)
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)
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)
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
def __init__(self, **kwargs): self._music_channel_description = ChannelCollection.get( kwargs.pop("music_channel_description", "MUSIC")) super().__init__(**kwargs)
def __init__(self, **kwargs): self._events_channel_description = ChannelCollection.get(kwargs.pop("events_channel_description", "COMMANDS")) super().__init__(**kwargs)
async def show_channels(channel: TextChannel): await long_send(channel, CategoryChannelCollection.to_str() + "\n" + ChannelCollection.to_str(), quotes=True)
def __init__(self, **kwargs): self._memo_channel_description = ChannelCollection.get( kwargs.pop("memo_channel_description", "MEMO")) super().__init__(**kwargs) self._simple_mode = None
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")
def clear_object_references(): RoleCollection.reset_object_references() ChannelCollection.reset_object_references() CategoryChannelCollection.reset_object_references() CharacterCollection.reset_object_references() GuildCollection.reset_object_references()