Browse Source

Merged testing with master and some minor tweaks.

tags/v0.3.3
roxie 7 years ago
parent
commit
d4cabb6d6d
13 changed files with 686 additions and 368 deletions
  1. +0
    -1
      blacklist.txt
  2. +252
    -0
      cogs/Admin.py
  3. +103
    -0
      cogs/Fun.py
  4. +81
    -0
      cogs/Twitch.py
  5. +7
    -0
      cogs/__init__.py
  6. +115
    -0
      cogs/selfAssign.py
  7. +0
    -1
      config.json
  8. +0
    -0
      config/__init__.py
  9. +0
    -0
      config/blacklist.txt
  10. +1
    -0
      config/config.json
  11. +77
    -0
      config/config.py
  12. +7
    -0
      config/settings.ini
  13. +43
    -366
      main.py

+ 0
- 1
blacklist.txt View File

@@ -1 +0,0 @@
190105096934129665

+ 252
- 0
cogs/Admin.py View File

@@ -0,0 +1,252 @@
import os
import sys
import aiohttp
import asyncio

from main import owner_id
from config.config import Config

import discord
from discord.ext.commands import bot


def owner(ctx):
return owner_id == ctx.message.author.id


class Admin():
def __init__(self, Bot):
self.bot = Bot
self.con = Config(Bot)

@bot.command(pass_context=True, hidden=True)
async def blacklist(self, ctx, option, *args):
"""
Usage:
.blacklist [ + | - | add | remove ] @UserName [@UserName2 ...]

Add or remove users to the blacklist.
Blacklisted users are forbidden from using bot commands.
Only the bot owner can use this command
"""
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
blacklist_amount = 0
mentions = ctx.message.mentions

if not mentions:
return await self.bot.say("You didn't mention anyone")

if option not in ['+', '-', 'add', 'remove']:
return await self.bot.say('Invalid option "%s" specified, use +, -, add, or remove' % option, expire_in=20)

for user in mentions:
if user.id == owner_id:
print("[Commands:Blacklist] The owner cannot be blacklisted.")
await self.bot.say("The owner cannot be blacklisted.")
mentions.remove(user)

if option in ['+', 'add']:
with open("config/blacklist.txt", "r") as fp:
for user in mentions:
for line in fp.readlines():
if user.id + "\n" in line:
mentions.remove(user)

with open("config/blacklist.txt", "a+") as fp:
lines = fp.readlines()
for user in mentions:
if user.id not in lines:
fp.write("{}\n".format(user.id))
blacklist_amount += 1
return await self.bot.say('{} user(s) have been added to the blacklist'.format(blacklist_amount))

elif option in ['-', 'remove']:
with open("config/blacklist.txt", "r") as fp:
lines = fp.readlines()
with open("config/blacklist.txt", "w") as fp:
for user in mentions:
for line in lines:
if user.id + "\n" != line:
fp.write(line)
else:
fp.write("")
blacklist_amount += 1
return await self.bot.say('{} user(s) have been removed from the blacklist'.format(blacklist_amount))


@bot.command(pass_context=True, hidden=True)
async def enablesetting(self, ctx, setting):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
if setting in self.con.serverconfig[ctx.message.server.id]:
self.con.serverconfig = self.con.load_config()
if not self.con.serverconfig[ctx.message.server.id][setting]["enabled"]:
self.con.serverconfig[ctx.message.server.id][setting]["enabled"] = 1
self.con.updateconfig()
return await self.bot.say("'{}' was enabled!".format(setting))
else:
self.con.serverconfig[ctx.message.server.id][setting]["enabled"] = 0
self.con.updateconfig()
return await self.bot.say("'{}' was disabled :cry:".format(setting))
else:
return await self.bot.say("That module dont exist fam. You made the thing")

@bot.command(pass_context=True, hidden=True)
async def set_welcomechannel(self, ctx, channel: discord.Channel = None):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
self.con.serverconfig = self.con.load_config()
self.con.serverconfig[ctx.message.server.id]["greets"]["welcome-channel"] = channel.id
self.con.updateconfig()
return await self.bot.say("{} has been set as the welcome channel!".format(channel.mention))

@bot.command(pass_context=True, hidden=True)
async def set_goodbyechannel(self, ctx, channel: discord.Channel = None):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
self.con.serverconfig = self.con.load_config()
self.con.serverconfig[ctx.message.server.id]["goodbyes"]["goodbye-channel"] = channel.id
self.con.updateconfig()
return await self.bot.say("{} has been set as the goodbye channel!".format(channel.mention))

