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.

433 lines
15KB

  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. # TODO: Move away from using ID's for everthing. Maybe replace list with dict
  13. # TODO: Add check for no channel id when a module is enabled
  14. import json
  15. import random
  16. import discord
  17. from discord.ext.commands import Bot
  18. bot = Bot(command_prefix=".")
  19. # bot.remove_command("help")
  20. # TODO: Take these from a file, not the program
  21. token = 'MzA4MDc3ODg3MDYyNTQwMjg5.DEW5YA.JfLfU5jPjTFQi0xFI6B_-SKvC54'
  22. owner_id = "142735312626515979"
  23. config_template = {
  24. "example": {
  25. "greets": {
  26. "enabled": 0,
  27. "welcome-channel": "",
  28. "member-role": ""
  29. },
  30. "goodbyes": {
  31. "enabled": 0,
  32. "goodbye-channel": ""
  33. },
  34. "self-assign_roles": {
  35. "enabled": 0,
  36. "roles": []
  37. },
  38. "twitch_shilling": {
  39. "enabled": 0,
  40. "twitch-channel": "",
  41. "whitelist": {
  42. "enabled": 0,
  43. "list": []
  44. }
  45. }
  46. }
  47. }
  48. def load_config():
  49. with open('config.json', 'r') as config_file:
  50. return json.load(config_file)
  51. def updateconfig():
  52. with open('config.json', 'w') as conf_file:
  53. json.dump(config, conf_file)
  54. def config_errorcheck():
  55. # Checks for errors in the config files and fixes them automatically
  56. for server in bot.servers:
  57. if server.id not in config:
  58. config[server.id] = config_template["example"]
  59. updateconfig()
  60. 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()))
  61. else:
  62. for module_setting in config_template["example"]:
  63. if module_setting not in config[server.id]:
  64. config[server.id][module_setting] = config_template["example"][module_setting]
  65. updateconfig()
  66. 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()))
  67. def owner(ctx):
  68. if owner_id == ctx.message.author.id:
  69. return True
  70. else:
  71. return False
  72. def mention_commandee(ctx):
  73. return ctx.message.author
  74. def blacklisted(user):
  75. with open("blacklist.txt", "r") as fp:
  76. for line in fp.readlines():
  77. if user.id+"\n" == line:
  78. return True
  79. return False
  80. def dice_roll(num):
  81. if num == 100:
  82. step = 10
  83. else:
  84. step = 1
  85. return random.randrange(step, num+1, step)
  86. @bot.event
  87. async def on_ready():
  88. # TODO: First part needs to be moved to wait_until_ready
  89. config_errorcheck()
  90. print("Client logged in\n")
  91. print("Servers I am currently in:")
  92. for server in bot.servers:
  93. print(server)
  94. print("")
  95. @bot.event
  96. async def on_member_update(member_b, member_a):
  97. # Twitch Shilling Part
  98. if blacklisted(member_b):
  99. return
  100. ts_enabled = config[member_a.server.id]["twitch_shilling"]["enabled"]
  101. if ts_enabled:
  102. if not config[member_a.server.id]["twitch_shilling"]["whitelist"]["enabled"] or member_a.id in config[member_a.server.id]["twitch_shilling"]["whitelist"]["list"]:
  103. if member_a.game:
  104. if member_a.game.type:
  105. channel = discord.Object(config[member_a.server.id]["twitch_shilling"]["twitch-channel"])
  106. return await bot.send_message(channel, content=":video_game:** {} is live!** :video_game:\n {}\n{}".format(member_a.name, member_a.game.name, member_a.game.url))
  107. @bot.event
  108. async def on_message(message):
  109. if blacklisted(message.author):
  110. return
  111. else:
  112. return await bot.process_commands(message)
  113. @bot.event
  114. async def on_member_join(member):
  115. """
  116. Greets users when they join a server.
  117. :param member:
  118. :return:
  119. """
  120. if not config[member.server.id]["greets"]["enabled"]:
  121. return
  122. em = discord.Embed(
  123. title="Welcome to {}!".format(member.server),
  124. description='Hey {}! Welcome to {}! Be sure to read the rules.'.format(member.mention, member.server),
  125. colour=0xDEADBF)
  126. if config[member.server.id]["greets"]["welcome-channel"]:
  127. channel = discord.Object(config[member.server.id]["greets"]["welcome-channel"])
  128. else:
  129. channel = member.server.default_channel
  130. return await bot.send_message(channel,embed=em)
  131. @bot.event
  132. async def on_member_remove(member):
  133. if not config[member.server.id]["goodbyes"]["enabled"]:
  134. return
  135. else:
  136. return await bot.send_message(member.server,embed=discord.Embed(
  137. description="{}#{} has left or been beaned.".format(member.name, member.discriminator), colour=0xDEADBF))
  138. @bot.event
  139. async def on_server_join(server):
  140. config[server.id] = config_template["example"]
  141. updateconfig()
  142. @bot.event
  143. async def on_server_remove(server):
  144. config.pop(server.id)
  145. updateconfig()
  146. @bot.command(pass_context=True)
  147. async def iam(ctx, role: discord.Role = None, *, user: discord.User = None, server: discord.Server = None):
  148. if not config[ctx.message.server.id]["self-assign_roles"]["enabled"]:
  149. return
  150. user = ctx.message.author
  151. server = ctx.message.server
  152. if role not in server.roles:
  153. return await bot.say("That role doesn't exist. Roles are case sensitive. ")
  154. if role in user.roles:
  155. return await bot.say("You already have that role.")
  156. if role.id in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
  157. await bot.add_roles(user, role)
  158. print("{} added {} to themselves in {} on {}".format(user.display_name, role.name, ctx.message.channel,
  159. ctx.message.server))
  160. return await bot.say("Yay {}! You now have the {} role!".format(user.mention, role.name))
  161. else:
  162. return await bot.say("That role is not self-assignable.")
  163. @bot.command(pass_context=True, enabled=False)
  164. async def dice(ctx, num, *, user: discord.User = None):
  165. # TODO: Change to ndx format
  166. die = ("4","6","8","10","12","20","100")
  167. if num not in die:
  168. if num == "help":
  169. 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.")
  170. else:
  171. return await bot.say("That is not a dice I know. Try !dice help for help!")
  172. user = mention_commandee(ctx)
  173. roll = dice_roll(int(num))
  174. return await bot.say("You rolled a {}, {}".format(roll,user.mention))
  175. @bot.command(pass_context=True)
  176. async def suck(ctx, user: discord.User = None):
  177. if user is None:
  178. try:
  179. user = ctx.message.mentions[0]
  180. except:
  181. return await bot.say("You didn't mention someone for me to suck")
  182. return await bot.say(":eggplant: :sweat_drops: :tongue: {}".format(user.mention))
  183. @bot.command(enabled=False)
  184. async def printcommands():
  185. for command in bot.commands:
  186. print(command)
  187. return await bot.say("Done.")
  188. @bot.command(pass_context=True)
  189. async def listroles(ctx):
  190. roles = []
  191. for role in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
  192. for serverrole in ctx.message.server.roles:
  193. if role == serverrole.id:
  194. roles.append(serverrole.name)
  195. return await bot.say(roles)
  196. #################
  197. # Owner Commands#
  198. #################
  199. @bot.command(pass_context=True)
  200. async def blacklist(ctx, option, *mentions):
  201. """
  202. Usage:
  203. .blacklist [ + | - | add | remove ] @UserName [@UserName2 ...]
  204. Add or remove users to the blacklist.
  205. Blacklisted users are forbidden from using bot commands.
  206. Only the bot owner can use this command
  207. """
  208. if not owner(ctx):
  209. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  210. blacklist_amount = 0
  211. mentions = ctx.message.mentions
  212. if not mentions:
  213. return await bot.say("You didn't mention anyone")
  214. if option not in ['+', '-', 'add', 'remove']:
  215. return await bot.say('Invalid option "%s" specified, use +, -, add, or remove' % option, expire_in=20)
  216. for user in mentions:
  217. if user.id == owner_id:
  218. print("[Commands:Blacklist] The owner cannot be blacklisted.")
  219. await bot.say("The owner cannot be blacklisted.")
  220. mentions.remove(user)
  221. if option in ['+', 'add']:
  222. with open("blacklist.txt", "r") as fp:
  223. for user in mentions:
  224. for line in fp.readlines():
  225. if user.id+"\n" in line:
  226. mentions.remove(user)
  227. with open("blacklist.txt","a+") as fp:
  228. lines = fp.readlines()
  229. for user in mentions:
  230. if user.id not in lines:
  231. fp.write("{}\n".format(user.id))
  232. blacklist_amount += 1
  233. return await bot.say('{} user(s) have been added to the blacklist'.format(blacklist_amount))
  234. elif option in ['-', 'remove']:
  235. with open("blacklist.txt","r") as fp:
  236. lines = fp.readlines()
  237. with open("blacklist.txt","w") as fp:
  238. for user in mentions:
  239. for line in lines:
  240. if user.id+"\n" != line:
  241. fp.write(line)
  242. else:
  243. fp.write("")
  244. blacklist_amount += 1
  245. return await bot.say('{} user(s) have been removed from the blacklist'.format(blacklist_amount))
  246. @bot.command(pass_context=True)
  247. async def addrole(ctx, role: discord.Role = None):
  248. # Add Remove List Help
  249. if not owner(ctx):
  250. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  251. else:
  252. config[ctx.message.server.id]["self-assign_roles"]["roles"].append(role.id)
  253. updateconfig()
  254. return await bot.say('Role "{}" added'.format(str(role)))
  255. @bot.command(pass_context=True)
  256. async def removerole(ctx, role: discord.Role = None):
  257. if not owner(ctx):
  258. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  259. if role.id in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
  260. config[ctx.message.server.id]["self-assign_roles"]["roles"].remove(role.id)
  261. return await bot.say('"{}" has been removed from the self-assignable roles.'.format(str(role)))
  262. else:
  263. return await bot.say("That role was not in the list.")
  264. @bot.command(pass_context=True)
  265. async def enablemodule(ctx, module):
  266. if not owner(ctx):
  267. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  268. else:
  269. if module in config[ctx.message.server.id]:
  270. if not config[ctx.message.server.id][module]["enabled"]:
  271. config[ctx.message.server.id][module]["enabled"] = 1
  272. updateconfig()
  273. return await bot.say("'{}' was enabled!".format(module))
  274. else:
  275. config[ctx.message.server.id][module]["enabled"] = 0
  276. updateconfig()
  277. return await bot.say("'{}' was disabled :cry:".format(module))
  278. else:
  279. return await bot.say("That module dont exist fam. You made the thing")
  280. @bot.command(pass_context=True)
  281. async def set_welcomechannel(ctx, channel: discord.Channel = None):
  282. if not owner(ctx):
  283. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  284. config[ctx.message.server.id]["greets"]["welcome-channel"] = channel.id
  285. updateconfig()
  286. return await bot.say("{} has been set as the welcome channel!".format(channel.mention))
  287. @bot.command(pass_context=True)
  288. async def set_goodbyechannel(ctx, channel: discord.Channel = None):
  289. if not owner(ctx):
  290. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  291. config[ctx.message.server.id]["goodbyes"]["goodbye-channel"] = channel.id
  292. updateconfig()
  293. return await bot.say("{} has been set as the goodbye channel!".format(channel.mention))
  294. @bot.command(pass_context=True)
  295. async def set_twitchchannel(ctx, channel: discord.Channel = None):
  296. if not owner(ctx):
  297. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  298. config[ctx.message.server.id]["twitch_shilling"]["twitch-channel"] = channel.id
  299. updateconfig()
  300. return await bot.say("{} has been set as the twitch shilling channel!".format(channel.mention))
  301. @bot.command(pass_context=True)
  302. async def ts_enablewhitelist(ctx):
  303. if not owner(ctx):
  304. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  305. else:
  306. if not config[ctx.server.id]["twitch_shilling"]["whitelist"]["enabled"]:
  307. config[ctx.server.id]["twitch_shilling"]["whitelist"]["enabled"] = 1
  308. updateconfig()
  309. return await bot.reply("Whitelist for Twitch shilling has been enabled.")
  310. else:
  311. config[ctx.server.id]["twitch_shilling"]["whitelist"]["enabled"] = 0
  312. updateconfig()
  313. return await bot.reply("Whitelist for Twitch shilling has been disabled.")
  314. @bot.command(pass_context=True)
  315. async def ts_whitelist(ctx, option, *mentions):
  316. if not owner(ctx):
  317. return await bot.reply("You do not have permission to do this command.", delete_after=20)
  318. whitelist_count = 0
  319. if not ctx.message.mentions and option != 'list':
  320. return await bot.reply("You haven't mentioned anyone to whitelist.")
  321. if option not in ['+', '-', 'add', 'remove', 'list']:
  322. return await bot.say('Invalid option "%s" specified, use +, -, add, or remove' % option, expire_in=20)
  323. if option in ['+', 'add']:
  324. for user in ctx.message.mentions:
  325. config[ctx.message.server.id]["twitch_shilling"]["whitelist"]["list"].append(user.id)
  326. updateconfig()
  327. whitelist_count += 1
  328. return await bot.say('{} user(s) have been added to the whitelist'.format(whitelist_count))
  329. elif option in ['-', 'remove']:
  330. for user in ctx.message.mentions:
  331. if user.id in config[ctx.message.server.id]["twitch_shilling"]["whitelist"]["list"]:
  332. config[ctx.message.server.id]["twitch_shilling"]["whitelist"]["list"].remove(user.id)
  333. updateconfig()
  334. whitelist_count += 1
  335. return await bot.say('{} user(s) have been removed to the whitelist'.format(whitelist_count))
  336. elif option == 'list':
  337. return await bot.say(config[ctx.message.server.id]["twitch_shilling"]["whitelist"]["list"])
  338. if __name__ == "__main__":
  339. config = load_config()
  340. bot.run(token)