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.

359 lines
11KB

  1. # RoxBot
  2. # Version = 1.1
  3. # Author = Roxxers
  4. ##############
  5. # To-do List #
  6. ##############
  7. # TODO: On member role assign, welcome member using on_member_update
  8. # TODO: Better help menu- AutoGen using <command>.help
  9. # TODO: WaifuRater - Mention user and RNG a rating
  10. # TODO: Admin tools - For commands already in and things like purge a chat
  11. # TODO: Overwatch stats - Using Overwatch-API lib
  12. import json
  13. import random
  14. import discord
  15. from discord.ext.commands import Bot
  16. bot = Bot(command_prefix=".")
  17. # bot.remove_command("help")
  18. # TODO: Take these from a file, not the program
  19. token = ''
  20. owner_id = "142735312626515979"
  21. config_template = {
  22. "example": {
  23. "greets": {
  24. "enabled": 0,
  25. "welcome-channel": "",
  26. "member-role": ""
  27. },
  28. "goodbyes": {
  29. "enabled": 0,
  30. "goodbye-channel": ""
  31. },
  32. "self-assign_roles": {
  33. "enabled": 0,
  34. "roles": []
  35. }
  36. }
  37. }
  38. def load_config():
  39. with open('config.json', 'r') as config_file:
  40. return json.load(config_file)
  41. def updateconfig():
  42. with open('config.json', 'w') as conf_file:
  43. json.dump(config, conf_file)
  44. def config_errorcheck():
  45. # Checks for errors in the config files and fixes them automatically
  46. for server in bot.servers:
  47. if server.id not in config:
  48. config[server.id] = config_template["example"]
  49. updateconfig()
  50. print("WARNING: The config file for {} was not found. A template has been loaded and saved. All modules are turned off by default.".format(server.name.upper()))
  51. else:
  52. for module_setting in config_template["example"]:
  53. if module_setting not in config[server.id]:
  54. config[server.id][module_setting] = config_template["example"][module_setting]
  55. updateconfig()
  56. print("WARNING: The config file for {} was missing the {} module. This has been fixed with the template version. It is disabled by default.".format(server.name.upper(), module_setting.upper()))
  57. def owner(ctx):
  58. if owner_id == ctx.author.id:
  59. return True
  60. else:
  61. return False
  62. def mention_commandee(ctx):
  63. return ctx.message.author
  64. def blacklisted(user):
  65. with open("blacklist.txt", "r") as fp:
  66. for line in fp.readlines():
  67. if user.id+"\n" == line:
  68. return True
  69. return False
  70. def dice_roll(num):
  71. if num == 100:
  72. step = 10
  73. else:
  74. step = 1
  75. return random.randrange(step, num+1, step)
  76. @bot.event
  77. async def on_ready():
  78. # TODO: First part needs to be moved to wait_until_ready
  79. config_errorcheck()
  80. print("Client logged in\n\n")
  81. print("Servers I am currently in:\n")
  82. for server in bot.servers:
  83. print(server)
  84. @bot.event
  85. async def on_member_update(before, after):
  86. if True:
  87. return
  88. for role in before.roles:
  89. print(role.name)
  90. for role in after.roles:
  91. print(role.name)
  92. @bot.event
  93. async def on_message(message):
  94. if blacklisted(message.author):
  95. return
  96. else:
  97. return await bot.process_commands(message)
  98. @bot.event
  99. async def on_member_join(member):
  100. """
  101. Greets users when they join a server.
  102. :param member:
  103. :return:
  104. """
  105. if not config[member.server.id]["greets"]["enabled"]:
  106. return
  107. em = discord.Embed(
  108. title="Welcome to {}!".format(member.server),
  109. description='Hey {}! Welcome to {}! Be sure to read the rules.'.format(member.mention, member.server),
  110. colour=0xDEADBF)
  111. if config[member.server.id]["greets"]["welcome-channel"]:
  112. channel = discord.Object(config[member.server.id]["greets"]["welcome-channel"])
  113. else:
  114. channel = member.server.default_channel
  115. return await bot.send_message(channel,embed=em)
  116. @bot.event
  117. async def on_member_remove(member):
  118. if not config[member.server.id]["goodbyes"]["enabled"]:
  119. return
  120. else:
  121. return await bot.send_message(member.server,embed=discord.Embed(
  122. description="{}#{} has left or been beaned.".format(member.name, member.discriminator), colour=0xDEADBF))
  123. @bot.event
  124. async def on_server_join(server):
  125. config[server.id] = config_template["example"]
  126. updateconfig()
  127. @bot.event
  128. async def on_server_remove(server):
  129. config.pop(server.id)
  130. updateconfig()
  131. @bot.command(pass_context=True)
  132. async def iam(ctx, role: discord.Role = None, *, user: discord.User = None, server: discord.Server = None):
  133. if not config[ctx.message.server.id]["self-assign_roles"]["enabled"]:
  134. return
  135. user = ctx.message.author
  136. server = ctx.message.server
  137. if role not in server.roles:
  138. return await bot.say("That role doesn't exist. Roles are case sensitive. ")
  139. if role in user.roles:
  140. return await bot.say("You already have that role.")
  141. if role.id in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
  142. await bot.add_roles(user, role)
  143. print("{} added {} to themselves in {} on {}".format(user.display_name, role.name, ctx.message.channel,
  144. ctx.message.server))
  145. return await bot.say("Yay {}! You now have the {} role!".format(user.mention, role.name))
  146. else:
  147. return await bot.say("That role is not self-assignable.")
  148. @bot.command(pass_context=True)
  149. async def blacklist(ctx, option, *mentions):
  150. """
  151. Usage:
  152. .blacklist [ + | - | add | remove ] @UserName [@UserName2 ...]
  153. Add or remove users to the blacklist.
  154. Blacklisted users are forbidden from using bot commands.
  155. Only the bot owner can use this command
  156. """
  157. if not owner(ctx):
  158. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  159. blacklist_amount = 0
  160. mentions = ctx.message.mentions
  161. if not mentions:
  162. bot.say("You didn't mention anyone")
  163. if option not in ['+', '-', 'add', 'remove']:
  164. return await bot.say('Invalid option "%s" specified, use +, -, add, or remove' % option, expire_in=20)
  165. for user in mentions:
  166. if user.id == owner_id:
  167. print("[Commands:Blacklist] The owner cannot be blacklisted.")
  168. await bot.say("The owner cannot be blacklisted.")
  169. mentions.remove(user)
  170. if option in ['+', 'add']:
  171. with open("blacklist.txt", "r") as fp:
  172. for user in mentions:
  173. for line in fp.readlines():
  174. if user.id+"\n" in line:
  175. mentions.remove(user)
  176. with open("blacklist.txt","a+") as fp:
  177. lines = fp.readlines()
  178. for user in mentions:
  179. if user.id not in lines:
  180. fp.write("{}\n".format(user.id))
  181. blacklist_amount += 1
  182. return await bot.say('{} users have been added to the blacklist'.format(blacklist_amount))
  183. else:
  184. with open("blacklist.txt","r") as fp:
  185. lines = fp.readlines()
  186. with open("blacklist.txt","w") as fp:
  187. for user in mentions:
  188. for line in lines:
  189. if user.id+"\n" != line:
  190. fp.write(line)
  191. else:
  192. fp.write("")
  193. blacklist_amount += 1
  194. return await bot.say('{} users have been removed from the blacklist'.format(blacklist_amount))
  195. @bot.command(pass_context=True, enabled=False)
  196. async def dice(ctx, num, *, user: discord.User = None):
  197. # TODO: Change to ndx format
  198. die = ("4","6","8","10","12","20","100")
  199. if num not in die:
  200. if num == "help":
  201. return await bot.say("!dice - This command random roles a dice. The die I support are (4, 6, 8, 10, 12, 20, 100) like the ones used in Table Top games.")
  202. else:
  203. return await bot.say("That is not a dice I know. Try !dice help for help!")
  204. user = mention_commandee(ctx)
  205. roll = dice_roll(int(num))
  206. return await bot.say("You rolled a {}, {}".format(roll,user.mention))
  207. @bot.command(pass_context=True)
  208. async def suck(ctx, user: discord.User = None):
  209. if user is None:
  210. try:
  211. user = ctx.message.mentions[0]
  212. except:
  213. return await bot.say("You didn't mention someone for me to suck")
  214. return await bot.say(":eggplant: :sweat_drops: :tongue: {}".format(user.mention))
  215. @bot.command(enabled=False)
  216. async def printcommands():
  217. for command in bot.commands:
  218. print(command)
  219. return await bot.say("Done.")
  220. @bot.command(pass_context=True)
  221. async def listroles(ctx):
  222. roles = []
  223. for role in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
  224. for serverrole in ctx.message.server.roles:
  225. if role == serverrole.id:
  226. roles.append(serverrole.name)
  227. return await bot.say(roles)
  228. #################
  229. # Owner Commands#
  230. #################
  231. @bot.command(pass_context=True)
  232. async def addrole(ctx, role: discord.Role = None):
  233. # Add Remove List Help
  234. if not owner:
  235. return
  236. else:
  237. config[ctx.message.server.id]["self-assign_roles"]["roles"].append(role.id)
  238. updateconfig()
  239. return await bot.say('Role "{}" added'.format(str(role)))
  240. @bot.command(pass_context=True)
  241. async def removerole(ctx, role: discord.Role = None):
  242. if not owner:
  243. return
  244. count = 0
  245. for sa_role in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
  246. if sa_role == role.id:
  247. config[ctx.message.server.id]["self-assign_roles"]["roles"].pop(count)
  248. updateconfig()
  249. return await bot.say('"{}" has been removed from the self-assignable roles.'.format(str(role)))
  250. else:
  251. count += 1
  252. return await bot.say("That role was not in the list.")
  253. @bot.command(pass_context=True)
  254. async def enablemodule(ctx, module):
  255. if not owner:
  256. return await bot.say("You ain't the owner, normie get out!!! REEE!")
  257. else:
  258. if module in config[ctx.message.server.id]:
  259. if not config[ctx.message.server.id][module]["enabled"]:
  260. config[ctx.message.server.id][module]["enabled"] = 1
  261. updateconfig()
  262. return await bot.say("'{}' was enabled!".format(module))
  263. else:
  264. config[ctx.message.server.id][module]["enabled"] = 0
  265. updateconfig()
  266. return await bot.say("'{}' was disabled :cry:".format(module))
  267. else:
  268. return await bot.say("That module dont exist fam. You made the thing")
  269. @bot.command(pass_context=True)
  270. async def set_welcomechannel(ctx, channel: discord.Channel = None):
  271. config[ctx.message.server.id]["greets"]["welcome-channel"] = channel.id
  272. updateconfig()
  273. return await bot.say("{} has been set as the welcome channel!".format(channel.mention))
  274. @bot.command(pass_context=True)
  275. async def set_goodbyechannel(ctx, channel: discord.Channel = None):
  276. config[ctx.message.server.id]["goodbyes"]["goodbye-channel"] = channel.id
  277. updateconfig()
  278. return await bot.say("{} has been set as the goodbye channel!".format(channel.mention))
  279. if __name__ == "__main__":
  280. config = load_config()
  281. bot.run(token)