@bot.command(pass_context=True, hidden=True)
async def set_twitchchannel(self, ctx, channel: discord.Channel = None):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
self.con.serverconfig = self.con.load_config()
self.con.serverconfig[ctx.message.server.id]["twitch_shilling"]["twitch-channel"] = channel.id
self.con.updateconfig()
return await self.bot.say("{} has been set as the twitch shilling channel!".format(channel.mention))

@bot.command(pass_context=True, visible=False)
async def set_customwelcomemessage(self, ctx, *, message: str):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
self.con.serverconfig = self.con.load_config()
self.con.serverconfig[ctx.message.server.id]["greets"]["custom_message"] = message
self.con.updateconfig()
return await self.bot.say("Custom message set to '{}'".format(message))

@bot.command(pass_context=True, hidden=True, aliases=["setava"])
async def changeavatar(self, ctx, url=None):
"""
Usage:
{command_prefix}setavatar [url]

Changes the bot's avatar.
Attaching a file and leaving the url parameter blank also works.
"""
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)

if ctx.message.attachments:
thing = ctx.message.attachments[0]['url']
else:
thing = url.strip('<>')

avaimg = 'avaimg.png'
async with aiohttp.get(thing) as img:
with open(avaimg, 'wb') as f:
f.write(await img.read())
with open(avaimg, 'rb') as f:
await self.bot.edit_profile(avatar=f.read())
os.remove(avaimg)
asyncio.sleep(2)
return await self.bot.say(":ok_hand:")

@bot.command(pass_context=True, hidden=True, aliases=["nick"])
async def changenickname(self, ctx, *nick):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
if ctx.message.channel.permissions_for(ctx.message.server.me).change_nickname:
await self.bot.change_nickname(ctx.message.server.me, ' '.join(nick))
return await self.bot.say(":thumbsup:")
else:
return await self.bot.say("I don't have permission to do that :sob:", delete_after=self.con.delete_after)

@bot.command(pass_context=True, hidden=True, aliases=["setgame", "game"])
async def changegame(self, ctx, *, game: str):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
if game.lower() == "none":
game_name = None
else:
game_name = discord.Game(name=game)
await self.bot.change_presence(game=game_name, afk=False)
return await self.bot.say(":ok_hand: Game set to {}".format(str(game_name)))

@bot.command(pass_context=True, hidden=True, aliases=["status"])
async def changestatus(self, ctx, status: str):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
status = status.lower()
if status == 'offline' or status == 'invisible':
discordStatus = discord.Status.invisible
elif status == 'idle':
discordStatus = discord.Status.idle
elif status == 'dnd':
discordStatus = discord.Status.dnd
else:
discordStatus = discord.Status.online
await self.bot.change_presence(status=discordStatus)
await self.bot.say("**:ok:** Status set to {}".format(discordStatus))

@bot.command(pass_context=True, hidden=True)
async def echo(self, ctx, channel, *, message: str):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
if ctx.message.channel_mentions:
for channel in ctx.message.channel_mentions:
await self.bot.send_message(channel, content=message)
return await self.bot.say(":point_left:")
elif channel.isdigit():
channel = ctx.message.server.get_channel(channel)
await self.bot.send_message(channel, content=message)
return await self.bot.say(":point_left:")
else:
return await self.bot.say("You did something wrong smh")

@bot.command(pass_context=True, hidden=True)
async def restart(self, ctx):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)

await self.bot.logout()
return os.execl(sys.executable, sys.executable, *sys.argv)

@bot.command(pass_context=True, hidden=True)
async def shutdown(self, ctx):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)

await self.bot.logout()
return exit(0)

@bot.command(pass_context=True, hidden=True)
async def announce(self, ctx, *announcement):
"""
ONLY USE FOR SERIOUS ANNOUNCEMENTS
"""
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
embed = discord.Embed(title="RoxBot Announcement", colour=discord.Colour(0x306f99), description=' '.join(announcement))
embed.set_footer(text="This message has be automatically generated by a QT Roxie",
icon_url=self.bot.user.avatar_url)
for server in self.bot.servers:
await self.bot.send_message(server, embed=embed)
return await self.bot.say("Done!", delete_after=self.con.delete_after)


def setup(Bot):
Bot.add_cog(Admin(Bot))

+ 103
- 0
cogs/Fun.py View File

@@ -0,0 +1,103 @@
import random

from discord.ext.commands import bot


class Fun():
def __init__(self, Bot):
self.bot = Bot

