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.

434 lines
15KB

  1. import os
  2. import sys
  3. import aiohttp
  4. import asyncio
  5. from Roxbot import checks, load_config
  6. from Roxbot.settings import guild_settings
  7. import discord
  8. from discord.ext.commands import bot, group, is_owner, bot_has_permissions
  9. class Settings:
  10. """
  11. Settings is a mix of settings and admin stuff for the bot. OWNER OR ADMIN ONLY.
  12. """
  13. def __init__(self, bot_client):
  14. self.bot = bot_client
  15. def get_channel(self, ctx, channel):
  16. if ctx.message.channel_mentions:
  17. return ctx.message.channel_mentions[0]
  18. else:
  19. return self.bot.get_channel(channel)
  20. @bot.command()
  21. @checks.is_owner_or_admin()
  22. async def blacklist(self, ctx, option):
  23. """
  24. Add or remove users to the blacklist. Blacklisted users are forbidden from using bot commands.
  25. Usage:
  26. ;blacklist [add|+ OR remove|-] @user#0000
  27. OWNER OR ADMIN ONLY
  28. """
  29. blacklist_amount = 0
  30. mentions = ctx.message.mentions
  31. if not mentions:
  32. return await ctx.send("You didn't mention anyone")
  33. if option not in ['+', '-', 'add', 'remove']:
  34. return await ctx.send('Invalid option "%s" specified, use +, -, add, or remove' % option, expire_in=20)
  35. for user in mentions:
  36. if user.id == load_config.owner:
  37. print("[Commands:Blacklist] The owner cannot be blacklisted.")
  38. await ctx.send("The owner cannot be blacklisted.")
  39. mentions.remove(user)
  40. if option in ['+', 'add']:
  41. with open("settings/blacklist.txt", "r") as fp:
  42. for user in mentions:
  43. for line in fp.readlines():
  44. if user.id + "\n" in line:
  45. mentions.remove(user)
  46. with open("settings/blacklist.txt", "a+") as fp:
  47. lines = fp.readlines()
  48. for user in mentions:
  49. if user.id not in lines:
  50. fp.write("{}\n".format(user.id))
  51. blacklist_amount += 1
  52. return await ctx.send('{} user(s) have been added to the blacklist'.format(blacklist_amount))
  53. elif option in ['-', 'remove']:
  54. with open("settings/blacklist.txt", "r") as fp:
  55. lines = fp.readlines()
  56. with open("settings/blacklist.txt", "w") as fp:
  57. for user in mentions:
  58. for line in lines:
  59. if user.id + "\n" != line:
  60. fp.write(line)
  61. else:
  62. fp.write("")
  63. blacklist_amount += 1
  64. return await ctx.send('{} user(s) have been removed from the blacklist'.format(blacklist_amount))
  65. @bot.command(aliases=["setavatar"])
  66. @is_owner()
  67. async def changeavatar(self, ctx, url=None):
  68. """
  69. Changes the bot's avatar. Can't be a gif.
  70. Usage:
  71. ;changeavatar [url]
  72. Attaching a file and leaving the url parameter blank also works.
  73. """
  74. avaimg = 'avaimg'
  75. if ctx.message.attachments:
  76. await ctx.message.attachments[0].save(avaimg)
  77. else:
  78. thing = url.strip('<>')
  79. async with aiohttp.ClientSession() as session:
  80. async with session.get(thing) as img:
  81. with open(avaimg, 'wb') as f:
  82. f.write(await img.read())
  83. with open(avaimg, 'rb') as f:
  84. await self.bot.user.edit(avatar=f.read())
  85. os.remove(avaimg)
  86. asyncio.sleep(2)
  87. return await ctx.send(":ok_hand:")
  88. @bot.command(aliases=["nick", "nickname"])
  89. @is_owner()
  90. @bot_has_permissions(change_nickname=True)
  91. async def changenickname(self, ctx, *, nick):
  92. """Changes the bot's nickname in the guild.
  93. Usage:
  94. ;nickname [nickname]"""
  95. await self.bot.change_nickname(ctx.message.server.me, nick)
  96. return await ctx.send(":thumbsup:")
  97. @bot.command(aliases=["activity"])
  98. @is_owner()
  99. async def changeactivity(self, ctx, *, game: str):
  100. """Changes the "playing" status of the bot.
  101. Usage:
  102. ;changeactivity` [game]"""
  103. if game.lower() == "none":
  104. game= None
  105. else:
  106. game = discord.Game(game)
  107. await self.bot.change_presence(activity=game)
  108. return await ctx.send(":ok_hand: Activity set to {}".format(str(game)))
  109. @bot.command(aliases=["status"])
  110. @is_owner()
  111. async def changestatus(self, ctx, status: str):
  112. """Changes the status of the bot.
  113. Usage:
  114. ;changesatus [game]"""
  115. status = status.lower()
  116. if status == 'offline' or status == 'invisible':
  117. discordStatus = discord.Status.invisible
  118. elif status == 'idle':
  119. discordStatus = discord.Status.idle
  120. elif status == 'dnd':
  121. discordStatus = discord.Status.dnd
  122. else:
  123. discordStatus = discord.Status.online
  124. await self.bot.change_presence(status=discordStatus)
  125. await ctx.send("**:ok:** Status set to {}".format(discordStatus))
  126. @bot.command()
  127. @is_owner()
  128. async def restart(self, ctx):
  129. """Restarts the bot."""
  130. await self.bot.logout()
  131. return os.execl(sys.executable, sys.executable, *sys.argv)
  132. @bot.command()
  133. @is_owner()
  134. async def shutdown(self, ctx):
  135. """Shuts down the bot."""
  136. await self.bot.logout()
  137. return exit(0)
  138. @bot.command()
  139. @checks.is_owner_or_admin()
  140. async def printsettings(self, ctx, option=None):
  141. "OWNER OR ADMIN ONLY: Prints the servers settings file."
  142. config = guild_settings.get(ctx.guild)
  143. em = discord.Embed(colour=0xDEADBF)
  144. em.set_author(name="{} settings for {}.".format(self.bot.user.name, ctx.message.guild.name), icon_url=self.bot.user.avatar_url)
  145. if option in config.settings:
  146. settingcontent = ""
  147. for x in config.settings[option].items():
  148. settingcontent += str(x).strip("()") + "\n"
  149. em.add_field(name=option, value=settingcontent, inline=False)
  150. return await ctx.send(embed=em)
  151. else:
  152. for settings in config.settings:
  153. if settings != "custom_commands" and settings != "warnings":
  154. settingcontent = ""
  155. for x in config.settings[settings].items():
  156. settingcontent += str(x).strip("()") + "\n"
  157. em.add_field(name=settings, value=settingcontent, inline=False)
  158. elif settings == "custom_commands":
  159. em.add_field(name="custom_commands", value="For Custom Commands, use the custom list command.", inline=False)
  160. return await ctx.send(embed=em)
  161. @group()
  162. @checks.is_admin_or_mod()
  163. async def settings(self, ctx):
  164. if ctx.invoked_subcommand is None:
  165. return await ctx.send('Missing Argument')
  166. self.guild_settings = guild_settings.get(ctx.guild)
  167. @settings.command(aliases=["sa"])
  168. async def selfassign(self, ctx, selection, *, changes = None):
  169. """Edits settings for self assign cog.
  170. Options:
  171. enable/disable: Enable/disables the cog.
  172. addrole/removerole: adds or removes a role that can be self assigned in the server.
  173. """
  174. selection = selection.lower()
  175. role = discord.utils.find(lambda u: u.name == changes, ctx.message.guild.roles)
  176. self_assign = self.guild_settings.self_assign
  177. if selection == "enable":
  178. self_assign["enabled"] = 1
  179. await ctx.send("'self_assign' was enabled!")
  180. elif selection == "disable":
  181. self_assign["enabled"] = 0
  182. await ctx.send("'self_assign' was disabled :cry:")
  183. elif selection == "addrole":
  184. if role.id in self_assign["roles"]:
  185. return await ctx.send("{} is already a self-assignable role.".format(role.name))
  186. self_assign["roles"].append(role.id)
  187. await ctx.send('Role "{}" added'.format(str(role)))
  188. elif selection == "removerole":
  189. if role.id in self_assign["roles"]:
  190. self_assign["roles"].remove(role.id)
  191. await ctx.send('"{}" has been removed from the self-assignable roles.'.format(str(role)))
  192. else:
  193. return await ctx.send("That role was not in the list.")
  194. else:
  195. return await ctx.send("No valid option given.")
  196. return self.guild_settings.update(self_assign, "self_assign")
  197. @settings.command(aliases=["jl"])
  198. async def joinleave(self, ctx, selection, *, changes = None):
  199. """Edits settings for joinleave cog.
  200. Options:
  201. enable/disable: Enable/disables parts of the cog. Needs to specify which part.
  202. Example:
  203. ;settings joinleave enable greets|goodbyes
  204. greetschannel/goodbyeschannel: Sets the channels for either option. Must be a ID or mention.
  205. custommessage: specifies a custom message for the greet messages.
  206. """
  207. selection = selection.lower()
  208. channel = self.get_channel(ctx, changes)
  209. greets = self.guild_settings.greets
  210. goodbyes = self.guild_settings.goodbyes
  211. if changes == "greets":
  212. if selection == "enable":
  213. greets["enabled"] = 1
  214. await ctx.send("'greets' was enabled!")
  215. elif selection == "disable":
  216. greets["enabled"] = 0
  217. await ctx.send("'greets' was disabled :cry:")
  218. elif changes == "goodbyes":
  219. if selection == "enable":
  220. goodbyes["enabled"] = 1
  221. await ctx.send("'goodbyes' was enabled!")
  222. elif selection == "disable":
  223. goodbyes["enabled"] = 0
  224. await ctx.send("'goodbyes' was disabled :cry:")
  225. else:
  226. if selection == "greetschannel":
  227. greets["welcome-channel"] = channel.id
  228. changes = "greets"
  229. await ctx.send("{} has been set as the welcome channel!".format(channel.mention))
  230. elif selection == "goodbyeschannel":
  231. goodbyes["goodbye-channel"] = channel.id
  232. changes = "goodbyes"
  233. await ctx.send("{} has been set as the goodbye channel!".format(channel.mention))
  234. elif selection == "custommessage":
  235. greets["custom-message"] = changes
  236. changes = "greets"
  237. await ctx.send("Custom message set to '{}'".format(changes))
  238. else:
  239. return await ctx.send("No valid option given.")
  240. if changes == "greets":
  241. return self.guild_settings.update(greets, "greets")
  242. elif changes == "goodbyes":
  243. return self.guild_settings.update(goodbyes, "goodbyes")
  244. @settings.command()
  245. async def twitch(self, ctx, selection, *, changes = None):
  246. """Edits settings for self assign cog.
  247. Options:
  248. enable/disable: Enable/disables the cog.
  249. channel: Sets the channel to shill in.
  250. """
  251. selection = selection.lower()
  252. twitch = self.guild_settings.twitch
  253. if selection == "enable":
  254. twitch["enabled"] = 1
  255. await ctx.send("'twitch' was enabled!")
  256. elif selection == "disable":
  257. twitch["enabled"] = 0
  258. await ctx.send("'twitch' was disabled :cry:")
  259. elif selection == "channel":
  260. channel = self.get_channel(ctx, changes)
  261. twitch["channel"] = channel.id
  262. await ctx.send("{} has been set as the twitch shilling channel!".format(channel.mention))
  263. # Is lacking whitelist options. Might be added or might be depreciated.
  264. # Turns out this is handled in the cog and I don't think it needs changing but may be confusing.
  265. else:
  266. return await ctx.send("No valid option given.")
  267. return self.guild_settings.update(twitch, "twitch")
  268. @settings.command(aliases=["perms"])
  269. async def permrole(self, ctx, selection, *, changes = None):
  270. """Edits settings for permission roles.
  271. Options:
  272. addadmin/removeadmin: Adds/Removes admin role.
  273. addmod/removemod: Adds/Removes mod role.
  274. Example:
  275. ;settings permrole addadmin Admin
  276. """
  277. selection = selection.lower()
  278. role = discord.utils.find(lambda u: u.name == changes, ctx.message.guild.roles)
  279. perm_roles = self.guild_settings.perm_roles
  280. if selection == "addadmin":
  281. if role.id not in perm_roles["admin"]:
  282. perm_roles["admin"].append(role.id)
  283. await ctx.send("'{}' has been added to the Admin role list.".format(role.name))
  284. else:
  285. return await ctx.send("'{}' is already in the list.".format(role.name))
  286. elif selection == "addmod":
  287. if role.id not in perm_roles["mod"]:
  288. perm_roles["mod"].append(role.id)
  289. await ctx.send("'{}' has been added to the Mod role list.".format(role.name))
  290. else:
  291. return await ctx.send("'{}' is already in the list.".format(role.name))
  292. elif selection == "removeadmin":
  293. try:
  294. perm_roles["admin"].remove(role.id)
  295. await ctx.send("'{}' has been removed from the Admin role list.".format(role.name))
  296. except ValueError:
  297. return await ctx.send("That role was not in the list.")
  298. elif selection == "removemod":
  299. try:
  300. perm_roles["mod"].remove(role.id)
  301. await ctx.send("'{}' has been removed from the Mod role list.".format(role.name))
  302. except ValueError:
  303. return await ctx.send("That role was not in the list.")
  304. else:
  305. return await ctx.send("No valid option given.")
  306. return self.guild_settings.update(perm_roles, "perm_roles")
  307. @settings.command()
  308. async def gss(self, ctx, selection, *, changes = None):
  309. """Custom Cog for the GaySoundsShitposts Discord Server."""
  310. selection = selection.lower()
  311. gss = self.guild_settings.gss
  312. if selection == "loggingchannel":
  313. channel = self.get_channel(ctx, changes)
  314. gss["log_channel"] = channel.id
  315. await ctx.send("Logging Channel set to '{}'".format(channel.name))
  316. elif selection == "requireddays":
  317. gss["required_days"] = int(changes)
  318. await ctx.send("Required days set to '{}'".format(str(changes)))
  319. elif selection == "requiredscore":
  320. gss["required_score"] = int(changes)
  321. await ctx.send("Required score set to '{}'".format(str(changes)))
  322. else:
  323. return await ctx.send("No valid option given.")
  324. return self.guild_settings.update(gss, "gss")
  325. @settings.command()
  326. async def nsfw(self, ctx, selection, *, changes = None):
  327. """Edits settings for the nsfw cog and other nsfw commands.
  328. If nsfw is enabled and nsfw channels are added, the bot will only allow nsfw commands in the specified channels.
  329. Options:
  330. enable/disable: Enable/disables nsfw commands.
  331. addchannel/removechannel: Adds/Removes a nsfw channel.
  332. Example:
  333. ;settings nsfw addchannel #nsfw_stuff
  334. """
  335. selection = selection.lower()
  336. nsfw = self.guild_settings.nsfw
  337. if selection == "enable":
  338. nsfw["enabled"] = 1
  339. await ctx.send("'nsfw' was enabled!")
  340. elif selection == "disable":
  341. nsfw["enabled"] = 0
  342. await ctx.send("'nsfw' was disabled :cry:")
  343. elif selection == "addchannel":
  344. channel = self.get_channel(ctx, changes)
  345. if channel.id not in nsfw["channels"]:
  346. nsfw["channels"].append(channel.id)
  347. await ctx.send("'{}' has been added to the nsfw channel list.".format(channel.name))
  348. else:
  349. return await ctx.send("'{}' is already in the list.".format(channel.name))
  350. elif selection == "removechannel":
  351. channel = self.get_channel(ctx, changes)
  352. try:
  353. nsfw["channels"].remove(channel.id)
  354. await ctx.send("'{}' has been removed from the nsfw channel list.".format(channel.name))
  355. except ValueError:
  356. return await ctx.send("That role was not in the list.")
  357. elif selection == "addbadtag":
  358. if changes not in nsfw["nsfw"]["blacklist"]:
  359. nsfw["blacklist"].append(changes)
  360. await ctx.send("'{}' has been added to the blacklisted tag list.".format(changes))
  361. else:
  362. return await ctx.send("'{}' is already in the list.".format(changes))
  363. elif selection == "removebadtag":
  364. try:
  365. nsfw["blacklist"].remove(changes)
  366. await ctx.send("'{}' has been removed from the blacklisted tag list.".format(changes))
  367. except ValueError:
  368. return await ctx.send("That tag was not in the blacklisted tag list.")
  369. else:
  370. return await ctx.send("No valid option given.")
  371. return self.guild_settings.update(nsfw, "nsfw")
  372. @checks.is_admin_or_mod()
  373. @bot.command()
  374. async def serverisanal(self, ctx):
  375. """Tells the bot where the server is anal or not.
  376. This only changes if roxbot can do the suck and spank commands outside of the specified nsfw channels."""
  377. is_anal = self.guild_settings.is_anal
  378. if is_anal["y/n"] == 0:
  379. is_anal["y/n"] = 1
  380. self.guild_settings.update(is_anal, "is_anal")
  381. await ctx.send("I now know this server is anal")
  382. else:
  383. is_anal["y/n"] = 0
  384. self.guild_settings.update(is_anal, "is_anal")
  385. await ctx.send("I now know this server is NOT anal")
  386. return self.guild_settings.update()
  387. def setup(bot_client):
  388. bot_client.add_cog(Settings(bot_client))