def add_command(self, command: commands.Command): super().add_command(command) # 2 SEC NEEDED TO RUN A COMMAND command.cooldown_after_parsing = True if not getattr(command._buckets, "_cooldown", None): command._buckets = commands.CooldownMapping.from_cooldown( 1, 2, commands.BucketType.user)
async def _transform_command_help(self, command: commands.Command): await self.bot.wait_until_ready() format_mapping = self.bot.mk.to_dict() format_mapping["COMMAND"] = command.qualified_name format_mapping["PREFIX"] = config.BOT_PREFIX command.help = command.help.format_map(format_mapping)
def load_commands(self): '''Load commands from the Commands class. ''' cmds = Commands() for cmd in [func for func in dir(cmds) if callable(getattr(cmds, func)) and not func.startswith("__")]: self.add_command(Command(cmd, getattr(cmds, cmd)))
def can_run_recursive(self, ctx, command: Command): try: can_run = command.can_run(ctx) except CheckFailure: return False else: return can_run
def add_formatter(self, formatter: Callable[[str], str], name: str, doc: str) -> None: """creates and registers a command from a simple text formatter""" async def func(ctx, *, text: str): await ctx.send(formatter(text)) command = Command(func, name=name, help=doc) self.add_command(command)
def inner(func): cls = Command(func) bot.add_command(cls) Commands.get_instance().register(cls.qualified_name, kwargs['desc'], kwargs.get('params'), cls.module.rsplit('.', 1)[1]) return func
def __init__(self, bot: Bot): Plugin.set_cvar_once("qlx_discordAdminPassword", "supersecret") Plugin.set_cvar_once("qlx_discordAuthCommand", "auth") Plugin.set_cvar_once("qlx_discordExecPrefix", "qlx") self.bot = bot self.authed_discord_ids: set[int] = set() self.auth_attempts: dict[int:int] = {} self.discord_admin_password: str = Plugin.get_cvar( "qlx_discordAdminPassword") self.discord_auth_command: str = Plugin.get_cvar( "qlx_discordAuthCommand") self.discord_exec_prefix: str = Plugin.get_cvar( "qlx_discordExecPrefix") self.bot.add_command( Command(self.auth, name=self.discord_auth_command, checks=[ self.is_private_message, lambda ctx: not self.is_authed(ctx), lambda ctx: not self.is_barred_from_auth(ctx) ], hidden=True, pass_context=True, help="auth with the bot", require_var_positional=True)) self.bot.add_command( Command(self.qlx, name=self.discord_exec_prefix, checks=[self.is_private_message, self.is_authed], hidden=True, pass_context=True, help="execute minqlx commands on the server", require_var_positional=True)) self.bot.tree.add_command( app_commands.Command( name=self.discord_exec_prefix, description="execute minqlx commands on the server", callback=self.slash_qlx, parent=None, nsfw=False)) super().__init__()
def kaz_preprocess(self, command: commands.Command, bot: commands.Bot): if command is not bot: # command or cog - not the bot itself try: data = self.parser.parse(command, bot) except NotKazhelpError: logger.info("Non-!kazhelp for command '{!s}'".format(command)) else: logger.debug("Parsed !kazhelp for command '{!s}'".format(command)) if isinstance(command, commands.Command): command.description = self._format_links(self._fix_paragraphs(data['description'])) command.brief = self._format_links(self._fix_paragraphs(data['brief'] or data['description'])) command.help = self._format_links(self._build_detailed_info(data)) if isinstance(command, commands.GroupMixin): command.help += '\n\n' + self._make_title("SUB-COMMANDS") else: # cog command.__doc__ = self._format_links( self._fix_paragraphs(data['description']) + '\n\n' + self._build_detailed_info(data) )
async def parse_args(self, context, command: Command, values): mappings = {item["name"]: item["value"] for item in values} parsed = {} for name, param in command.clean_params.items(): converter = command._get_converter(param) mapping = mappings.get(name) if mapping is None: continue parsed[name] = await command.do_conversion(context, converter, mapping, name) return parsed
def wrapper(command: Command) -> Command: # NOTE: this could be changed if a subclass of Command were to be used if not isinstance(command, Command): raise TypeError( 'Decorator `cooldown_with_role_bypass` must be applied after the command decorator. ' 'This means it has to be above the command decorator in the code.' ) command._before_invoke = predicate return command
def wrapper(command: Command) -> Command: # NOTE: this could be changed if a subclass of Command were to be used. I didn't see the need for it # so I just made it raise an error when the decorator is applied before the actual command object exists. # # if the `before_invoke` detail is ever a problem then I can quickly just swap over. if not isinstance(command, Command): raise TypeError('Decorator `cooldown_with_role_bypass` must be applied after the command decorator. ' 'This means it has to be above the command decorator in the code.') command._before_invoke = predicate return command
def __call__(self, command: Command): if command.parent is None: # Use state to order these top-level commands since the cog isn't # bound yet and therefore we can't query the command count order = self.top_level_order self.top_level_order += 1 else: # Order by parent's commands count order = len(command.parent.commands) - 1 command.__original_kwargs__['order'] = order return command
def __new__(cls, name, bases, attrs, *, generator: BaseImageGenerator, **kwargs): for attr_name in dir(generator): attr = getattr(generator, attr_name) if not getattr(attr, "__image_generator__", False): continue signature = inspect.signature(attr) params = signature.parameters if len(params) == 2 and list(params.values())[1].annotation == ImageType: cmd = Command(image_paste_command(attr_name), name=attr_name) elif all([p.annotation == str for p in list(params.values())[1:]]): cmd = Command( text_write_command(attr_name, len(params) - 1), name=attr_name ) else: raise RuntimeError("Unknown image generator args") cooldown(1, 5, BucketType.user)(cmd) attrs[attr.__name__] = cmd self = super().__new__(cls, name, bases, attrs, **kwargs) return self
def generate_command(self, task: ScheduledTask): controller = self.core.get_controller(task.extension_name) method = getattr(controller, task.method_name) signature = inspect.signature(method) first_param = next(iter(signature.parameters.values())) pass_context = first_param.name == 'ctx' or first_param.annotation is hero.Context if not pass_context: method = no_context_wrapper(method) func = partial(maybe_coroutine, method) # wrap in generated command to enable converting of kwargs return Command(func, name=f"scheduled_{task.extension_name}_{task.method_name}", parent=self.core)
def initialize_bot(self, discord_bot: discord.ext.commands.Bot) -> None: """ initializes a discord bot with commands and listeners on this pseudo cog class :param: discord_bot: the discord_bot to initialize """ discord_bot.add_listener(self.on_ready) discord_bot.add_listener(self.on_message) if self.discord_version_enabled: discord_bot.add_command( Command(self.version, name="version", pass_context=True, ignore_extra=False, help="display the plugin's version information"))
def __init__(self, cls, *, name=None, parent=None): kwargs = {'name': name or cls.__name__, 'parent': parent} func = cls.__call__ try: cls._CONFIG except AttributeError: pass else: kwargs.update(cls._CONFIG.to_dict()) super().__init__(func, **kwargs) for f in dir(cls): if f.startswith('_'): continue attr = getattr(cls, f) if inspect.isclass(attr): self.add_command(ClassGroup(attr, parent=self)) elif inspect.iscoroutinefunction(attr): self.add_command(Command(attr))
def __init__(self, bot: Bot): self.bot = bot Plugin.set_cvar_once("qlx_discordTriggerStatus", "status") Plugin.set_cvar_once("qlx_discord_ext_status_show_spectators", "0") Plugin.set_cvar_once("qlx_discordTriggeredChatMessagePrefix", "") Plugin.set_cvar_once("qlx_discordRelayChannelIds", "") Plugin.set_cvar_once("qlx_discordTriggeredChannelIds", "") self.discord_trigger_status: str = Plugin.get_cvar( "qlx_discordTriggerStatus") self.discord_triggered_channel_message_prefix: str = Plugin.get_cvar( "qlx_discordTriggeredChatMessagePrefix") self.discord_relay_channel_ids: set[int] = \ int_set(Plugin.get_cvar("qlx_discordRelayChannelIds", set)) self.discord_triggered_channel_ids: set[int] = int_set( Plugin.get_cvar("qlx_discordTriggeredChannelIds", set)) self.bot.add_command( Command(self.trigger_status, name=self.discord_trigger_status, checks=[self.is_message_in_relay_or_triggered_channel], pass_context=True, ignore_extra=False, help="display current game status information")) # noinspection PyTypeChecker slash_status_command = app_commands.Command( name=self.discord_trigger_status, description="display current game status information", callback=self.slash_trigger_status, parent=None, nsfw=False) slash_status_command.guild_only = True self.bot.tree.add_command(slash_status_command) super().__init__()
def __init__(self, bot: Bot): self.bot = bot Plugin.set_cvar_once("qlx_discordTriggeredChannelIds", "") Plugin.set_cvar_once("qlx_discordTriggerTriggeredChannelChat", "quakelive") Plugin.set_cvar_once("qlx_discordMessagePrefix", "[DISCORD]") self.discord_trigger_triggered_channel_chat: str = Plugin.get_cvar("qlx_discordTriggerTriggeredChannelChat") self.discord_message_prefix: str = Plugin.get_cvar("qlx_discordMessagePrefix") self.discord_triggered_channel_ids: set[int] = int_set( Plugin.get_cvar("qlx_discordTriggeredChannelIds", set)) self.bot.add_command(Command(self.triggered_chat, name=self.discord_trigger_triggered_channel_chat, checks=[self.is_message_in_triggered_channel], pass_context=True, help="send [message...] to the Quake Live server", require_var_positional=True)) # noinspection PyTypeChecker slash_triggered_chat_command = app_commands.Command(name=self.discord_trigger_triggered_channel_chat, description="send a message to the Quake Live server", callback=self.slash_triggered_chat, parent=None, nsfw=False) slash_triggered_chat_command.guild_only = True self.bot.tree.add_command(slash_triggered_chat_command)
def patch_command_signature(cmd: Command) -> Command: """Patches `discord.ext.commands.Command`'s `signature` method to ignore keyword-only parameters.""" cmd.signature = signature setattr(cmd, "help_doc", help_doc)
def __init__(self): super().__init__(command_prefix=';') self.add_command(Command(self.active))
def _add_command(self, bot: commands.Bot, command: commands.Command): if self.secret: command.hidden = True bot.add_command(command) self.commands.append(command)
await ctx.send(f"Try using `{ctx.prefix}encounter` again, this time you'll be prompted to capture the enemy.") await bot.wait_for("message", check=eigth_check(ctx)) enemy = await capture(ctx) await asyncio.sleep(2) await ctx.send(f"Sweet, you captured the {enemy.name}. Now if you use the command `{ctx.prefix}compendium`, " f"it'll show it's name in a table.") await bot.wait_for("message", check=ninth_check(ctx)) comp = player.compendium comp.bits[enemy.id-1] = 1 render = comp.format() await ctx.send(f"```\n{render}\n```") await asyncio.sleep(2) await ctx.send("And that's pretty much everything! Since your player is a tutorial player, I'll have to delete it.") await asyncio.sleep(2) await ctx.send("Try to remember everything that happened in this tutorial, and you should be fine.") await asyncio.sleep(2) await ctx.send("Good luck on your Adventure!") bot.in_tutorial.remove(ctx.author.id) del player tut = Command(tutorial) def setup(bot): bot.add_command(tut) def teardown(bot): bot.remove_command("tutorial")
def add_command(self, command: commands.Command) -> None: command.cooldown_after_parsing = True super().add_command(command)
def register_all(self): def check_perms(ctx): return ctx.author.id == 146483065223512064 or 703018636301828246 in [role.id for role in ctx.message.author.roles] async def set_channel(ctx, chntype, channel: TextChannelConverter): if not check_perms(ctx): return await ctx.send("This command is what's known as 'Don't touch it or things will blow up'") titan.config[chntype] = channel.id titan.save() await ctx.send("Messages for {} now redirecting to channel named \"{}\"".format(chntype, channel)) # Generic set_channel @self.client.command() async def set_cfg(ctx, ctype, value): if not check_perms(ctx): return await ctx.send("This command is what's known as 'Don't touch it or things will blow up'") titan.config[ctype] = value titan.save() await ctx.send("{} -> \"{}\"".format(ctype, value)) async def force_update(ctx): await app_task.checkforums(self.client.get_channel(titan.config["appChn"]), self.client) @commands.has_role("Trover") @self.client.group() async def trover(ctx): if not ctx.invoked_subcommand: await ctx.send("This is the Trovers command (Subcommands are available, this command does nothing)") @trover.command() async def lend(ctx, player: discord.User, item: str): titan.trovers["lend"].update({player.id: item}) titan.save_trovers() await ctx.send("{} has been lent a(n) {}".format(player, item)) @trover.command() async def returned(ctx, player: discord.User): await ctx.send("{} has been taken off the borrow-list after returning the {}".format(player, titan.trovers["lend"][str(player.id)])) del titan.trovers["lend"][str(player.id)] titan.save_trovers() @trover.error async def trover_error(ctx, error): await ctx.send(error) @has_permissions(administrator=True) @self.client.command() async def roles(ctx: commands.Context, user: discord.Member, mcname): await user.add_roles(*[x for x in ctx.guild.roles if x.name in titan.config["role_names"]]) await user.edit(nick=f"♙ Citizen {mcname}") await ctx.send("Roles added to the user {}".format(user)) @has_permissions(administrator=True) @self.client.command() async def promote(ctx, user: discord.Member, m_or_f): hier, hiermap, hiergroup = titan.config[f"hierarchy_names_{m_or_f}"], titan.config[f"hierarchy_names_{m_or_f}map"], titan.config["hierarchy_group"] rank_nominal = list({x.name for x in user.roles} & set(hier)) oldgroup = list({x.name for x in user.roles} & set(hiergroup)) newrank = hier[hier.index(rank_nominal[0])+1] await user.remove_roles(*[x for x in ctx.guild.roles if x.name in {oldgroup[0], rank_nominal[0]}]) await user.add_roles(*[x for x in ctx.guild.roles if x.name in {newrank, hiergroup[hiermap[newrank]]}]) name = user.nick.split(" ")[-1] await user.edit(nick=f"{hiergroup[hiermap[newrank]][0]} {newrank} {name}") await ctx.send("Promoted user {} to {}".format(user, newrank)) @roles.error async def roles_error(ctx, error): await ctx.send(error) @promote.error async def promote_error(ctx, error): await ctx.send(error) @self.client.command() async def online(ctx): membs = await activity_task.get_current_members() await ctx.send('```Wynn Online ({})\n'.format(len(membs))+'\n'.join(membs)+'```') @self.client.command() async def write_online(ctx): if check_perms(ctx): activity_task.write_online() await ctx.send("Done.") @self.client.command() async def activity(ctx, limit: int = 20): if check_perms(ctx): bar = await ctx.send("`-Progress bar will slow down the process by 400% \so it's not getting displayed anymore.-`") activity = await activity_task.get_members_activity(bar, activity_task.get_members_uuid()) now = datetime.utcnow().timestamp() activity = sorted(activity, key=lambda k: k[1]) msg = '```\n'+'\n'.join("%16s %7s" % (i, str((now-j)/3600/24)[:5] +'d') for i, j in activity[:limit])+'\n```' await bar.edit(content=msg) @commands.has_any_role("Titanbot GL", "Titans Brilliance", "Military") @self.client.command() async def ffa(ctx, guild, date_format): times = [] if date_format == "days": for ffa_name in titan.ffas["ffas"]: times.append([ffa_name, titan.ffas[ffa_name].get(guild,0)/60/60/24]) times = sorted(times, key=lambda x: x[1], reverse=True) await ctx.send(f'```\n{guild}\'s report\n------------\n'+'\n'.join("%20s %0.2f days" % (x[0], x[1]) for x in times)+'```') elif date_format == "h:m": for ffa_name in titan.ffas["ffas"]: hr = titan.ffas[ffa_name].get(guild,0)/60/60 mins = (hr-int(hr))*60 times.append([ffa_name, hr, mins]) times = sorted(times, key=lambda x: x[1], reverse=True) await ctx.send(f'```\n{guild}\'s report\n------------\n'+'\n'.join("%20s %d:%02d" % (x[0], x[1], x[2]) for x in times)+'```') @ffa.error async def ffa_error(ctx, error): await ctx.send(error) @commands.has_any_role("Titanbot GL", "Titans Brilliance", "Military") @self.client.command() async def ffa_clear(ctx): for key in titan.ffas.keys(): if key != "ffas": titan.ffas.update({key:{"latest":""}}) titan.save_ffas() await ctx.send("Cleared FFA History") @commands.has_any_role("Titanbot GL", "Titans Brilliance", "Military") @self.client.command() async def xp(ctx, hours=24, length=10): if hours < 1 or hours > 24: return await ctx.send("Please specify a time between 1 and 24 hours") leaderboard = requests.get(LEADURL).json() send = {} stored_data = titan.lead["last"][24-hours] for guild in leaderboard["data"]: exists = stored_data.get(guild["name"]) if not exists: continue send.update({guild["name"]:guild["xp"]-exists}) data = sorted(send.items(), key=lambda x: x[1], reverse=True)[:length] await ctx.send('```Guild XP Gain In the Last %d Hour(s) Report\n%s```' % (hours, '\n'.join("%20s %12d" % x for x in data))) @xp.error async def xp_error(ctx, error): await ctx.send(error) @commands.has_any_role("\u265cHigh Nobility", "\u265eNobility", "\u2658Minor Nobility", "♛ HM Parliament") @self.client.command() async def lockwarning(ctx, duration: int): titan.warning_timeout = time.time() + duration*60 await ctx.send(f"Locked territory warnings for {duration} minutes!") @commands.has_any_role("\u265cHigh Nobility", "\u265eNobility", "\u2658Minor Nobility", "♛ HM Parliament") @self.client.command() async def clear_lock(ctx): titan.warning_timeout = 0 await ctx.send("Cleared Warning Lock. Warning pings will now be sent again.") @commands.has_role("Survival") @self.client.command() async def survival(ctx): r = requests.get("https://api.mcsrvstat.us/2/136.243.138.207:25569").json() if r["online"]: if not r["players"].get("list"): return await ctx.send("```Server Online. No one on.```") return await ctx.send("```Server Online. Online ({}): \n{}```".format(len(r["players"]["list"]), '\n'.join(x for x in r["players"]["list"]))) await ctx.send("The server is offline") # ADD HAS ROLE CHECK @commands.has_permissions(administrator=True) @self.client.command() async def create_ticket_message(ctx): e = discord.Embed(title="React to submit an application!") e.description = "React to his message (click the ticket)" msg = await ctx.send(embed=e) titan.config["appMsg"] = msg.id titan.save() await msg.add_reaction("🎟️") # ADD HAS ROLE CHECK @self.client.command() async def debug(ctx): sheets.new_capt_apps() self.client.add_command(Command(set_channel)) self.client.add_command(Command(force_update))
def copy(self): ret: CCmd = _Command.copy(self) for cmd in map(lambda x: x.copy(), self.commands): ret.add_command(cmd) cmd.cogcmd = ret return ret
def any_checks(f: commands.Command): """Decorator to handle optional checks This Decorator will make any @checks placed below itself to be called with a logical OR. This means that if one or more return True, the command will be able to run .. note:: When using this decorator remember that you don't need to call it:: # correct @any_checks # incorrect @any_checks() Example ------- :: from dpytools.checks import any_checks @commands.guild_only() # This command must be called inside a server @any_checks # Place the decorator above the checks you with to compare using "OR" @commands.is_owner() # The command will run if ctx.author is the owner of the bot @commands.has_role('Admin') # __OR__ if ctx.author has the role "Admin" @bot.command() # this decorator transforms this function in a command async def test(ct): await ctx.send('The command works') .. warning:: This decorator makes it impossible to know which optional checks succeded or failed. .. note:: The decorator will raise CheckFailure if all checks below itself fail Raises ------ :class:`commands.CheckFailure` If all checks below itself fail. """ if not isinstance(f, commands.Command): raise TypeError( "This decorator must be placed above the @command decorator.") checks = copy(f.checks) async def async_any_checks(ctx): if len(checks) == 0: return True else: result = any([await _silent_except(c, ctx) for c in checks]) if result: return True else: raise commands.CheckFailure( f'All optional checks for command "{f.qualified_name}" failed' ) f.checks = [async_any_checks] return f