Ruby-Cogs/extendedcommands/extendedcommands.py

116 lines
No EOL
4.2 KiB
Python

from redbot.core import commands, Config
from redbot.core.bot import Red
import discord
import shlex
import asyncio
class ExtendedCommands(commands.Cog):
"""Extended command functionality for Red bots."""
def __init__(self, bot: Red):
self.bot = bot
self.config = Config.get_conf(self, identifier=867530998, force_registration=True)
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
if message.author.bot:
return
# Check if message starts with any bot prefix
prefixes = await self.bot.get_valid_prefixes(message.guild)
has_prefix = False
content = message.content
prefix_used = None
for prefix in prefixes:
if content.startswith(prefix):
has_prefix = True
prefix_used = prefix
content = content[len(prefix):]
break
if not has_prefix:
return
# Check if message contains &&
if "&&" not in content:
return
# Stop the original message from triggering commands
message._process_commands = False
# Split commands and execute them in sequence
commands_to_run = [cmd.strip() for cmd in content.split("&&")]
async with message.channel.typing():
for cmd in commands_to_run:
if not cmd: # Skip empty commands
continue
# Create a new message object with the command
new_message = discord.Message(
state=message._state,
channel=message.channel,
data={
"id": message.id,
"content": prefix_used + cmd, # Use the prefix that was used
"author": message.author.to_dict(),
"pinned": False,
"mention_everyone": False,
"tts": False,
"type": 0,
"flags": 0,
}
)
try:
# Process the command
await self.bot.process_commands(new_message)
# Add a small delay between commands
await asyncio.sleep(0.5)
except Exception as e:
await message.channel.send(f"Error executing command `{cmd}`: {str(e)}")
break # Stop executing remaining commands on error
@commands.command()
async def chain(self, ctx: commands.Context, *, commands_str: str):
"""Chain multiple commands together using &&.
Example:
[p]chain ping && info && glb show
"""
if "&&" not in commands_str:
await ctx.send("Please provide multiple commands separated by &&")
return
commands_to_run = [cmd.strip() for cmd in commands_str.split("&&")]
async with ctx.typing():
for cmd in commands_to_run:
if not cmd: # Skip empty commands
continue
# Create a new message object with the command
new_message = discord.Message(
state=ctx.message._state,
channel=ctx.channel,
data={
"id": ctx.message.id,
"content": ctx.prefix + cmd,
"author": ctx.author.to_dict(),
"pinned": False,
"mention_everyone": False,
"tts": False,
"type": 0,
"flags": 0,
}
)
try:
# Process the command
await self.bot.process_commands(new_message)
# Add a small delay between commands
await asyncio.sleep(0.5)
except Exception as e:
await ctx.send(f"Error executing command `{cmd}`: {str(e)}")
break # Stop executing remaining commands on error