116 lines
No EOL
4.2 KiB
Python
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 |