@bot.command(pass_context=True)
async def roll(self, ctx, die):
"""
Rolls a die using ndx format.
Usage:
{command_prefix}roll ndx
Example:
.roll 2d20 # Rolls two D20s
"""
# TODO: Change to ndx format
dice = 0
if die[0].isdigit():
if die[1].isdigit() or die[0] == 0:
return await self.bot.say("I only support multipliers from 1-9")
multiplier = int(die[0])
else:
multiplier = 1
if die[1].lower() != "d":
return await self.bot.say("Use the format 'ndx'.")
options = (4, 6, 8, 10, 12, 20, 100)
for option in options:
if die.endswith(str(option)):
dice = option
if dice == 0:
return await self.bot.say("You didn't give a die to use.")

rolls = []
if dice == 100:
step = 10
else:
step = 1

total = 0
if multiplier > 1:
for x in range(multiplier):
rolls.append(random.randrange(step, dice+1, step))
for r in rolls:
total += r
return await self.bot.say("{} rolled **{}**. Totaling **{}**".format(ctx.message.author.mention, rolls, total))
else:
roll = random.randrange(step, dice + 1, step)
return await self.bot.say("{} rolled a **{}**".format(ctx.message.author.mention, roll))

@bot.command(pass_context=True)
async def suck(self, ctx):
"""
Sucks the mentioned user ;)
Usage:
{command_prefix}suck @user#9999
"""
if len(ctx.message.mentions) < 1:
return await self.bot.say("You didn't mention someone for me to suck")
user = ctx.message.mentions[0]
return await self.bot.say(":eggplant: :sweat_drops: :tongue: {}".format(user.mention))

@bot.command(pass_context=True, aliases=["wf"])
async def waifurate(self, ctx):
"""
Rates the mentioned waifu(s)
Usage:
{command_prefix}waifurate @user#9999
"""
mentions = ctx.message.mentions
if not mentions:
return await self.bot.reply("You didn't mention anyone for me to rate.", delete_after=10)

rating = random.randrange(1, 11)
if rating <= 2:
emoji = ":sob:"
elif rating <= 4:
emoji = ":disappointed:"
elif rating <= 6:
emoji = ":thinking:"
elif rating <= 8:
emoji = ":blush:"
elif rating == 9:
emoji = ":kissing_heart:"
else:
emoji = ":heart_eyes:"

if len(mentions) > 1:
return await self.bot.say("Oh poly waifu rating? :smirk: Your combined waifu rating is {}/10. {}".format(rating, emoji))
else:
return await self.bot.say("Oh that's your waifu? I rate them a {}/10. {}".format(rating, emoji))

@bot.command(pass_context=True, aliases=["cf"])
async def coinflip(self, ctx):
"""Flip a coin"""
return await self.bot.reply("the coin landed on {}!".format(random.choice(["heads", "tails"])))


def setup(Bot):
Bot.add_cog(Fun(Bot))

+ 81
- 0
cogs/Twitch.py View File

@@ -0,0 +1,81 @@
from discord.ext.commands import bot
import discord
from main import blacklisted
from cogs.Admin import owner
from config.config import Config


class Twitch():
def __init__(self, bot):
self.bot = bot
self.con = Config(bot)

async def on_member_update(self, member_b, member_a):
# Twitch Shilling Part
if blacklisted(member_b):
return
ts_enabled = self.con.serverconfig[member_a.server.id]["twitch"]["enabled"]
if ts_enabled:
if not self.con.serverconfig[member_a.server.id]["twitch"]["whitelist"][
"enabled"] or member_a.id in \
self.con.serverconfig[member_a.server.id]["twitch"]["whitelist"]["list"]:
if member_a.game:
if member_a.game.type:
channel = discord.Object(
self.con.serverconfig[member_a.server.id]["twitch"]["twitch-channel"])
return await self.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))

@bot.command(pass_context=True, hidden=True)
async def ts_enablewhitelist(self, ctx):
if not owner(ctx):
return await self.bot.reply("You do not have permission to do this command.", delete_after=20)
else:
self.con.serverconfig = self.con.load_config()
if not self.con.serverconfig[ctx.server.id]["twitch"]["whitelist"]["enabled"]:
self.con.serverconfig[ctx.server.id]["twitch"]["whitelist"]["enabled"] = 1
self.con.updateconfig()
return await self.bot.reply("Whitelist for Twitch shilling has been enabled.")
else:
self.con.serverconfig[ctx.server.id]["twitch"]["whitelist"]["enabled"] = 0
self.con.updateconfig()
return await self.bot.reply("Whitelist for Twitch shilling has been disabled.")

@bot.command(pass_context=True, hidden=True)
async def ts_whitelist(self, ctx, option, *mentions):
if not owner(ctx):
return await self.bot.reply("You do not have permission to do this command.", delete_after=20)

whitelist_count = 0

if not ctx.message.mentions and option != 'list':
return await self.bot.reply("You haven't mentioned anyone to whitelist.")

