You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
4.6 KiB

  1. import sys
  2. import logging
  3. import logging.handlers
  4. import traceback
  5. import config
  6. import discord
  7. from discord.ext import commands
  8. stdout_handler = logging.StreamHandler(sys.stdout)
  9. log_format = logging.Formatter(
  10. "[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s"
  11. )
  12. stdout_handler.setFormatter(log_format)
  13. log = logging.getLogger("discord")
  14. log.setLevel(logging.INFO)
  15. log.addHandler(stdout_handler)
  16. def get_prefix(bot, message):
  17. prefixes = config.prefixes
  18. return commands.when_mentioned_or(*prefixes)(bot, message)
  19. initial_extensions = [
  20. "cogs.common",
  21. "cogs.admin",
  22. "cogs.basic",
  23. "cogs.links",
  24. "cogs.lists",
  25. "cogs.meme",
  26. "cogs.uwu",
  27. ]
  28. intents = discord.Intents.default()
  29. intents.typing = False
  30. intents.members = True
  31. bot = commands.Bot(
  32. command_prefix=get_prefix,
  33. pm_help=True,
  34. description=config.bot_description,
  35. intents=intents,
  36. )
  37. bot.log = log
  38. if __name__ == "__main__":
  39. for extension in initial_extensions:
  40. try:
  41. bot.load_extension(extension)
  42. except Exception as e:
  43. log.error(f"Failed to load extension {extension}.")
  44. log.error(traceback.print_exc())
  45. @bot.event
  46. async def on_ready():
  47. bot.botlog_channel = bot.get_channel(config.botlog_channel)
  48. log.info(
  49. f"\nLogged in as: {bot.user.name} - "
  50. f"{bot.user.id}\ndpy version: {discord.__version__}\n"
  51. )
  52. game_name = f"{config.prefixes[0]}help"
  53. msg = f"{bot.user.name} has started! "
  54. await bot.botlog_channel.send(msg)
  55. activity = discord.Activity(name=game_name, type=discord.ActivityType.listening)
  56. await bot.change_presence(activity=activity)
  57. @bot.event
  58. async def on_error(event_method, *args, **kwargs):
  59. log.error(f"Error on {event_method}: {sys.exc_info()}")
  60. @bot.event
  61. async def on_command_error(ctx, error):
  62. error_text = str(error)
  63. err_msg = (
  64. f'Error with "{ctx.message.content}" from '
  65. f"{ctx.message.author} ({ctx.message.author.id}) "
  66. f"of type {type(error)}: {error_text}"
  67. )
  68. log.error(err_msg)
  69. if not isinstance(error, commands.CommandNotFound):
  70. err_msg = bot.escape_message(err_msg)
  71. await bot.botlog_channel.send(err_msg)
  72. if isinstance(error, commands.NoPrivateMessage):
  73. return await ctx.send("This command doesn't work on DMs.")
  74. elif isinstance(error, commands.MissingPermissions):
  75. roles_needed = "\n- ".join(error.missing_perms)
  76. return await ctx.send(
  77. f"{ctx.author.mention}: You don't have the right"
  78. " permissions to run this command. You need: "
  79. f"```- {roles_needed}```"
  80. )
  81. elif isinstance(error, commands.BotMissingPermissions):
  82. roles_needed = "\n-".join(error.missing_perms)
  83. return await ctx.send(
  84. f"{ctx.author.mention}: Bot doesn't have "
  85. "the right permissions to run this command. "
  86. "Please add the following roles: "
  87. f"```- {roles_needed}```"
  88. )
  89. elif isinstance(error, commands.CommandOnCooldown):
  90. return await ctx.send(
  91. f"{ctx.author.mention}: You're being "
  92. "ratelimited. Try in "
  93. f"{error.retry_after:.1f} seconds."
  94. )
  95. elif isinstance(error, commands.CheckFailure):
  96. return await ctx.send(
  97. f"{ctx.author.mention}: Check failed. "
  98. "You might not have the right permissions "
  99. "to run this command, or you may not be able "
  100. "to run this command in the current channel."
  101. )
  102. elif isinstance(error, commands.CommandInvokeError) and (
  103. "Cannot send messages to this user" in error_text
  104. ):
  105. return await ctx.send(
  106. f"{ctx.author.mention}: I can't DM you.\n"
  107. "You might have me blocked or have DMs "
  108. f"blocked globally or for {ctx.guild.name}.\n"
  109. "Please resolve that, then "
  110. "run the command again."
  111. )
  112. elif isinstance(error, commands.CommandNotFound):
  113. # Nothing to do when command is not found.
  114. return
  115. help_text = (
  116. f"Usage of this command is: ```{ctx.prefix}"
  117. f"{ctx.command.signature}```\nPlease see `{ctx.prefix}help "
  118. f"{ctx.command.name}` for more info about this command."
  119. )
  120. if isinstance(error, commands.BadArgument):
  121. return await ctx.send(
  122. f"{ctx.author.mention}: You gave incorrect " f"arguments. {help_text}"
  123. )
  124. elif isinstance(error, commands.MissingRequiredArgument):
  125. return await ctx.send(
  126. f"{ctx.author.mention}: You gave incomplete " f"arguments. {help_text}"
  127. )
  128. bot.run(config.token, bot=True, reconnect=True)