Exemple #1
0
    async def add_commands(self, slash: SlashCommand):
        slash.add_slash_command(
            self.database_command,
            name=self.configuration.get("command_prefix", "") +
            "database-inspect",
            description=
            "Consult the Randovania's logic database for one specific room.",
            guild_ids=None,
            options=[
                manage_commands.create_option(
                    "game",
                    "The game's database to check.",
                    option_type=SlashCommandOptionType.STRING,
                    required=True,
                    choices=[
                        manage_commands.create_choice(game.value,
                                                      game.long_name)
                        for game in enum_lib.iterate_enum(RandovaniaGame)
                    ])
            ],
        )

        def add_id(custom_id: str, call, **kwargs):
            self._on_database_component_listener[
                custom_id] = functools.partial(call, **kwargs)

        for game in enum_lib.iterate_enum(RandovaniaGame):
            db = default_database.game_description_for(game)
            world_options = await create_split_worlds(db)
            self._split_worlds[game] = world_options

            add_id(f"{game.value}_world",
                   self.on_database_world_selected,
                   game=game)
            add_id(f"back_to_{game.value}",
                   self.on_database_back_to_game,
                   game=game)

            for i, split_world in enumerate(world_options):
                add_id(f"{game.value}_world_{i}",
                       self.on_database_area_selected,
                       game=game,
                       split_world=split_world,
                       world_id=i)
                for j, area in enumerate(split_world.areas):
                    add_id(f"{game.value}_world_{i}_area_{j}",
                           self.on_area_node_selection,
                           game=game,
                           area=area)

        slash.add_component_callback(
            self.on_database_component,
            components=list(self._on_database_component_listener.keys()),
            use_callback_name=False,
        )
Exemple #2
0
    description="Return the latency of the bot",
    guild_ids=get_testing_guilds(),
)
async def ping(ctx):
    gotten_ping = client.latency * 1000
    print(f"Recorded ping: {gotten_ping} ms")
    await ctx.send(embed=Embed(
        title=":ping_pong: Pong!",
        description=f"{gotten_ping:.4} ms",
        color=Color.blue(),
    ))


slash.add_slash_command(
    igotpinged.igotpinged,
    name="igotpinged",  # TODO: Add "whopingedme" alias
    description="Get the person who pinged you ever since your last message",
    guild_ids=get_testing_guilds(),
)
slash.add_slash_command(
    cc.cc,
    name="cc",
    description="CC other people your last message",
    guild_ids=get_testing_guilds(),
    options=cc.create_person_options(10),
)
slash.add_slash_command(
    cc.bcc,
    name="bcc",
    description="BCC other people your last message",
    guild_ids=get_testing_guilds(),
    options=cc.create_person_options(10),
Exemple #3
0
class Bot(commands.Bot):
    @classmethod
    def create(cls):
        bot = Bot(env=env, storage=storage, config=config, db=db)
        # bot = Bot(env=env.env, storage=storage.storage, config=config.config, db=db.db)
        return bot

    def __init__(self, env, storage, config, db):
        self.env = env
        self.storage = storage
        self.config = config
        self.db = db
        intents = discord.Intents.default()
        intents.members = True

        # we are moving away from commands
        # but still want to support the main ones for a while
        print(f"setting prefix to {self.config['commands']['prefix']}")
        super().__init__(command_prefix=self.config['commands']['prefix'],
                         intents=intents)

        # "global" interactions without explicit guild_ids
        # take hours to register
        self.guild_ids = None
        override_guild_ids = env['GUILD_IDS']
        if override_guild_ids is not None:
            self.guild_ids = list(map(int, override_guild_ids.split(',')))
            print(
                f"setting guild_ids to {self.guild_ids} for faster slash command registration"
            )

        self.slash = SlashCommand(self,
                                  sync_commands=True,
                                  sync_on_cog_reload=True,
                                  override_type=True)
        self.add_slash_command(self.ping, name="ping")

        initial_cogs = [
            cogs.PresenceCog,
            cogs.PostingCog,
            cogs.WelcomeCog,
            cogs.RolerCog,
            cogs.AfterdarkCog,
            cogs.RealtalkCog,
            cogs.ActivityCog,
            cogs.LurkersCog,
            cogs.AnimeCog,
            cogs.NoveltyCog,
            cogs.AnnoyingCog,
        ]
        for cog in initial_cogs:
            self.add_cog(cog(self))

        # set the db up
        self.db.generate_mapping(create_tables=False)

        self.heartbeat_loop.start()

    def run(self) -> None:
        super().run(self.config['discord']['token'])

    def add_slash_command(self,
                          cmd: typing.Callable,
                          roles: typing.Optional[typing.Sequence] = None,
                          channels: typing.Optional[typing.Sequence] = None,
                          options: typing.Optional[typing.Sequence] = None,
                          **kwargs) -> None:
        async def wrapper(ctx: SlashContext, cmd=cmd, **kwargs):
            return await cmd(ctx, **kwargs)

        def check_channels(channels: typing.Sequence):
            def predicate(ctx: SlashContext):
                print(f"channels: {channels}")
                if channels is None: return True
                for channel in channels:
                    name = self.config['channels'].get(channel, channel)
                    if ctx.channel.name == name:
                        return True
                return False

            return commands.check(predicate)

        cmd = check_channels(channels)(wrapper)

        if roles is not None:
            cmd = commands.has_any_role(*roles)(cmd)

        # have to set a dummy list to prevent
        # discord_slash from probing our cmd's args
        if options is None:
            options = []

        return self.slash.add_slash_command(cmd,
                                            guild_ids=self.guild_ids,
                                            options=options,
                                            **kwargs)

    # on a regular interval we will dispatch a heartbeat to cogs
    @tasks.loop(seconds=10.0)
    async def heartbeat_loop(self) -> None:
        if not self.is_closed():
            self.dispatch('heartbeat')

    @heartbeat_loop.before_loop
    async def before_heartbeat_loop(self):
        print("waiting for bot to be ready")
        await self.wait_until_ready()
        print("bot is ready")

    async def on_ready(self):
        print("on_ready")

    async def on_slash_command_error(self, ctx, ex):
        print('on_slash_command_error')
        if isinstance(ex, discord.ext.commands.errors.MissingAnyRole):
            await ctx.channel.send("Permission check failed")
        elif isinstance(ex, discord_slash.error.CheckFailure):
            await ctx.channel.send("Channel check failed")
        else:
            await ctx.channel.send('Oopsie woopsie')
            print(ex)
            # raise ex

    async def ping(self, ctx: SlashContext) -> None:
        print("ping")
        await ctx.send(content='pong')