if option not in ['+', '-', 'add', 'remove', 'list']:
return await self.bot.say('Invalid option "%s" specified, use +, -, add, or remove' % option, expire_in=20)

if option in ['+', 'add']:
self.con.serverconfig = self.con.load_config()
for user in ctx.message.mentions:
self.con.serverconfig[ctx.message.server.id]["twitch"]["whitelist"]["list"].append(user.id)
self.con.updateconfig()
whitelist_count += 1
return await self.bot.say('{} user(s) have been added to the whitelist'.format(whitelist_count))

elif option in ['-', 'remove']:
self.con.serverconfig = self.con.load_config()
for user in ctx.message.mentions:
if user.id in self.con.serverconfig[ctx.message.server.id]["twitch"]["whitelist"]["list"]:
self.con.serverconfig[ctx.message.server.id]["twitch"]["whitelist"]["list"].remove(user.id)
self.con.updateconfig()
whitelist_count += 1
return await self.bot.say('{} user(s) have been removed to the whitelist'.format(whitelist_count))

elif option == 'list':
return await self.bot.say(
self.con.serverconfig[ctx.message.server.id]["twitch"]["whitelist"]["list"])


def setup(bot):
bot.add_cog(Twitch(bot))

+ 7
- 0
cogs/__init__.py View File

@@ -0,0 +1,7 @@
import json
cogs = [
'cogs.Admin',
'cogs.Twitch',
'cogs.selfAssign',
'cogs.Fun'
]

+ 115
- 0
cogs/selfAssign.py View File

@@ -0,0 +1,115 @@
from discord.ext.commands import bot
import discord

from main import owner_id
from config.config import Config


def owner(ctx):
return owner_id == ctx.message.author.id


class selfAssign():
def __init__(self, Bot):
self.bot = Bot
self.con = Config(Bot)

@bot.command(pass_context=True)
async def listroles(self, ctx):
"""
List's all roles that can be self-assigned on this server.
Usage:
{command_prefix}listroles
"""
roles = []
for role in self.con.serverconfig[ctx.message.server.id]["selfAssign"]["roles"]:
for serverrole in ctx.message.server.roles:
if role == serverrole.id:
roles.append(serverrole.name)
return await self.bot.say(roles)

@bot.command(pass_context=True)
async def iam(self, ctx, role: discord.Role = None):
"""
Self-assign yourself a role. Only one role at a time. Doesn't work for roles with spaces.
Usage:
{command_prefix}iam [role]
Example:
.iam OverwatchPing
"""
self.con.serverconfig = self.con.load_config()
if not self.con.serverconfig[ctx.message.server.id]["selfAssign"]["enabled"]:
return

user = ctx.message.author
server = ctx.message.server

if role not in server.roles:
return await self.bot.say("That role doesn't exist. Roles are case sensitive. ")

if role in user.roles:
return await self.bot.say("You already have that role.")

if role.id in self.con.serverconfig[ctx.message.server.id]["selfAssign"]["roles"]:
await self.bot.add_roles(user, role)
print("{} added {} to themselves in {} on {}".format(user.display_name, role.name, ctx.message.channel,
ctx.message.server))
return await self.bot.say("Yay {}! You now have the {} role!".format(user.mention, role.name))
else:
return await self.bot.say("That role is not self-assignable.")

@bot.command(pass_context=True)
async def iamn(self, ctx, role: discord.Role = None):
"""
Remove a self-assigned role
Usage:
{command_prefix}iamn [role]
Example:
.iamn OverwatchPing
"""
self.con.serverconfig = self.con.load_config()
if not self.con.serverconfig[ctx.message.server.id]["selfAssign"]["enabled"]:
return

user = ctx.message.author
server = ctx.message.server

if role not in server.roles:
return await self.bot.say("That role doesn't exist. Roles are case sensitive. ")

elif role in user.roles and role.id in self.con.serverconfig[ctx.message.server.id]["selfAssign"]["roles"]:
await self.bot.remove_roles(user, role)
return await self.bot.reply("{} has been successfully removed.".format(role.name))

elif role not in user.roles and role.id in self.con.serverconfig[ctx.message.server.id]["selfAssign"]["roles"]:
return await self.bot.reply("You do not have {}.".format(role.name))
else:
return await self.bot.say("That role is not self-assignable.")

@bot.command(pass_context=True, hidden=True)
async def addrole(self, ctx, role: discord.Role = None):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
if role.id in self.con.serverconfig[ctx.message.server.id]["selfAssign"]["roles"]:
return await self.bot.say("{} is already a self-assignable role.".format(role.name), delete_after=self.con.delete_after)
self.con.serverconfig = self.con.load_config()
self.con.serverconfig[ctx.message.server.id]["selfAssign"]["roles"].append(role.id)
self.con.updateconfig()
return await self.bot.say('Role "{}" added'.format(str(role)))

