-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from ClanBadJas/dev
Merge Dev to Master for version 2.0
- Loading branch information
Showing
9 changed files
with
599 additions
and
408 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import functools | ||
|
||
import discord | ||
|
||
import settings | ||
|
||
|
||
class LogSelect(discord.ui.Select): | ||
valueToLabel = {} | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
for option in self.options: | ||
self.valueToLabel[option.value] = option.label | ||
|
||
async def callback(self, interaction: discord.Interaction): | ||
logChannel = interaction.client.get_channel(settings.DISCORD_LOG_CHANNEL) | ||
opts = ", ".join([self.valueToLabel[value] for value in self.values]) | ||
|
||
await logChannel.send( | ||
f":ballot_box_with_check: Options selected | {interaction.channel.mention} | {interaction.user} selected: ({opts})." | ||
) | ||
|
||
|
||
class LogButton(discord.ui.Button): | ||
async def callback(self, interaction: discord.Interaction): | ||
logChannel = interaction.client.get_channel(settings.DISCORD_LOG_CHANNEL) | ||
await logChannel.send( | ||
f":radio_button: Button clicked | {interaction.channel.mention} | {interaction.user} clicked ({self.label})." | ||
) | ||
|
||
|
||
def commandlogger(func): | ||
""" | ||
Decorator that allows slash commands to be logged | ||
:param func: original function | ||
:return: wrapped function | ||
""" | ||
|
||
def slashCommand(ctx, kwargs): | ||
log_string = ":arrow_forward: SlashCommand: " | ||
log_string += ( | ||
ctx.channel.mention | ||
if isinstance(ctx.channel, discord.TextChannel) | ||
else "????" | ||
) | ||
log_string += f" | {ctx.author}: /{ctx.command} " | ||
|
||
for k, v in kwargs.items(): | ||
log_string += f" {k}: {v}" | ||
return log_string | ||
|
||
def messageCommand(ctx): | ||
log_string = ":arrow_forward: MessageCommand: " | ||
log_string += ( | ||
ctx.channel.mention | ||
if isinstance(ctx.channel, discord.TextChannel) | ||
else "????" | ||
) | ||
log_string += f' | {ctx.author}: "{ctx.command}"' | ||
return log_string | ||
|
||
def otherCommand(ctx): | ||
log_string = ":arrow_forward: OtherCommand: " | ||
log_string += ( | ||
ctx.channel.mention | ||
if isinstance(ctx.channel, discord.TextChannel) | ||
else "????" | ||
) | ||
log_string += f' | {ctx.author}: "{ctx.command}"' | ||
return log_string | ||
|
||
@functools.wraps(func) | ||
async def wrapped(self, ctx, *args, **kwargs): | ||
# Some fancy foo stuff | ||
await func(self, ctx, *args, **kwargs) | ||
if isinstance(ctx.command, discord.MessageCommand): | ||
msg = messageCommand(ctx) | ||
elif isinstance(ctx.command, (discord.SlashCommand, discord.SlashCommandGroup)): | ||
msg = slashCommand(ctx, kwargs) | ||
else: | ||
msg = otherCommand(ctx) | ||
logChannel = self.client.get_channel(settings.DISCORD_LOG_CHANNEL) | ||
await logChannel.send(msg) | ||
|
||
return wrapped |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,148 +1,155 @@ | ||
import functools | ||
from dotenv import load_dotenv | ||
|
||
import discord | ||
from discord.ext import commands | ||
from discord import option, Permissions | ||
from discord import option | ||
|
||
import settings | ||
|
||
|
||
async def logCommand(channel, ctx, *args, **kwargs): | ||
log_string = ":arrow_forward: Command: " | ||
log_string += ctx.channel.mention if isinstance(ctx.channel, discord.TextChannel) else "????" | ||
log_string += f" | {ctx.author}: /{ctx.command} " | ||
|
||
for k, v in kwargs.items(): | ||
log_string += f" {k}: {v}" | ||
await channel.send(log_string) | ||
|
||
|
||
client = commands.Bot(command_prefix=commands.when_mentioned_or("!"), intents=settings.INTENTS) | ||
@client.event | ||
async def on_command_error(ctx: commands.Context, error: commands.CommandError): | ||
""" | ||
Give feedback to the user when user has no perms to use the command | ||
:param ctx: Original command context | ||
:param error: Error | ||
:return: | ||
""" | ||
|
||
if isinstance(error, commands.errors.MissingRole): | ||
await ctx.response.send_message(f"{ctx.author.mention}, You do not have permissions to use that command.", ephemeral=True) | ||
else: | ||
raise error | ||
|
||
@client.event | ||
async def on_application_command_error(ctx: commands.Context, error: commands.CommandError): | ||
""" | ||
Give feedback to the user when user has no perms to use the command | ||
:param ctx: Original command context | ||
:param error: Error | ||
:return: | ||
""" | ||
await on_command_error(ctx, error) | ||
|
||
def slashcommandlogger(func): | ||
""" | ||
Decorator to log slash commands | ||
:param func: wrapped function | ||
:return: | ||
""" | ||
@functools.wraps(func) | ||
async def wrapped(ctx, cog: str): | ||
# Some fancy foo stuff | ||
await logCommand(client.get_channel(settings.DISCORD_LOG_CHANNEL), ctx, cog=cog.lower()) | ||
await func(ctx, cog) | ||
|
||
return wrapped | ||
|
||
@client.slash_command(description="load a cog", | ||
guild_ids=settings.DISCORD_GUILD_IDS, | ||
default_permission=False) | ||
@commands.has_role(settings.DISCORD_COMMAND_PERMISSION_ROLE) | ||
@option(name="cog", | ||
description="Select Cog", | ||
from cogManagerMixin import commandlogger | ||
|
||
|
||
class CogManager(commands.Cog): | ||
def __init__(self, client): | ||
self.client = client | ||
|
||
@commands.Cog.listener() | ||
async def on_ready(self): | ||
await self.client.get_channel(settings.DISCORD_LOG_CHANNEL).send( | ||
':white_check_mark: Cog: "cogmanager" ready' | ||
) | ||
|
||
@commands.slash_command( | ||
description="load a cog", | ||
guild_ids=settings.DISCORD_GUILD_IDS, | ||
default_permission=False, | ||
) | ||
@commands.has_role(settings.DISCORD_COMMAND_PERMISSION_ROLE) | ||
@option( | ||
name="cog", | ||
description="Select Cog", | ||
required=True, | ||
choices=settings.DISCORD_COGS | ||
) | ||
@slashcommandlogger | ||
async def load(ctx: discord.ApplicationContext, cog: str): | ||
""" | ||
Load a cog | ||
:param ctx: Original slash command context | ||
:param cog: Name of the cog to load | ||
:return: | ||
""" | ||
cog, className = cog.lower(), cog | ||
try: | ||
client.load_extension(f"cogs.{cog}") | ||
bot = client.get_cog(className) | ||
await bot.on_ready() | ||
await ctx.respond(f"Cog: \"{cog}\" loaded.") | ||
except discord.errors.ExtensionAlreadyLoaded: | ||
await ctx.respond(f"Cog: \"{cog}\" already loaded.") | ||
|
||
@client.slash_command(description="unload a cog", | ||
guild_ids=settings.DISCORD_GUILD_IDS, | ||
default_permission=False) | ||
@commands.has_role(settings.DISCORD_COMMAND_PERMISSION_ROLE) | ||
@option(name="cog", | ||
description="Select Cog", | ||
choices=settings.DISCORD_COGS, | ||
) | ||
@commandlogger | ||
async def load(self, ctx: discord.ApplicationContext, cog: str): | ||
""" | ||
Load a cog | ||
:param ctx: Original slash command context | ||
:param cog: Name of the cog to load | ||
:return: | ||
""" | ||
cog, className = cog.lower(), cog | ||
try: | ||
self.client.load_extension(f"cogs.{cog}") | ||
bot = self.client.get_cog(className) | ||
await bot.on_ready() | ||
await ctx.respond(f'Cog: "{cog}" loaded.') | ||
except discord.errors.ExtensionAlreadyLoaded: | ||
await ctx.respond(f'Cog: "{cog}" already loaded.') | ||
|
||
@commands.slash_command( | ||
description="unload a cog", | ||
guild_ids=settings.DISCORD_GUILD_IDS, | ||
default_permission=False, | ||
) | ||
@commands.has_role(settings.DISCORD_COMMAND_PERMISSION_ROLE) | ||
@option( | ||
name="cog", | ||
description="Select Cog", | ||
required=True, | ||
choices=settings.DISCORD_COGS | ||
) | ||
@slashcommandlogger | ||
async def unload(ctx, cog: str): | ||
""" | ||
Unload a cog | ||
:param ctx: Original slash command context | ||
:param cog: Name of the cog to unload | ||
:return: | ||
""" | ||
cog = cog.lower() | ||
try: | ||
client.unload_extension(f"cogs.{cog}") | ||
await ctx.respond(f"Cog: \"{cog}\" unloaded.") | ||
await client.get_channel(settings.DISCORD_LOG_CHANNEL).send(f":negative_squared_cross_mark: Cog: \"{cog}\" unloaded.") | ||
except discord.errors.ExtensionNotLoaded: | ||
await ctx.respond(f"Cog: \"{cog}\" not loaded.") | ||
|
||
@client.slash_command(description="reload a cog", | ||
guild_ids=settings.DISCORD_GUILD_IDS, | ||
default_permission=False) | ||
@commands.has_role(settings.DISCORD_COMMAND_PERMISSION_ROLE) | ||
@option(name="cog", | ||
description="Select Cog", | ||
choices=settings.DISCORD_COGS, | ||
) | ||
@commandlogger | ||
async def unload(self, ctx: discord.ApplicationContext, cog: str): | ||
""" | ||
Unload a cog | ||
:param ctx: Original slash command context | ||
:param cog: Name of the cog to unload | ||
:return: | ||
""" | ||
cog = cog.lower() | ||
try: | ||
self.client.unload_extension(f"cogs.{cog}") | ||
await ctx.respond(f'Cog: "{cog}" unloaded.') | ||
await self.client.get_channel(settings.DISCORD_LOG_CHANNEL).send( | ||
f':negative_squared_cross_mark: Cog: "{cog}" unloaded.' | ||
) | ||
except discord.errors.ExtensionNotLoaded: | ||
await ctx.respond(f'Cog: "{cog}" not loaded.') | ||
|
||
@commands.slash_command( | ||
description="reload a cog", | ||
guild_ids=settings.DISCORD_GUILD_IDS, | ||
default_permission=False, | ||
) | ||
@commands.has_role(settings.DISCORD_COMMAND_PERMISSION_ROLE) | ||
@option( | ||
name="cog", | ||
description="Select Cog", | ||
required=True, | ||
choices=settings.DISCORD_COGS | ||
) | ||
@slashcommandlogger | ||
async def reload(ctx, cog: str): | ||
""" | ||
Reload a cog | ||
:param ctx: Original slash command context | ||
:param cog: Name of the cog to reload | ||
:return: | ||
""" | ||
# Attempt to unload | ||
cog, className = cog.lower(), cog | ||
try: | ||
client.unload_extension(f"cogs.{cog}") | ||
await client.get_channel(settings.DISCORD_LOG_CHANNEL).send(f":negative_squared_cross_mark: Cog: \"{cog}\" unloaded.") | ||
except discord.errors.ExtensionNotLoaded: | ||
pass | ||
|
||
# Load the cog | ||
client.load_extension(f"cogs.{cog}") | ||
bot = client.get_cog(className) | ||
await bot.on_ready() | ||
await ctx.send(f"Cog: \"{cog}\" reloaded.") | ||
choices=settings.DISCORD_COGS, | ||
) | ||
@commandlogger | ||
async def reload(self, ctx: discord.ApplicationContext, cog: str): | ||
""" | ||
Reload a cog | ||
:param ctx: Original slash command context | ||
:param cog: Name of the cog to reload | ||
:return: | ||
""" | ||
# Attempt to unload | ||
cog, className = cog.lower(), cog | ||
try: | ||
self.client.unload_extension(f"cogs.{cog}") | ||
await self.client.get_channel(settings.DISCORD_LOG_CHANNEL).send( | ||
f':negative_squared_cross_mark: Cog: "{cog}" unloaded.' | ||
) | ||
except discord.errors.ExtensionNotLoaded: | ||
pass | ||
|
||
# Load the cog | ||
self.client.load_extension(f"cogs.{cog}") | ||
bot = self.client.get_cog(className) | ||
await bot.on_ready() | ||
await ctx.respond(f'Cog: "{cog}" reloaded.') | ||
|
||
|
||
class ClanBotjasClient(commands.Bot): | ||
def __init__(self): | ||
super().__init__( | ||
command_prefix=commands.when_mentioned_or("!"), intents=settings.INTENTS | ||
) | ||
self.add_cog(CogManager(self)) | ||
for cog in settings.DISCORD_COGS: | ||
self.load_extension(f"cogs.{cog.name}") | ||
|
||
async def on_command_error( | ||
self, ctx: commands.Context, error: commands.CommandError | ||
): | ||
""" | ||
Give feedback to the user when user has no perms to use the command | ||
:param ctx: Original command context | ||
:param error: Error | ||
:return: | ||
""" | ||
|
||
if isinstance(error, commands.errors.MissingRole): | ||
await ctx.response.send_message( | ||
f"{ctx.author.mention}, You do not have permissions to use that command.", | ||
ephemeral=True, | ||
) | ||
else: | ||
raise error | ||
|
||
async def on_application_command_error( | ||
self, ctx: commands.Context, error: commands.CommandError | ||
): | ||
""" | ||
Give feedback to the user when user has no perms to use the command | ||
:param ctx: Original command context | ||
:param error: Error | ||
:return: | ||
""" | ||
await self.on_command_error(ctx, error) | ||
|
||
|
||
if __name__ == "__main__": | ||
# Load all cogs | ||
for cog in settings.DISCORD_COGS: | ||
client.load_extension(f'cogs.{cog.name}') | ||
|
||
client.run(settings.DISCORD_TOKEN) | ||
ClanBotjasClient().run(settings.DISCORD_TOKEN) |
Oops, something went wrong.