import traceback from typing import Optional from discord import Intents from discord.ext import commands from config import CONFIG from rocketbot.cogs.basecog import BaseCog from rocketbot.cogsetting import CogSetting from rocketbot.utils import bot_log, dump_stacktrace class Rocketbot(commands.Bot): """ Bot subclass """ def __init__(self, command_prefix, **kwargs): super().__init__(command_prefix, **kwargs) self.__commands_set_up = False async def on_command_error(self, context: commands.Context, exception: BaseException) -> None: bot_log(None, None, f'Command error') dump_stacktrace(exception) if context.guild is None or \ context.message.channel is None or \ context.message.author.bot: return if not context.message.channel.permissions_for(context.message.author).ban_members: # Don't tell non-mods about errors return if isinstance(exception, (commands.errors.CommandError, )): # Reply with the error message for ordinary command errors await context.message.reply( f'{CONFIG["failure_emoji"]} {exception}', mention_author=False) return # Stack trace everything else async def on_error(self, event_method, args=None, kwargs=None): bot_log(None, None, 'Event caused error\n' + \ f' event method: {event_method}' + \ f' event args: {args}' + \ f' event kwargs: {kwargs}' + \ traceback.format_exc()) async def on_ready(self): if not self.__commands_set_up: await self.__set_up_commands() bot_log(None, None, 'Bot done initializing') print('----------------------------------------------------------') async def __set_up_commands(self): if self.__commands_set_up: return self.__commands_set_up = True for cog in self.cogs.values(): if isinstance(cog, BaseCog): bcog: BaseCog = cog if len(bcog.settings) > 0: CogSetting.set_up_all(bcog, self, bcog.settings) try: synced_commands = await self.tree.sync() for command in synced_commands: bot_log(None, None, f'Synced command: /{command.name}') except Exception as e: dump_stacktrace(e) # Current active bot instance rocketbot: Optional[Rocketbot] = None def __create_bot(): global rocketbot if rocketbot is not None: return bot_log(None, None, 'Creating bot...') intents = Intents.default() intents.messages = True # pylint: disable=assigning-non-slot intents.message_content = True # pylint: disable=assigning-non-slot intents.members = True # pylint: disable=assigning-non-slot intents.presences = True rocketbot = Rocketbot(command_prefix=CONFIG['command_prefix'], intents=intents) __create_bot() from rocketbot.cogs.autokickcog import AutoKickCog from rocketbot.cogs.configcog import ConfigCog from rocketbot.cogs.crosspostcog import CrossPostCog from rocketbot.cogs.generalcog import GeneralCog from rocketbot.cogs.joinraidcog import JoinRaidCog from rocketbot.cogs.logcog import LoggingCog from rocketbot.cogs.patterncog import PatternCog from rocketbot.cogs.urlspamcog import URLSpamCog from rocketbot.cogs.usernamecog import UsernamePatternCog async def start_bot(): bot_log(None, None, 'Bot initializing...') bot_log(None, None, f"Type {CONFIG['command_prefix']}help in Discord for available commands.") # Core await rocketbot.add_cog(GeneralCog(rocketbot)) await rocketbot.add_cog(ConfigCog(rocketbot)) # Optional await rocketbot.add_cog(AutoKickCog(rocketbot)) await rocketbot.add_cog(CrossPostCog(rocketbot)) await rocketbot.add_cog(JoinRaidCog(rocketbot)) await rocketbot.add_cog(LoggingCog(rocketbot)) await rocketbot.add_cog(PatternCog(rocketbot)) await rocketbot.add_cog(URLSpamCog(rocketbot)) await rocketbot.add_cog(UsernamePatternCog(rocketbot)) await rocketbot.start(CONFIG['client_token'], reconnect=True) print('\nBot aborted')