@bot.command(pass_context=True, hidden=True)
async def removerole(self, ctx, role: discord.Role = None):
if not owner(ctx):
return await self.bot.reply(self.con.no_perms_reponse, delete_after=self.con.delete_after)
else:
self.con.serverconfig = self.con.load_config()
if role.id in self.con.serverconfig[ctx.message.server.id]["selfAssign"]["roles"]:
self.con.serverconfig[ctx.message.server.id]["selfAssign"]["roles"].remove(role.id)
self.con.updateconfig()
return await self.bot.say('"{}" has been removed from the self-assignable roles.'.format(str(role)))
else:
return await self.bot.say("That role was not in the list.")

def setup(Bot):
Bot.add_cog(selfAssign(Bot))

+ 0
- 1
config.json View File

@@ -1 +0,0 @@
{"304048071963312130": {"greets": {"enabled": 0, "welcome-channel": "", "member-role": ""}, "goodbyes": {"enabled": 0, "goodbye-channel": ""}, "self-assign_roles": {"enabled": 0, "roles": []}, "twitch_shilling": {"enabled": 1, "twitch-channel": "304048071963312130", "whitelist": {"enabled": 0, "list": ["259869304369971200"]}}}, "175285455204384768": {"greets": {"enabled": 0, "welcome-channel": "", "member-role": ""}, "goodbyes": {"enabled": 0, "goodbye-channel": ""}, "self-assign_roles": {"enabled": 0, "roles": []}, "twitch_shilling": {"enabled": 1, "twitch-channel": "334812611575283712", "whitelist": {"enabled": 0, "list": []}}}}

+ 0
- 0
config/__init__.py View File


+ 0
- 0
config/blacklist.txt View File


+ 1
- 0
config/config.json View File

@@ -0,0 +1 @@
{"175285455204384768": {"greets": {"enabled": 0, "welcome-channel": "", "member-role": "", "custom-message": "", "default-message:": "Be sure to read the rules."}, "goodbyes": {"enabled": 0, "goodbye-channel": ""}, "selfAssign": {"enabled": 0, "roles": []}, "twitch": {"enabled": 0, "twitch-channel": "", "whitelist": {"enabled": 0, "list": []}}}, "304048071963312130": {"greets": {"enabled": 0, "welcome-channel": "", "member-role": "", "custom-message": "", "default-message:": "Be sure to read the rules."}, "goodbyes": {"enabled": 0, "goodbye-channel": ""}, "selfAssign": {"enabled": 0, "roles": []}, "twitch": {"enabled": 0, "twitch-channel": "", "whitelist": {"enabled": 0, "list": []}}}}

+ 77
- 0
config/config.py View File

@@ -0,0 +1,77 @@
import json


class Config():
def __init__(self, bot):
self.serverconfig_template = {
"example": {
"greets": {
"enabled": 0,
"welcome-channel": "",
"member-role": "",
"custom-message": "",
"default-message:": "Be sure to read the rules."
},
"goodbyes": {
"enabled": 0,
"goodbye-channel": "",
},
"selfAssign": {
"enabled": 0,
"roles": []
},
"twitch": {
"enabled": 0,
"twitch-channel": "",
"whitelist": {
"enabled": 0,
"list": []
}
}
}
}
self.serverconfig = self.load_config()
self.bot = bot
self.no_perms_reponse = ":no_entry_sign: You do not have permission to use this command."
self.delete_after = 20

async def on_server_join(self, server):
self.serverconfig[server.id] = self.serverconfig_template["example"]
self.updateconfig()

async def on_server_remove(self, server):
self.serverconfig.pop(server.id)
self.updateconfig()

def load_config(self):
with open('config/config.json', 'r') as config_file:
return json.load(config_file)

def updateconfig(self):
with open('config/config.json', 'w') as conf_file:
json.dump(self.serverconfig, conf_file)

def config_errorcheck(self):
# TODO: Fix so that it checks for problems in children of module settings. i.e children of 'greets'
# TODO: Fix issue where a setting can be enabled when it has no channel to post to.
for server in self.bot.servers:
if server.id not in self.serverconfig:
self.serverconfig[server.id] = self.serverconfig_template["example"]
self.updateconfig()
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()))
else:
for module_setting in self.serverconfig_template["example"]:
if module_setting not in self.serverconfig[server.id]:
self.serverconfig[server.id][module_setting] = self.serverconfig_template["example"][
module_setting]
self.updateconfig()
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()))
print("")


def setup(bot):
bot.add_cog(Config(bot))

+ 7
- 0
config/settings.ini View File

@@ -0,0 +1,7 @@
[Credentials]
; Put your token here.
Token =

[RoxBot]
OwnerID = 142735312626515979
CommandPrefix = .

+ 43
- 366
main.py View File

@@ -1,142 +1,71 @@
# RoxBot
# Version = 1.1
# Author = Roxxers
#!/usr/env python

##############
# To-do List #
##############

# High Priority #
# TODO: Fix Config Bug

# Mid Priority #
# TODO: Move away from using ID's for everything. Maybe replace list with dict
# TODO: Admin tools - For commands already in and things like purge a chat
# TODO: On member role assign, welcome member using on_member_update

# Low Priority #
# TODO: Command Review, look at all commands and flesh them out. Make sure user experience feels nice
# TODO: Better help menu- AutoGen using <command>.help
# TODO: WaifuRater - Mention user and RNG a rating
# TODO: Admin tools - For commands already in and things like purge a chat
# TODO: Overwatch stats - Using Overwatch-API lib
# TODO: Move away from using ID's for everthing. Maybe replace list with dict
# TODO: Add check for no channel id when a module is enabled
# TODO: Formatting, both the code and the messages send. Add more rich embeds

# TODO: Maybe some randomised dialogue so that not every command has only one response.

import json
import random
import configparser

import discord
from discord.ext.commands import Bot

bot = Bot(command_prefix=".")
# bot.remove_command("help")
# TODO: Take these from a file, not the program
token = 'MzA4MDc3ODg3MDYyNTQwMjg5.DEW5YA.JfLfU5jPjTFQi0xFI6B_-SKvC54'
owner_id = "142735312626515979"

config_template = {
"example": {
"greets": {
"enabled": 0,
"welcome-channel": "",
"member-role": ""
},
"goodbyes": {
"enabled": 0,
"goodbye-channel": ""
},
"self-assign_roles": {
"enabled": 0,
"roles": []
},
"twitch_shilling": {
"enabled": 0,
"twitch-channel": "",
"whitelist": {
"enabled": 0,
"list": []
}
}
}
}


def load_config():
with open('config.json', 'r') as config_file:
return json.load(config_file)


def updateconfig():
with open('config.json', 'w') as conf_file:
json.dump(config, conf_file)


def config_errorcheck():
# Checks for errors in the config files and fixes them automatically
for server in bot.servers:
if server.id not in config:
config[server.id] = config_template["example"]
updateconfig()
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()))
else:
for module_setting in config_template["example"]:
if module_setting not in config[server.id]:
config[server.id][module_setting] = config_template["example"][module_setting]
updateconfig()
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()))
from config.config import Config
from cogs import cogs

__version__ = '0.3.2'

def owner(ctx):
if owner_id == ctx.message.author.id:
return True
else:
return False
settings = configparser.ConfigParser()
settings.read('config/settings.ini')

token = settings["Credentials"]["Token"]
owner_id = settings["RoxBot"]["OwnerID"]
command_prefix = settings["RoxBot"]["CommandPrefix"]

def mention_commandee(ctx):
return ctx.message.author
bot = Bot(command_prefix=command_prefix)
con = Config(bot)


def blacklisted(user):
with open("blacklist.txt", "r") as fp:
with open("config/blacklist.txt", "r") as fp:
for line in fp.readlines():
if user.id+"\n" == line:
return True
return False


def dice_roll(num):
if num == 100:
step = 10
else:
step = 1
return random.randrange(step, num+1, step)


@bot.event
async def on_ready():
# TODO: First part needs to be moved to wait_until_ready
config_errorcheck()
con.config_errorcheck()
print("Discord.py version: "+discord.__version__)
print("Client logged in\n")
await bot.change_presence(game=discord.Game(name=__version__), afk=False)
print("Cods loaded:")
for cog in cogs:
bot.load_extension(cog)
print("{}".format(cog))
print("")
print("Servers I am currently in:")
for server in bot.servers:
print(server)
print("")


@bot.event
async def on_member_update(member_b, member_a):
# Twitch Shilling Part

if blacklisted(member_b):
return

ts_enabled = config[member_a.server.id]["twitch_shilling"]["enabled"]
if ts_enabled:
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"]:
if member_a.game:
if member_a.game.type:
channel = discord.Object(config[member_a.server.id]["twitch_shilling"]["twitch-channel"])
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))


@bot.event
async def on_message(message):
if blacklisted(message.author):
@@ -153,287 +82,35 @@ async def on_member_join(member):
:param member:
:return:
"""
if not config[member.server.id]["greets"]["enabled"]:
if not con.serverconfig[member.server.id]["greets"]["enabled"]:
return

print("Passes Enabled Check")
if con.serverconfig[member.server.id]["greets"]["custom-message"]:
message = con.serverconfig[member.server.id]["greets"]["custom-message"]
else:
message = con.serverconfig[member.server.id]["greets"]["default-message"]
print("passed message check")
em = discord.Embed(
title="Welcome to {}!".format(member.server),
description='Hey {}! Welcome to {}! Be sure to read the rules.'.format(member.mention, member.server),
description='Hey {}! Welcome to **{}**! {}'.format(member.mention, member.server, message),
colour=0xDEADBF)

if config[member.server.id]["greets"]["welcome-channel"]:
channel = discord.Object(config[member.server.id]["greets"]["welcome-channel"])
if con.serverconfig[member.server.id]["greets"]["welcome-channel"]:
channel = discord.Object(con.serverconfig[member.server.id]["greets"]["welcome-channel"])
else:
channel = member.server.default_channel
print("passed channel getting")
return await bot.send_message(channel,embed=em)


@bot.event
async def on_member_remove(member):
if not config[member.server.id]["goodbyes"]["enabled"]:
if not con.serverconfig[member.server.id]["goodbyes"]["enabled"]:
return
else:
return await bot.send_message(member.server,embed=discord.Embed(
description="{}#{} has left or been beaned.".format(member.name, member.discriminator), colour=0xDEADBF))


@bot.event
async def on_server_join(server):
config[server.id] = config_template["example"]
updateconfig()


@bot.event
async def on_server_remove(server):
config.pop(server.id)
updateconfig()


@bot.command(pass_context=True)
async def iam(ctx, role: discord.Role = None, *, user: discord.User = None, server: discord.Server = None):

if not config[ctx.message.server.id]["self-assign_roles"]["enabled"]:
return

user = ctx.message.author
server = ctx.message.server

if role not in server.roles:
return await bot.say("That role doesn't exist. Roles are case sensitive. ")

if role in user.roles:
return await bot.say("You already have that role.")

if role.id in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
await bot.add_roles(user, role)
print("{} added {} to themselves in {} on {}".format(user.display_name, role.name, ctx.message.channel,
ctx.message.server))
return await bot.say("Yay {}! You now have the {} role!".format(user.mention, role.name))
else:
return await bot.say("That role is not self-assignable.")


@bot.command(pass_context=True, enabled=False)
async def dice(ctx, num, *, user: discord.User = None):
# TODO: Change to ndx format
die = ("4","6","8","10","12","20","100")
if num not in die:
if num == "help":
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.")
else:
return await bot.say("That is not a dice I know. Try !dice help for help!")
user = mention_commandee(ctx)
roll = dice_roll(int(num))
return await bot.say("You rolled a {}, {}".format(roll,user.mention))


@bot.command(pass_context=True)
async def suck(ctx, user: discord.User = None):
if user is None:
try:
user = ctx.message.mentions[0]
except:
return await bot.say("You didn't mention someone for me to suck")
return await bot.say(":eggplant: :sweat_drops: :tongue: {}".format(user.mention))


@bot.command(enabled=False)
async def printcommands():
for command in bot.commands:
print(command)
return await bot.say("Done.")


@bot.command(pass_context=True)
async def listroles(ctx):
if not config[ctx.message.server.id]["self-assign_roles"]["enabled"]:
return
roles = []
for role in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
for serverrole in ctx.message.server.roles:
if role == serverrole.id:
roles.append(serverrole.name)
return await bot.say(roles)


#################
# Owner Commands#
#################


@bot.command(pass_context=True)
async def blacklist(ctx, option, *mentions):
"""
Usage:
.blacklist [ + | - | add | remove ] @UserName [@UserName2 ...]

Add or remove users to the blacklist.
Blacklisted users are forbidden from using bot commands.
Only the bot owner can use this command
"""
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)
blacklist_amount = 0
mentions = ctx.message.mentions

if not mentions:
return await bot.say("You didn't mention anyone")

if option not in ['+', '-', 'add', 'remove']:
return await bot.say('Invalid option "%s" specified, use +, -, add, or remove' % option, expire_in=20)

for user in mentions:
if user.id == owner_id:
print("[Commands:Blacklist] The owner cannot be blacklisted.")
await bot.say("The owner cannot be blacklisted.")
mentions.remove(user)

if option in ['+', 'add']:
with open("blacklist.txt", "r") as fp:
for user in mentions:
for line in fp.readlines():
if user.id+"\n" in line:
mentions.remove(user)

with open("blacklist.txt","a+") as fp:
lines = fp.readlines()
for user in mentions:
if user.id not in lines:
fp.write("{}\n".format(user.id))
blacklist_amount += 1
return await bot.say('{} user(s) have been added to the blacklist'.format(blacklist_amount))

elif option in ['-', 'remove']:
with open("blacklist.txt","r") as fp:
lines = fp.readlines()
with open("blacklist.txt","w") as fp:
for user in mentions:
for line in lines:
if user.id+"\n" != line:
fp.write(line)
else:
fp.write("")
blacklist_amount += 1
return await bot.say('{} user(s) have been removed from the blacklist'.format(blacklist_amount))


@bot.command(pass_context=True)
async def addrole(ctx, role: discord.Role = None):
# Add Remove List Help
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)
else:
config[ctx.message.server.id]["self-assign_roles"]["roles"].append(role.id)
updateconfig()
return await bot.say('Role "{}" added'.format(str(role)))


@bot.command(pass_context=True)
async def removerole(ctx, role: discord.Role = None):
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)

if role.id in config[ctx.message.server.id]["self-assign_roles"]["roles"]:
config[ctx.message.server.id]["self-assign_roles"]["roles"].remove(role.id)
return await bot.say('"{}" has been removed from the self-assignable roles.'.format(str(role)))
else:
return await bot.say("That role was not in the list.")


@bot.command(pass_context=True)
async def enablemodule(ctx, module):
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)
else:
if module in config[ctx.message.server.id]:
if not config[ctx.message.server.id][module]["enabled"]:
config[ctx.message.server.id][module]["enabled"] = 1
updateconfig()
return await bot.say("'{}' was enabled!".format(module))
else:
config[ctx.message.server.id][module]["enabled"] = 0
updateconfig()
return await bot.say("'{}' was disabled :cry:".format(module))
else:
return await bot.say("That module dont exist fam. You made the thing")


@bot.command(pass_context=True)
async def set_welcomechannel(ctx, channel: discord.Channel = None):
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)
config[ctx.message.server.id]["greets"]["welcome-channel"] = channel.id
updateconfig()
return await bot.say("{} has been set as the welcome channel!".format(channel.mention))


@bot.command(pass_context=True)
async def set_goodbyechannel(ctx, channel: discord.Channel = None):
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)
config[ctx.message.server.id]["goodbyes"]["goodbye-channel"] = channel.id
updateconfig()
return await bot.say("{} has been set as the goodbye channel!".format(channel.mention))


@bot.command(pass_context=True)
async def set_twitchchannel(ctx, channel: discord.Channel = None):
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)
config[ctx.message.server.id]["twitch_shilling"]["twitch-channel"] = channel.id
updateconfig()
return await bot.say("{} has been set as the twitch shilling channel!".format(channel.mention))


@bot.command(pass_context=True)
async def ts_enablewhitelist(ctx):
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)
else:
if not config[ctx.server.id]["twitch_shilling"]["whitelist"]["enabled"]:
config[ctx.server.id]["twitch_shilling"]["whitelist"]["enabled"] = 1
updateconfig()
return await bot.reply("Whitelist for Twitch shilling has been enabled.")
else:
config[ctx.server.id]["twitch_shilling"]["whitelist"]["enabled"] = 0
updateconfig()
return await bot.reply("Whitelist for Twitch shilling has been disabled.")


@bot.command(pass_context=True)
async def ts_whitelist(ctx, option, *mentions):
if not owner(ctx):
return await bot.reply("You do not have permission to do this command.", delete_after=20)

whitelist_count = 0

if not ctx.message.mentions and option != 'list':
return await bot.reply("You haven't mentioned anyone to whitelist.")

if option not in ['+', '-', 'add', 'remove', 'list']:
return await bot.say('Invalid option "%s" specified, use +, -, add, or remove' % option, expire_in=20)

if option in ['+', 'add']:
for user in ctx.message.mentions:
config[ctx.message.server.id]["twitch_shilling"]["whitelist"]["list"].append(user.id)
updateconfig()
whitelist_count += 1
return await bot.say('{} user(s) have been added to the whitelist'.format(whitelist_count))

elif option in ['-', 'remove']:
for user in ctx.message.mentions:
if user.id in config[ctx.message.server.id]["twitch_shilling"]["whitelist"]["list"]:
config[ctx.message.server.id]["twitch_shilling"]["whitelist"]["list"].remove(user.id)
updateconfig()
whitelist_count += 1
return await bot.say('{} user(s) have been removed to the whitelist'.format(whitelist_count))

elif option == 'list':
return await bot.say(config[ctx.message.server.id]["twitch_shilling"]["whitelist"]["list"])


if __name__ == "__main__":
config = load_config()

bot.run(token)

Loading…
Cancel
Save