Complete modification to use cogs
This commit is contained in:
parent
ee03eb3b1b
commit
2bde1ce936
638
bot.py
638
bot.py
|
@ -1,104 +1,35 @@
|
||||||
#!/usr/local/bin/python3.5
|
#!/usr/local/bin/python3.5
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import random
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import urllib.parse
|
|
||||||
import urllib.request
|
|
||||||
import yaml
|
|
||||||
from threading import Timer
|
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
import pymysql.cursors
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
from cogs.utils import config
|
||||||
|
|
||||||
import playlist
|
extensions = ['cogs.interaction',
|
||||||
|
'cogs.core',
|
||||||
|
'cogs.mod',
|
||||||
|
'cogs.owner',
|
||||||
|
'cogs.stats',
|
||||||
|
'cogs.playlist']
|
||||||
|
|
||||||
with open("/home/phxntx5/public_html/bot/config.yml", "r") as f:
|
bot = commands.Bot(command_prefix=config.commandPrefix, description=config.botDescription, pm_help="True")
|
||||||
global_config = yaml.load(f)
|
|
||||||
|
|
||||||
botDescription = global_config.get("description")
|
|
||||||
commandPrefix = global_config.get("command_prefix")
|
|
||||||
|
|
||||||
|
|
||||||
# Custom predicates
|
|
||||||
def isOwner():
|
|
||||||
def predicate(ctx):
|
|
||||||
return ctx.message.author.id == ownerID
|
|
||||||
|
|
||||||
return commands.check(predicate)
|
|
||||||
|
|
||||||
|
|
||||||
def isMod():
|
|
||||||
def predicate(ctx):
|
|
||||||
return ctx.message.author.top_role.permissions.kick_members
|
|
||||||
|
|
||||||
return commands.check(predicate)
|
|
||||||
|
|
||||||
|
|
||||||
def isAdmin():
|
|
||||||
def predicate(ctx):
|
|
||||||
return ctx.message.author.top_role.permissions.manage_server
|
|
||||||
|
|
||||||
return commands.check(predicate)
|
|
||||||
|
|
||||||
|
|
||||||
def isPM():
|
|
||||||
def predicate(ctx):
|
|
||||||
return ctx.message.channel.is_private
|
|
||||||
|
|
||||||
return commands.check(predicate)
|
|
||||||
|
|
||||||
|
|
||||||
def battled():
|
|
||||||
def predicate(ctx):
|
|
||||||
return ctx.message.author == battleP2
|
|
||||||
|
|
||||||
return commands.check(predicate)
|
|
||||||
|
|
||||||
|
|
||||||
bot = commands.Bot(command_prefix=commandPrefix, description=botDescription)
|
|
||||||
music = playlist.Music(bot)
|
|
||||||
bot.add_cog(music)
|
|
||||||
|
|
||||||
|
|
||||||
# Turn battling off, reset users
|
|
||||||
def battlingOff():
|
|
||||||
global battleP1
|
|
||||||
global battleP2
|
|
||||||
global battling
|
|
||||||
battling = False
|
|
||||||
battleP1 = ""
|
|
||||||
battleP2 = ""
|
|
||||||
|
|
||||||
|
|
||||||
# Bot event overrides
|
# Bot event overrides
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_ready():
|
async def on_ready():
|
||||||
# Change the status upon connection to the default status
|
# Change the status upon connection to the default status
|
||||||
game = discord.Game(name=defaultStatus, type=0)
|
game = discord.Game(name=config.defaultStatus, type=0)
|
||||||
await bot.change_status(game)
|
await bot.change_status(game)
|
||||||
cursor = connection.cursor()
|
cursor = config.connection.cursor()
|
||||||
|
|
||||||
'''success = checkSetup(cursor)
|
cursor.execute('use {0}'.format(config.db_default))
|
||||||
if success=="Error: default_db":
|
|
||||||
fmt = "The bot ran into an error while checking for the default database information."
|
|
||||||
await bot.send_message(determineId(ownerID),fmt)
|
|
||||||
elif success="Error: boop_db":
|
|
||||||
fmt = "The bot ran into an error while checking for the boop database information."
|
|
||||||
await bot.send_message(determineId(ownerID),fmt)'''
|
|
||||||
|
|
||||||
cursor.execute('use {0}'.format(db_default))
|
|
||||||
cursor.execute('select channel_id from restart_server where id=1')
|
cursor.execute('select channel_id from restart_server where id=1')
|
||||||
result = cursor.fetchone()['channel_id']
|
result = cursor.fetchone()['channel_id']
|
||||||
if int(result) != 0:
|
if int(result) != 0:
|
||||||
await bot.send_message(determineId(result), "I have just finished restarting!")
|
destination = discord.utils.find(lambda m: m.id == result, bot.get_all_channels())
|
||||||
|
await bot.send_message(destination, "I have just finished restarting!")
|
||||||
cursor.execute('update restart_server set channel_id=0 where id=1')
|
cursor.execute('update restart_server set channel_id=0 where id=1')
|
||||||
connection.commit()
|
config.connection.commit()
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
|
@ -110,540 +41,7 @@ async def on_member_join(member):
|
||||||
async def on_member_remove(member):
|
async def on_member_remove(member):
|
||||||
await bot.say("{0} has left the server, I hope it wasn't because of something I said :c".format(member))
|
await bot.say("{0} has left the server, I hope it wasn't because of something I said :c".format(member))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
# Bot commands
|
for e in extensions:
|
||||||
@bot.command()
|
bot.load_extension(e)
|
||||||
async def joke():
|
bot.run(config.botToken)
|
||||||
try:
|
|
||||||
fortuneCommand = "/usr/bin/fortune riddles"
|
|
||||||
fortune = subprocess.check_output(fortuneCommand.split()).decode("utf-8")
|
|
||||||
await bot.say(fortune)
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
|
||||||
@isOwner()
|
|
||||||
async def restart(ctx):
|
|
||||||
try:
|
|
||||||
cursor = connection.cursor()
|
|
||||||
cursor.execute('use {0}'.format(db_default))
|
|
||||||
sql = "update restart_server set channel_id={0} where id=1".format(ctx.message.channel.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
connection.commit()
|
|
||||||
await bot.say("Restarting; see you in the next life {0}!".format(ctx.message.author.mention))
|
|
||||||
python = sys.executable
|
|
||||||
os.execl(python, python, *sys.argv)
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
|
||||||
@isOwner()
|
|
||||||
async def py(ctx):
|
|
||||||
try:
|
|
||||||
match_single = getter.findall(ctx.message.content)
|
|
||||||
match_multi = multi.findall(ctx.message.content)
|
|
||||||
if not match_single and not match_multi:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
if not match_multi:
|
|
||||||
result = eval(match_single[0])
|
|
||||||
await bot.say("```{0}```".format(result))
|
|
||||||
else:
|
|
||||||
def r(v):
|
|
||||||
loop.create_task(bot.say("```{0}```".format(v)))
|
|
||||||
|
|
||||||
exec(match_multi[0])
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
|
||||||
@isOwner()
|
|
||||||
async def shutdown(ctx):
|
|
||||||
try:
|
|
||||||
fmt = 'Shutting down, I will miss you {0.author.name}'
|
|
||||||
await bot.say(fmt.format(ctx.message))
|
|
||||||
await bot.logout()
|
|
||||||
await bot.close()
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command()
|
|
||||||
@isOwner()
|
|
||||||
async def avatar(content):
|
|
||||||
try:
|
|
||||||
file = '/home/phxntx5/public_html/bot/images/' + content
|
|
||||||
with open(file, 'rb') as fp:
|
|
||||||
await bot.edit_profile(avatar=fp.read())
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command()
|
|
||||||
@isOwner()
|
|
||||||
async def name(newNick):
|
|
||||||
try:
|
|
||||||
await bot.edit_profile(username=newNick)
|
|
||||||
await bot.say('Changed username to ' + newNick)
|
|
||||||
# Restart the bot after this, as profile changes are not immediate
|
|
||||||
python = sys.executable
|
|
||||||
os.execl(python, python, *sys.argv)
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True, no_pm=True)
|
|
||||||
@isOwner()
|
|
||||||
async def leave(ctx):
|
|
||||||
try:
|
|
||||||
await bot.say('Why must I leave? Hopefully I can come back :c')
|
|
||||||
await bot.leave_server(ctx.message.server)
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command()
|
|
||||||
@isMod()
|
|
||||||
async def status(*stat: str):
|
|
||||||
try:
|
|
||||||
newStatus = ' '.join(stat)
|
|
||||||
game = discord.Game(name=newStatus, type=0)
|
|
||||||
await bot.change_status(game)
|
|
||||||
await bot.say("Just changed my status to '{0}'!".format(newStatus))
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
|
||||||
@isMod()
|
|
||||||
async def say(ctx, *msg: str):
|
|
||||||
try:
|
|
||||||
msg = ' '.join(msg)
|
|
||||||
await bot.say(msg)
|
|
||||||
await bot.delete_message(ctx.message)
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command()
|
|
||||||
async def urban(*msg: str):
|
|
||||||
try:
|
|
||||||
term = '+'.join(msg)
|
|
||||||
url = "http://api.urbandictionary.com/v0/define?term={}".format(term)
|
|
||||||
response = urllib.request.urlopen(url)
|
|
||||||
data = json.loads(response.read().decode('utf-8'))
|
|
||||||
if len(data['list']) == 0:
|
|
||||||
await bot.say("No result with that term!")
|
|
||||||
else:
|
|
||||||
await bot.say(data['list'][0]['definition'])
|
|
||||||
except discord.HTTPException:
|
|
||||||
await bot.say('```Error: Defintion is too long for me to send```')
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
|
||||||
async def derpi(ctx, *search: str):
|
|
||||||
try:
|
|
||||||
if len(search) > 0:
|
|
||||||
url = 'https://derpibooru.org/search.json?q='
|
|
||||||
query = '+'.join(search)
|
|
||||||
url += query
|
|
||||||
if ctx.message.channel.id in nsfwChannels:
|
|
||||||
url += ",+explicit&filter_id=95938"
|
|
||||||
# url should now be in the form of url?q=search+terms
|
|
||||||
# Next part processes the json format, and saves the data in useful lists/dictionaries
|
|
||||||
response = urllib.request.urlopen(url)
|
|
||||||
data = json.loads(response.read().decode('utf-8'))
|
|
||||||
results = data['search']
|
|
||||||
|
|
||||||
if len(results) > 0:
|
|
||||||
index = random.randint(0, len(results) - 1)
|
|
||||||
randImageUrl = results[index].get('representations').get('full')[2:]
|
|
||||||
randImageUrl = 'http://' + randImageUrl
|
|
||||||
imageLink = randImageUrl.strip()
|
|
||||||
else:
|
|
||||||
await bot.say("No results with that search term, {0}!".format(ctx.message.author.mention))
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
with urllib.request.urlopen('https://derpibooru.org/images/random') as response:
|
|
||||||
imageLink = response.geturl()
|
|
||||||
url = 'https://shpro.link/redirect.php/'
|
|
||||||
data = urllib.parse.urlencode({'link': imageLink}).encode('ascii')
|
|
||||||
response = urllib.request.urlopen(url, data).read().decode('utf-8')
|
|
||||||
await bot.say(response)
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
|
||||||
async def roll(ctx):
|
|
||||||
try:
|
|
||||||
num = random.randint(1, 6)
|
|
||||||
fmt = '{0.author.name} has rolled a die and got the number {1}!'
|
|
||||||
await bot.say(fmt.format(ctx.message, num))
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(no_pm=True)
|
|
||||||
@battled()
|
|
||||||
async def accept():
|
|
||||||
try:
|
|
||||||
if not battling:
|
|
||||||
return
|
|
||||||
num = random.randint(1, 100)
|
|
||||||
fmt = battleWins[random.randint(0, len(battleWins) - 1)]
|
|
||||||
if num <= 50:
|
|
||||||
await bot.say(fmt.format(battleP1.mention, battleP2.mention))
|
|
||||||
updateBattleRecords(battleP1, battleP2)
|
|
||||||
elif num > 50:
|
|
||||||
await bot.say(fmt.format(battleP2.mention, battleP1.mention))
|
|
||||||
updateBattleRecords(battleP2, battleP1)
|
|
||||||
battlingOff()
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(no_pm=True)
|
|
||||||
@battled()
|
|
||||||
async def decline():
|
|
||||||
try:
|
|
||||||
if not battling:
|
|
||||||
return
|
|
||||||
await bot.say("{0} has chickened out! {1} wins by default!".format(battleP2.mention, battleP1.mention))
|
|
||||||
updateBattleRecords(battleP1, battleP2)
|
|
||||||
battlingOff()
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
|
||||||
async def commands(ctx):
|
|
||||||
try:
|
|
||||||
fmt = 'Hello {0.author.name}!\n\nThis is {1.user.name}! '
|
|
||||||
fmt += 'Here is a list of commands that you have access to '
|
|
||||||
fmt += '(please note that this only includes the commands that you have access to):'
|
|
||||||
await bot.whisper(fmt.format(ctx.message, bot))
|
|
||||||
|
|
||||||
fmt2 = 'I have just sent you a PM, containing all the commands you have access to {0.author.mention}!'
|
|
||||||
ocmds = 'Commands for everyone: ```'
|
|
||||||
for com, act in openCommands.items():
|
|
||||||
ocmds += commandPrefix + com + ": " + act + "\n\n"
|
|
||||||
ocmds += '```'
|
|
||||||
await bot.whisper(ocmds)
|
|
||||||
vcmds = 'Voice Commands: ```'
|
|
||||||
for com, act in voiceCommands.items():
|
|
||||||
vcmds += commandPrefix + com + ": " + act + "\n\n"
|
|
||||||
vcmds += '```'
|
|
||||||
await bot.whisper(vcmds)
|
|
||||||
if ctx.message.author.top_role.permissions.kick_members:
|
|
||||||
if len(modCommands) > 0:
|
|
||||||
mcmds = 'Moderator Commands: ```'
|
|
||||||
for com, act in modCommands.items():
|
|
||||||
mcmds += commandPrefix + com + ": " + act + "\n\n"
|
|
||||||
mcmds += '```'
|
|
||||||
await bot.whisper(mcmds)
|
|
||||||
if ctx.message.author.top_role.permissions.manage_server:
|
|
||||||
if len(adminCommands) > 0:
|
|
||||||
acmds = 'Admin Commands: ```'
|
|
||||||
for com, act in adminCommands.items():
|
|
||||||
acmds += commandPrefix + com + ": " + act + "\n\n"
|
|
||||||
acmds += '```'
|
|
||||||
await bot.whisper(acmds)
|
|
||||||
if ctx.message.author.id == ownerID:
|
|
||||||
if len(ownerCommands) > 0:
|
|
||||||
owncmds = 'Owner Commands: ```'
|
|
||||||
for com, act in ownerCommands.items():
|
|
||||||
owncmds += commandPrefix + com + ": " + act + "\n\n"
|
|
||||||
owncmds += '```'
|
|
||||||
await bot.whisper(owncmds)
|
|
||||||
await bot.say(fmt2.format(ctx.message))
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True, no_pm=True)
|
|
||||||
async def battle(ctx):
|
|
||||||
try:
|
|
||||||
global battleP1
|
|
||||||
global battleP2
|
|
||||||
global battling
|
|
||||||
if battling:
|
|
||||||
return
|
|
||||||
if len(ctx.message.mentions) == 0:
|
|
||||||
await bot.say("You must mention someone in the room " + ctx.message.author.mention + "!")
|
|
||||||
return
|
|
||||||
if len(ctx.message.mentions) > 1:
|
|
||||||
await bot.say("You cannot battle more than one person at once!")
|
|
||||||
return
|
|
||||||
player2 = ctx.message.mentions[0]
|
|
||||||
if ctx.message.author.id == player2.id:
|
|
||||||
await bot.say("Why would you want to battle yourself? Suicide is not the answer")
|
|
||||||
return
|
|
||||||
if bot.user.id == player2.id:
|
|
||||||
await bot.say("I always win, don't even try it.")
|
|
||||||
return
|
|
||||||
fmt = "{0.mention} has challenged you to a battle {1.mention}\n!accept or !decline"
|
|
||||||
battleP1 = ctx.message.author
|
|
||||||
battleP2 = player2
|
|
||||||
await bot.say(fmt.format(ctx.message.author, player2))
|
|
||||||
t = Timer(180, battlingOff)
|
|
||||||
t.start()
|
|
||||||
battling = True
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True, no_pm=True)
|
|
||||||
async def boop(ctx):
|
|
||||||
try:
|
|
||||||
if len(ctx.message.mentions) == 0:
|
|
||||||
await bot.say("You must mention someone in the room " + ctx.message.author.mention + "!")
|
|
||||||
return
|
|
||||||
if len(ctx.message.mentions) > 1:
|
|
||||||
await bot.say("You cannot boop more than one person at once!")
|
|
||||||
return
|
|
||||||
boopee = ctx.message.mentions[0]
|
|
||||||
booper = ctx.message.author
|
|
||||||
if boopee.id == booper.id:
|
|
||||||
await bot.say("You can't boop yourself! Silly...")
|
|
||||||
return
|
|
||||||
if boopee.id == bot.user.id:
|
|
||||||
await bot.say("Why the heck are you booping me? Get away from me >:c")
|
|
||||||
return
|
|
||||||
|
|
||||||
cursor = connection.cursor()
|
|
||||||
cursor.execute('use {0}'.format(db_boops))
|
|
||||||
sql = "show tables like '" + str(booper.id) + "'"
|
|
||||||
cursor.execute(sql)
|
|
||||||
result = cursor.fetchone()
|
|
||||||
amount = 1
|
|
||||||
# Booper's table exists, continue
|
|
||||||
if result is not None:
|
|
||||||
sql = "select `amount` from `" + booper.id + "` where id='" + str(boopee.id) + "'"
|
|
||||||
cursor.execute(sql)
|
|
||||||
result = cursor.fetchone()
|
|
||||||
# Boopee's entry exists, continue
|
|
||||||
if result is not None:
|
|
||||||
amount = result.get('amount') + 1
|
|
||||||
sql = "update `" + str(booper.id) + "` set amount = " + str(amount) + " where id=" + str(
|
|
||||||
boopee.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
# Boopee does not exist, need to create the field for it
|
|
||||||
else:
|
|
||||||
sql = "insert into `" + str(booper.id) + "` (id,amount) values ('" + str(boopee.id) + "',1)"
|
|
||||||
cursor.execute(sql)
|
|
||||||
# Booper's table does not exist, need to create the table
|
|
||||||
else:
|
|
||||||
sql = "create table `" + str(booper.id) + \
|
|
||||||
"` (`id` varchar(255) not null,`amount` int(11) not null" + \
|
|
||||||
",primary key (`id`)) engine=InnoDB default charset=utf8 collate=utf8_bin"
|
|
||||||
cursor.execute(sql)
|
|
||||||
sql = "insert into `" + str(booper.id) + "` (id,amount) values ('" + str(boopee.id) + "',1)"
|
|
||||||
cursor.execute(sql)
|
|
||||||
fmt = "{0.mention} has just booped you {1.mention}! That's {2} times now!"
|
|
||||||
await bot.say(fmt.format(booper, boopee, amount))
|
|
||||||
connection.commit()
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True, no_pm=True)
|
|
||||||
async def mostboops(ctx):
|
|
||||||
try:
|
|
||||||
cursor = connection.cursor()
|
|
||||||
cursor.execute('use {0}'.format(db_boops))
|
|
||||||
sql = "select id,amount from `{0}` where amount=(select MAX(amount) from `{0}`)".format(ctx.message.author.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
result = cursor.fetchone()
|
|
||||||
member = determineId(result.get('id'))
|
|
||||||
await bot.say("{0} you have booped {1} the most amount of times, coming in at {2} times".format(
|
|
||||||
ctx.message.author.mention, member.mention, result.get('amount')))
|
|
||||||
connection.commit()
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True, no_pm=True)
|
|
||||||
async def mostwins(ctx):
|
|
||||||
try:
|
|
||||||
members = ctx.message.server.members
|
|
||||||
cursor = connection.cursor()
|
|
||||||
cursor.execute('use {0}'.format(db_default))
|
|
||||||
sql = "select * from battle_records"
|
|
||||||
cursor.execute(sql)
|
|
||||||
result = cursor.fetchall()
|
|
||||||
count = 0
|
|
||||||
fmt = []
|
|
||||||
if result is not None:
|
|
||||||
for r in result:
|
|
||||||
member = determineId(r['id'])
|
|
||||||
if member in members:
|
|
||||||
record = r['record']
|
|
||||||
|
|
||||||
winAmt = int(record.split('-')[0])
|
|
||||||
loseAmt = int(record.split('-')[1])
|
|
||||||
percentage = winAmt / (winAmt + loseAmt)
|
|
||||||
|
|
||||||
position = count
|
|
||||||
|
|
||||||
indexPercentage = 0
|
|
||||||
if count > 0:
|
|
||||||
indexRecord = re.search('\d+-\d+', fmt[position - 1]).group(0)
|
|
||||||
indexWin = int(indexRecord.split('-')[0])
|
|
||||||
indexLose = int(indexRecord.split('-')[1])
|
|
||||||
indexPercentage = indexWin / (indexWin + indexLose)
|
|
||||||
while position > 0 and indexPercentage < percentage:
|
|
||||||
position -= 1
|
|
||||||
indexRecord = re.search('\d+-\d+', fmt[position - 1]).group(0)
|
|
||||||
indexWin = int(indexRecord.split('-')[0])
|
|
||||||
indexLose = int(indexRecord.split('-')[1])
|
|
||||||
indexPercentage = indexWin / (indexWin + indexLose)
|
|
||||||
fmt.insert(position, "{0} has a battling record of {1}".format(member.name, record))
|
|
||||||
count += 1
|
|
||||||
for index in range(0, len(fmt)):
|
|
||||||
fmt[index] = "{0}) {1}".format(index + 1, fmt[index])
|
|
||||||
connection.commit()
|
|
||||||
if len(fmt) == 0:
|
|
||||||
await bot.say("```No battling records found from any members in this server```")
|
|
||||||
return
|
|
||||||
await bot.say("```{}```".format("\n".join(fmt)))
|
|
||||||
except Exception as e:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await bot.say(fmt.format(type(e).__name__, e))
|
|
||||||
|
|
||||||
|
|
||||||
def determineId(ID):
|
|
||||||
if type(ID) is int:
|
|
||||||
ID = str(ID)
|
|
||||||
member = discord.utils.find(lambda m: m.id == ID, bot.get_all_members())
|
|
||||||
if member is not None:
|
|
||||||
return member
|
|
||||||
msg = discord.utils.find(lambda m: m.id == ID, bot.messages)
|
|
||||||
if msg is not None:
|
|
||||||
return msg
|
|
||||||
server = discord.utils.find(lambda s: s.id == ID, bot.servers)
|
|
||||||
if server is not None:
|
|
||||||
return server
|
|
||||||
channel = discord.utils.find(lambda c: c.id == ID, bot.get_all_channels())
|
|
||||||
if channel is not None:
|
|
||||||
return channel
|
|
||||||
|
|
||||||
|
|
||||||
def updateBattleRecords(winner, loser):
|
|
||||||
cursor = connection.cursor()
|
|
||||||
cursor.execute('use {0}'.format(db_default))
|
|
||||||
|
|
||||||
# Update winners records
|
|
||||||
sql = "select record from battle_records where id={0}".format(winner.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
result = cursor.fetchone()
|
|
||||||
if result is not None:
|
|
||||||
result = result['record'].split('-')
|
|
||||||
result[0] = str(int(result[0]) + 1)
|
|
||||||
sql = "update battle_records set record ='{0}' where id='{1}'".format("-".join(result), winner.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
else:
|
|
||||||
sql = "insert into battle_records (id,record) values ('{0}','1-0')".format(winner.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
|
|
||||||
connection.commit()
|
|
||||||
|
|
||||||
# Update losers records
|
|
||||||
sql = "select record from battle_records where id={0}".format(loser.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
result = cursor.fetchone()
|
|
||||||
if result is not None:
|
|
||||||
result = result['record'].split('-')
|
|
||||||
result[1] = str(int(result[1]) + 1)
|
|
||||||
sql = "update battle_records set record ='{0}' where id='{1}'".format('-'.join(result), loser.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
else:
|
|
||||||
sql = "insert into battle_records (id,record) values ('{0}','0-1')".format(loser.id)
|
|
||||||
cursor.execute(sql)
|
|
||||||
|
|
||||||
connection.commit()
|
|
||||||
|
|
||||||
|
|
||||||
def checkSetup(cursor):
|
|
||||||
try:
|
|
||||||
cursor.execute('use {}'.format(db_default))
|
|
||||||
except pymysql.OperationalError:
|
|
||||||
return "Error: default_db"
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
cursor.execute('describe battle_records')
|
|
||||||
except pymysql.ProgrammingError:
|
|
||||||
# battle_records does not exist, create it
|
|
||||||
sql = "create table `battle_records` (`id` varchar(32) not null,`record` varchar(32) not null," + \
|
|
||||||
"primary key (`id`)) engine=InnoDB default charset=utf8 collate=utf8_bin"
|
|
||||||
cursor.execute(sql)
|
|
||||||
connection.commit()
|
|
||||||
try:
|
|
||||||
cursor.execute('describe restart_server')
|
|
||||||
except pymysql.ProgrammingError:
|
|
||||||
# restart_server does not exist, create it
|
|
||||||
sql = "create table `restart_server` (`id` int(11) not null auto_increment,`channel_id` varchar(32)" + \
|
|
||||||
"not null,primary key (`id`)) engine=InnoDB default charset=utf8 collate=utf8_bin;"
|
|
||||||
cursor.execute(sql)
|
|
||||||
connection.commit()
|
|
||||||
sql = "insert into restart_server (id,channel_id) values (1,'0')"
|
|
||||||
cursor.execute(sql)
|
|
||||||
connection.commit()
|
|
||||||
try:
|
|
||||||
cursor.execute('use {}'.format(db_boops))
|
|
||||||
except pymysql.OperationalError:
|
|
||||||
return "Error: boop_db"
|
|
||||||
|
|
||||||
|
|
||||||
db_default = global_config.get("db_default")
|
|
||||||
db_boops = global_config.get("db_boops")
|
|
||||||
nsfwChannels = global_config.get("nsfw_channel")
|
|
||||||
connection = pymysql.connect(host=global_config.get("db_host"), user=global_config.get("db_user"),
|
|
||||||
password=global_config.get("db_user_pass"), charset='utf8mb4',
|
|
||||||
cursorclass=pymysql.cursors.DictCursor)
|
|
||||||
|
|
||||||
battling = False
|
|
||||||
battleP1 = None
|
|
||||||
battleP2 = None
|
|
||||||
|
|
||||||
battleWins = global_config.get("battleWins", [])
|
|
||||||
defaultStatus = global_config.get("default_status", "")
|
|
||||||
botToken = global_config.get("bot_token", "")
|
|
||||||
ownerID = global_config.get("owner_id", "")
|
|
||||||
|
|
||||||
modCommands = global_config.get("modCommands", {})
|
|
||||||
adminCommands = global_config.get("adminCommands", {})
|
|
||||||
openCommands = global_config.get("openCommands", {})
|
|
||||||
ownerCommands = global_config.get("ownerCommands", {})
|
|
||||||
voiceCommands = global_config.get("voiceCommands", {})
|
|
||||||
|
|
||||||
getter = re.compile(r'`(?!`)(.*?)`')
|
|
||||||
multi = re.compile(r'```(.*?)```', re.DOTALL)
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
try:
|
|
||||||
bot.run(botToken)
|
|
||||||
except:
|
|
||||||
quit()
|
|
||||||
|
|
92
cogs/core.py
Normal file
92
cogs/core.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
from discord.ext import commands
|
||||||
|
from .utils import config
|
||||||
|
import discord
|
||||||
|
import subprocess
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
class Core:
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def joke(self):
|
||||||
|
"""Prints a random riddle"""
|
||||||
|
try:
|
||||||
|
fortuneCommand = "/usr/bin/fortune riddles"
|
||||||
|
fortune = subprocess.check_output(fortuneCommand.split()).decode("utf-8")
|
||||||
|
await self.bot.say(fortune)
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def urban(self, *msg: str):
|
||||||
|
"""Pulls the top urbandictionary.com definition for a term"""
|
||||||
|
try:
|
||||||
|
term = '+'.join(msg)
|
||||||
|
url = "http://api.urbandictionary.com/v0/define?term={}".format(term)
|
||||||
|
response = urllib.request.urlopen(url)
|
||||||
|
data = json.loads(response.read().decode('utf-8'))
|
||||||
|
if len(data['list']) == 0:
|
||||||
|
await self.bot.say("No result with that term!")
|
||||||
|
else:
|
||||||
|
await self.bot.say(data['list'][0]['definition'])
|
||||||
|
except discord.HTTPException:
|
||||||
|
await self.bot.say('```Error: Definition is too long for me to send```')
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(pass_context=True)
|
||||||
|
async def derpi(self, ctx, *search: str):
|
||||||
|
"""Provides a random image from the first page of derpibooru.org for the following term"""
|
||||||
|
try:
|
||||||
|
if len(search) > 0:
|
||||||
|
url = 'https://derpibooru.org/search.json?q='
|
||||||
|
query = '+'.join(search)
|
||||||
|
url += query
|
||||||
|
if ctx.message.channel.id in config.nsfwChannels:
|
||||||
|
url += ",+explicit&filter_id=95938"
|
||||||
|
# url should now be in the form of url?q=search+terms
|
||||||
|
# Next part processes the json format, and saves the data in useful lists/dictionaries
|
||||||
|
response = urllib.request.urlopen(url)
|
||||||
|
data = json.loads(response.read().decode('utf-8'))
|
||||||
|
results = data['search']
|
||||||
|
|
||||||
|
if len(results) > 0:
|
||||||
|
index = random.randint(0, len(results) - 1)
|
||||||
|
randImageUrl = results[index].get('representations').get('full')[2:]
|
||||||
|
randImageUrl = 'http://' + randImageUrl
|
||||||
|
imageLink = randImageUrl.strip()
|
||||||
|
else:
|
||||||
|
await self.bot.say("No results with that search term, {0}!".format(ctx.message.author.mention))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
with urllib.request.urlopen('https://derpibooru.org/images/random') as response:
|
||||||
|
imageLink = response.geturl()
|
||||||
|
url = 'https://shpro.link/redirect.php/'
|
||||||
|
data = urllib.parse.urlencode({'link': imageLink}).encode('ascii')
|
||||||
|
response = urllib.request.urlopen(url, data).read().decode('utf-8')
|
||||||
|
await self.bot.say(response)
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(pass_context=True)
|
||||||
|
async def roll(self, ctx):
|
||||||
|
"""Rolls a six sided die"""
|
||||||
|
try:
|
||||||
|
num = random.randint(1, 6)
|
||||||
|
fmt = '{0.message.author.name} has rolled a die and got the number {1}!'
|
||||||
|
await self.bot.say(fmt.format(ctx, num))
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(Core(bot))
|
184
cogs/interaction.py
Normal file
184
cogs/interaction.py
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
from discord.ext import commands
|
||||||
|
from .utils import checks
|
||||||
|
from .utils import config
|
||||||
|
from threading import Timer
|
||||||
|
import random
|
||||||
|
|
||||||
|
battling = False
|
||||||
|
battleP1 = None
|
||||||
|
battleP2 = None
|
||||||
|
|
||||||
|
|
||||||
|
def battlingOff():
|
||||||
|
global battleP1
|
||||||
|
global battleP2
|
||||||
|
global battling
|
||||||
|
battling = False
|
||||||
|
battleP1 = ""
|
||||||
|
battleP2 = ""
|
||||||
|
|
||||||
|
|
||||||
|
def updateBattleRecords(winner, loser):
|
||||||
|
cursor = config.connection.cursor()
|
||||||
|
cursor.execute('use {0}'.format(config.db_default))
|
||||||
|
|
||||||
|
# Update winners records
|
||||||
|
sql = "select record from battle_records where id={0}".format(winner.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
result = cursor.fetchone()
|
||||||
|
if result is not None:
|
||||||
|
result = result['record'].split('-')
|
||||||
|
result[0] = str(int(result[0]) + 1)
|
||||||
|
sql = "update battle_records set record ='{0}' where id='{1}'".format("-".join(result), winner.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
else:
|
||||||
|
sql = "insert into battle_records (id,record) values ('{0}','1-0')".format(winner.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
|
||||||
|
config.connection.commit()
|
||||||
|
|
||||||
|
# Update losers records
|
||||||
|
sql = "select record from battle_records where id={0}".format(loser.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
result = cursor.fetchone()
|
||||||
|
if result is not None:
|
||||||
|
result = result['record'].split('-')
|
||||||
|
result[1] = str(int(result[1]) + 1)
|
||||||
|
sql = "update battle_records set record ='{0}' where id='{1}'".format('-'.join(result), loser.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
else:
|
||||||
|
sql = "insert into battle_records (id,record) values ('{0}','0-1')".format(loser.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
|
||||||
|
config.connection.commit()
|
||||||
|
|
||||||
|
|
||||||
|
class Interaction:
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
async def battle(self, ctx):
|
||||||
|
"""Challenges the mentioned user to a battle"""
|
||||||
|
try:
|
||||||
|
global battleP1
|
||||||
|
global battleP2
|
||||||
|
global battling
|
||||||
|
if battling:
|
||||||
|
return
|
||||||
|
if len(ctx.message.mentions) == 0:
|
||||||
|
await self.bot.say("You must mention someone in the room " + ctx.message.author.mention + "!")
|
||||||
|
return
|
||||||
|
if len(ctx.message.mentions) > 1:
|
||||||
|
await self.bot.say("You cannot battle more than one person at once!")
|
||||||
|
return
|
||||||
|
player2 = ctx.message.mentions[0]
|
||||||
|
if ctx.message.author.id == player2.id:
|
||||||
|
await self.bot.say("Why would you want to battle yourself? Suicide is not the answer")
|
||||||
|
return
|
||||||
|
if self.bot.user.id == player2.id:
|
||||||
|
await self.bot.say("I always win, don't even try it.")
|
||||||
|
return
|
||||||
|
fmt = "{0.mention} has challenged you to a battle {1.mention}\n!accept or !decline"
|
||||||
|
battleP1 = ctx.message.author
|
||||||
|
battleP2 = player2
|
||||||
|
await self.bot.say(fmt.format(ctx.message.author, player2))
|
||||||
|
t = Timer(180, battlingOff)
|
||||||
|
t.start()
|
||||||
|
battling = True
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(no_pm=True)
|
||||||
|
@checks.battled(battleP2)
|
||||||
|
async def accept(self):
|
||||||
|
"""Accepts the battle challenge"""
|
||||||
|
try:
|
||||||
|
if not battling:
|
||||||
|
return
|
||||||
|
num = random.randint(1, 100)
|
||||||
|
fmt = config.battleWins[random.randint(0, len(config.battleWins) - 1)]
|
||||||
|
if num <= 50:
|
||||||
|
await self.bot.say(fmt.format(battleP1.mention, battleP2.mention))
|
||||||
|
updateBattleRecords(battleP1, battleP2)
|
||||||
|
elif num > 50:
|
||||||
|
await self.bot.say(fmt.format(battleP2.mention, battleP1.mention))
|
||||||
|
updateBattleRecords(battleP2, battleP1)
|
||||||
|
battlingOff()
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(no_pm=True)
|
||||||
|
@checks.battled(battleP2)
|
||||||
|
async def decline(self):
|
||||||
|
"""Declines the battle challenge"""
|
||||||
|
try:
|
||||||
|
if not battling:
|
||||||
|
return
|
||||||
|
await self.bot.say("{0} has chickened out! {1} wins by default!".format(battleP2.mention, battleP1.mention))
|
||||||
|
updateBattleRecords(battleP1, battleP2)
|
||||||
|
battlingOff()
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
async def boop(self, ctx):
|
||||||
|
"""Boops the mentioned person"""
|
||||||
|
try:
|
||||||
|
if len(ctx.message.mentions) == 0:
|
||||||
|
await self.bot.say("You must mention someone in the room " + ctx.message.author.mention + "!")
|
||||||
|
return
|
||||||
|
if len(ctx.message.mentions) > 1:
|
||||||
|
await self.bot.say("You cannot boop more than one person at once!")
|
||||||
|
return
|
||||||
|
boopee = ctx.message.mentions[0]
|
||||||
|
booper = ctx.message.author
|
||||||
|
if boopee.id == booper.id:
|
||||||
|
await self.bot.say("You can't boop yourself! Silly...")
|
||||||
|
return
|
||||||
|
if boopee.id == self.bot.user.id:
|
||||||
|
await self.bot.say("Why the heck are you booping me? Get away from me >:c")
|
||||||
|
return
|
||||||
|
|
||||||
|
cursor = config.connection.cursor()
|
||||||
|
cursor.execute('use {0}'.format(config.db_boops))
|
||||||
|
sql = "show tables like '" + str(booper.id) + "'"
|
||||||
|
cursor.execute(sql)
|
||||||
|
result = cursor.fetchone()
|
||||||
|
amount = 1
|
||||||
|
# Booper's table exists, continue
|
||||||
|
if result is not None:
|
||||||
|
sql = "select `amount` from `" + booper.id + "` where id='" + str(boopee.id) + "'"
|
||||||
|
cursor.execute(sql)
|
||||||
|
result = cursor.fetchone()
|
||||||
|
# Boopee's entry exists, continue
|
||||||
|
if result is not None:
|
||||||
|
amount = result.get('amount') + 1
|
||||||
|
sql = "update `" + str(booper.id) + "` set amount = " + str(amount) + " where id=" + str(
|
||||||
|
boopee.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
# Boopee does not exist, need to create the field for it
|
||||||
|
else:
|
||||||
|
sql = "insert into `" + str(booper.id) + "` (id,amount) values ('" + str(boopee.id) + "',1)"
|
||||||
|
cursor.execute(sql)
|
||||||
|
# Booper's table does not exist, need to create the table
|
||||||
|
else:
|
||||||
|
sql = "create table `" + str(booper.id) + \
|
||||||
|
"` (`id` varchar(255) not null,`amount` int(11) not null" + \
|
||||||
|
",primary key (`id`)) engine=InnoDB default charset=utf8 collate=utf8_bin"
|
||||||
|
cursor.execute(sql)
|
||||||
|
sql = "insert into `" + str(booper.id) + "` (id,amount) values ('" + str(boopee.id) + "',1)"
|
||||||
|
cursor.execute(sql)
|
||||||
|
fmt = "{0.mention} has just booped you {1.mention}! That's {2} times now!"
|
||||||
|
await self.bot.say(fmt.format(booper, boopee, amount))
|
||||||
|
config.connection.commit()
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(Interaction(bot))
|
30
cogs/mod.py
Normal file
30
cogs/mod.py
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
from discord.ext import commands
|
||||||
|
from .utils import checks
|
||||||
|
|
||||||
|
|
||||||
|
class Mod:
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
@checks.isAdmin()
|
||||||
|
async def leave(self, ctx):
|
||||||
|
"""Forces the bot to leave the server"""
|
||||||
|
try:
|
||||||
|
await self.bot.say('Why must I leave? Hopefully I can come back :c')
|
||||||
|
await self.bot.leave_server(ctx.message.server)
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(pass_context=True)
|
||||||
|
@checks.isMod()
|
||||||
|
async def say(self, ctx, *msg: str):
|
||||||
|
"""Tells the bot to repeat what you say"""
|
||||||
|
try:
|
||||||
|
msg = ' '.join(msg)
|
||||||
|
await self.bot.say(msg)
|
||||||
|
await self.bot.delete_message(ctx.message)
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
110
cogs/owner.py
Normal file
110
cogs/owner.py
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
from discord.ext import commands
|
||||||
|
from .utils import config
|
||||||
|
from .utils import checks
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import discord
|
||||||
|
|
||||||
|
getter = re.compile(r'`(?!`)(.*?)`')
|
||||||
|
multi = re.compile(r'```(.*?)```', re.DOTALL)
|
||||||
|
|
||||||
|
|
||||||
|
class Owner:
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@commands.command(pass_context=True)
|
||||||
|
@checks.isOwner()
|
||||||
|
async def restart(self, ctx):
|
||||||
|
"""Forces the bot to restart"""
|
||||||
|
try:
|
||||||
|
cursor = config.connection.cursor()
|
||||||
|
cursor.execute('use {0}'.format(config.db_default))
|
||||||
|
sql = "update restart_server set channel_id={0} where id=1".format(ctx.message.channel.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
config.connection.commit()
|
||||||
|
await self.bot.say("Restarting; see you in the next life {0}!".format(ctx.message.author.mention))
|
||||||
|
python = sys.executable
|
||||||
|
os.execl(python, python, *sys.argv)
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(pass_context=True)
|
||||||
|
@checks.isOwner()
|
||||||
|
async def py(self, ctx):
|
||||||
|
"""Executes code"""
|
||||||
|
try:
|
||||||
|
match_single = getter.findall(ctx.message.content)
|
||||||
|
match_multi = multi.findall(ctx.message.content)
|
||||||
|
if not match_single and not match_multi:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if not match_multi:
|
||||||
|
result = eval(match_single[0])
|
||||||
|
await self.bot.say("```{0}```".format(result))
|
||||||
|
else:
|
||||||
|
def r(v):
|
||||||
|
config.loop.create_task(self.bot.say("```{0}```".format(v)))
|
||||||
|
|
||||||
|
exec(match_multi[0])
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(pass_context=True)
|
||||||
|
@checks.isOwner()
|
||||||
|
async def shutdown(self, ctx):
|
||||||
|
"""Shuts the bot down"""
|
||||||
|
try:
|
||||||
|
fmt = 'Shutting down, I will miss you {0.author.name}'
|
||||||
|
await self.bot.say(fmt.format(ctx.message))
|
||||||
|
await self.bot.logout()
|
||||||
|
await self.bot.close()
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@checks.isOwner()
|
||||||
|
async def avatar(self, content):
|
||||||
|
"""Changes the avatar for the bot to the filename following the command"""
|
||||||
|
try:
|
||||||
|
file = '/home/phxntx5/public_html/bot/images/' + content
|
||||||
|
with open(file, 'rb') as fp:
|
||||||
|
await self.bot.edit_profile(avatar=fp.read())
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@checks.isOwner()
|
||||||
|
async def name(self, newNick):
|
||||||
|
"""Changes the bot's name"""
|
||||||
|
try:
|
||||||
|
await self.bot.edit_profile(username=newNick)
|
||||||
|
await self.bot.say('Changed username to ' + newNick)
|
||||||
|
# Restart the bot after this, as profile changes are not immediate
|
||||||
|
python = sys.executable
|
||||||
|
os.execl(python, python, *sys.argv)
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@checks.isOwner()
|
||||||
|
async def status(self, *stat: str):
|
||||||
|
"""Changes the bot's 'playing' status"""
|
||||||
|
try:
|
||||||
|
newStatus = ' '.join(stat)
|
||||||
|
game = discord.Game(name=newStatus, type=0)
|
||||||
|
await self.bot.change_status(game)
|
||||||
|
await self.bot.say("Just changed my status to '{0}'!".format(newStatus))
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(Owner(bot))
|
|
@ -2,10 +2,12 @@ import asyncio
|
||||||
import discord
|
import discord
|
||||||
import traceback
|
import traceback
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
from .utils import checks
|
||||||
|
|
||||||
if not discord.opus.is_loaded():
|
if not discord.opus.is_loaded():
|
||||||
discord.opus.load_opus('/usr/lib64/libopus.so.0')
|
discord.opus.load_opus('/usr/lib64/libopus.so.0')
|
||||||
|
|
||||||
|
|
||||||
class VoiceEntry:
|
class VoiceEntry:
|
||||||
def __init__(self, message, player):
|
def __init__(self, message, player):
|
||||||
self.requester = message.author
|
self.requester = message.author
|
||||||
|
@ -16,9 +18,10 @@ class VoiceEntry:
|
||||||
fmt = '*{0.title}* uploaded by {0.uploader} and requested by {1.display_name}'
|
fmt = '*{0.title}* uploaded by {0.uploader} and requested by {1.display_name}'
|
||||||
duration = self.player.duration
|
duration = self.player.duration
|
||||||
if duration:
|
if duration:
|
||||||
fmt += ' [length: {0[0]}m {0[1]}s]'.format(divmod(round(duration,0), 60))
|
fmt += ' [length: {0[0]}m {0[1]}s]'.format(divmod(round(duration, 0), 60))
|
||||||
return fmt.format(self.player, self.requester)
|
return fmt.format(self.player, self.requester)
|
||||||
|
|
||||||
|
|
||||||
class VoiceState:
|
class VoiceState:
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.current = None
|
self.current = None
|
||||||
|
@ -26,7 +29,7 @@ class VoiceState:
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.play_next_song = asyncio.Event()
|
self.play_next_song = asyncio.Event()
|
||||||
self.songs = asyncio.Queue()
|
self.songs = asyncio.Queue()
|
||||||
self.skip_votes = set() # a set of user_ids that voted
|
self.skip_votes = set() # a set of user_ids that voted
|
||||||
self.audio_player = self.bot.loop.create_task(self.audio_player_task())
|
self.audio_player = self.bot.loop.create_task(self.audio_player_task())
|
||||||
|
|
||||||
def is_playing(self):
|
def is_playing(self):
|
||||||
|
@ -56,6 +59,7 @@ class VoiceState:
|
||||||
self.current.player.start()
|
self.current.player.start()
|
||||||
await self.play_next_song.wait()
|
await self.play_next_song.wait()
|
||||||
|
|
||||||
|
|
||||||
class Music:
|
class Music:
|
||||||
"""Voice related commands.
|
"""Voice related commands.
|
||||||
Works in multiple servers at once.
|
Works in multiple servers at once.
|
||||||
|
@ -85,13 +89,9 @@ class Music:
|
||||||
self.bot.loop.create_task(state.voice.disconnect())
|
self.bot.loop.create_task(state.voice.disconnect())
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
def isMod():
|
|
||||||
def predicate(ctx):
|
|
||||||
return ctx.message.author.top_role.permissions.kick_members
|
|
||||||
return commands.check(predicate)
|
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(no_pm=True)
|
||||||
async def join(self, ctx, *, channel : discord.Channel):
|
async def join(self, *, channel: discord.Channel):
|
||||||
"""Joins a voice channel."""
|
"""Joins a voice channel."""
|
||||||
try:
|
try:
|
||||||
await self.create_voice_client(channel)
|
await self.create_voice_client(channel)
|
||||||
|
@ -121,7 +121,7 @@ class Music:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
async def play(self, ctx, *, song : str):
|
async def play(self, ctx, *, song: str):
|
||||||
"""Plays a song.
|
"""Plays a song.
|
||||||
If there is a song currently in the queue, then it is
|
If there is a song currently in the queue, then it is
|
||||||
queued until the next song is done playing.
|
queued until the next song is done playing.
|
||||||
|
@ -147,8 +147,8 @@ class Music:
|
||||||
await state.songs.put(entry)
|
await state.songs.put(entry)
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@isMod()
|
@checks.isMod()
|
||||||
async def volume(self, ctx, value : int):
|
async def volume(self, ctx, value: int):
|
||||||
"""Sets the volume of the currently playing song."""
|
"""Sets the volume of the currently playing song."""
|
||||||
|
|
||||||
state = self.get_voice_state(ctx.message.server)
|
state = self.get_voice_state(ctx.message.server)
|
||||||
|
@ -158,7 +158,7 @@ class Music:
|
||||||
await self.bot.say('Set the volume to {:.0%}'.format(player.volume))
|
await self.bot.say('Set the volume to {:.0%}'.format(player.volume))
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@isMod()
|
@checks.isMod()
|
||||||
async def pause(self, ctx):
|
async def pause(self, ctx):
|
||||||
"""Pauses the currently played song."""
|
"""Pauses the currently played song."""
|
||||||
state = self.get_voice_state(ctx.message.server)
|
state = self.get_voice_state(ctx.message.server)
|
||||||
|
@ -167,7 +167,7 @@ class Music:
|
||||||
player.pause()
|
player.pause()
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@isMod()
|
@checks.isMod()
|
||||||
async def resume(self, ctx):
|
async def resume(self, ctx):
|
||||||
"""Resumes the currently played song."""
|
"""Resumes the currently played song."""
|
||||||
state = self.get_voice_state(ctx.message.server)
|
state = self.get_voice_state(ctx.message.server)
|
||||||
|
@ -176,7 +176,7 @@ class Music:
|
||||||
player.resume()
|
player.resume()
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@isMod()
|
@checks.isMod()
|
||||||
async def stop(self, ctx):
|
async def stop(self, ctx):
|
||||||
"""Stops playing audio and leaves the voice channel.
|
"""Stops playing audio and leaves the voice channel.
|
||||||
This also clears the queue.
|
This also clears the queue.
|
||||||
|
@ -194,11 +194,13 @@ class Music:
|
||||||
await state.voice.disconnect()
|
await state.voice.disconnect()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@commands.command(pass_context=True,no_pm=True)
|
|
||||||
async def queuelength(self,ctx):
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
async def queuelength(self, ctx):
|
||||||
"""Prints the length of the queue"""
|
"""Prints the length of the queue"""
|
||||||
try:
|
try:
|
||||||
await self.bot.say("There are a total of {} songs in the queue".format(str(self.get_voice_state(ctx.message.server).songs.qsize())))
|
await self.bot.say("There are a total of {} songs in the queue"
|
||||||
|
.format(str(self.get_voice_state(ctx.message.server).songs.qsize())))
|
||||||
except:
|
except:
|
||||||
await self.bot.say(traceback.format_exc())
|
await self.bot.say(traceback.format_exc())
|
||||||
|
|
||||||
|
@ -229,7 +231,7 @@ class Music:
|
||||||
await self.bot.say('You have already voted to skip this song.')
|
await self.bot.say('You have already voted to skip this song.')
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@isMod()
|
@checks.isMod()
|
||||||
async def modskip(self, ctx):
|
async def modskip(self, ctx):
|
||||||
"""Forces a song skip, can only be used by a moderator"""
|
"""Forces a song skip, can only be used by a moderator"""
|
||||||
state = self.get_voice_state(ctx.message.server)
|
state = self.get_voice_state(ctx.message.server)
|
||||||
|
@ -250,3 +252,7 @@ class Music:
|
||||||
else:
|
else:
|
||||||
skip_count = len(state.skip_votes)
|
skip_count = len(state.skip_votes)
|
||||||
await self.bot.say('Now playing {} [skips: {}/3]'.format(state.current, skip_count))
|
await self.bot.say('Now playing {} [skips: {}/3]'.format(state.current, skip_count))
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(Music(bot))
|
80
cogs/stats.py
Normal file
80
cogs/stats.py
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
from discord.ext import commands
|
||||||
|
from discord.utils import find
|
||||||
|
from .utils import config
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class Stats:
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
async def mostboops(self, ctx):
|
||||||
|
"""Shows the person you have 'booped' the most, as well as how many times"""
|
||||||
|
try:
|
||||||
|
cursor = config.connection.cursor()
|
||||||
|
cursor.execute('use {0}'.format(config.db_boops))
|
||||||
|
sql = "select id,amount from `{0}` where amount=(select MAX(amount) from `{0}`)"\
|
||||||
|
.format(ctx.message.author.id)
|
||||||
|
cursor.execute(sql)
|
||||||
|
result = cursor.fetchone()
|
||||||
|
member = find(lambda m: m.id == result.get('id'), self.bot.get_all_members())
|
||||||
|
await self.bot.say("{0} you have booped {1} the most amount of times, coming in at {2} times".format(
|
||||||
|
ctx.message.author.mention, member.mention, result.get('amount')))
|
||||||
|
config.connection.commit()
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
async def mostwins(self, ctx):
|
||||||
|
"""Prints a 'leaderboard' of everyone in the server's battling record"""
|
||||||
|
try:
|
||||||
|
members = ctx.message.server.members
|
||||||
|
cursor = config.connection.cursor()
|
||||||
|
cursor.execute('use {0}'.format(config.db_default))
|
||||||
|
sql = "select * from battle_records"
|
||||||
|
cursor.execute(sql)
|
||||||
|
result = cursor.fetchall()
|
||||||
|
count = 0
|
||||||
|
fmt = []
|
||||||
|
if result is not None:
|
||||||
|
for r in result:
|
||||||
|
member = self.bot.determineId(r['id'])
|
||||||
|
if member in members:
|
||||||
|
record = r['record']
|
||||||
|
|
||||||
|
winAmt = int(record.split('-')[0])
|
||||||
|
loseAmt = int(record.split('-')[1])
|
||||||
|
percentage = winAmt / (winAmt + loseAmt)
|
||||||
|
|
||||||
|
position = count
|
||||||
|
|
||||||
|
indexPercentage = 0
|
||||||
|
if count > 0:
|
||||||
|
indexRecord = re.search('\d+-\d+', fmt[position - 1]).group(0)
|
||||||
|
indexWin = int(indexRecord.split('-')[0])
|
||||||
|
indexLose = int(indexRecord.split('-')[1])
|
||||||
|
indexPercentage = indexWin / (indexWin + indexLose)
|
||||||
|
while position > 0 and indexPercentage < percentage:
|
||||||
|
position -= 1
|
||||||
|
indexRecord = re.search('\d+-\d+', fmt[position - 1]).group(0)
|
||||||
|
indexWin = int(indexRecord.split('-')[0])
|
||||||
|
indexLose = int(indexRecord.split('-')[1])
|
||||||
|
indexPercentage = indexWin / (indexWin + indexLose)
|
||||||
|
fmt.insert(position, "{0} has a battling record of {1}".format(member.name, record))
|
||||||
|
count += 1
|
||||||
|
for index in range(0, len(fmt)):
|
||||||
|
fmt[index] = "{0}) {1}".format(index + 1, fmt[index])
|
||||||
|
config.connection.commit()
|
||||||
|
if len(fmt) == 0:
|
||||||
|
await self.bot.say("```No battling records found from any members in this server```")
|
||||||
|
return
|
||||||
|
await self.bot.say("```{}```".format("\n".join(fmt)))
|
||||||
|
except Exception as e:
|
||||||
|
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
||||||
|
await self.bot.say(fmt.format(type(e).__name__, e))
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(Stats(bot))
|
37
cogs/utils/checks.py
Normal file
37
cogs/utils/checks.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
from discord.ext import commands
|
||||||
|
from . import config
|
||||||
|
|
||||||
|
|
||||||
|
def isOwner():
|
||||||
|
def predicate(ctx):
|
||||||
|
return ctx.message.author.id == config.ownerID
|
||||||
|
|
||||||
|
return commands.check(predicate)
|
||||||
|
|
||||||
|
|
||||||
|
def isMod():
|
||||||
|
def predicate(ctx):
|
||||||
|
return ctx.message.author.top_role.permissions.kick_members
|
||||||
|
|
||||||
|
return commands.check(predicate)
|
||||||
|
|
||||||
|
|
||||||
|
def isAdmin():
|
||||||
|
def predicate(ctx):
|
||||||
|
return ctx.message.author.top_role.permissions.manage_server
|
||||||
|
|
||||||
|
return commands.check(predicate)
|
||||||
|
|
||||||
|
|
||||||
|
def isPM():
|
||||||
|
def predicate(ctx):
|
||||||
|
return ctx.message.channel.is_private
|
||||||
|
|
||||||
|
return commands.check(predicate)
|
||||||
|
|
||||||
|
|
||||||
|
def battled(battleP2=""):
|
||||||
|
def predicate(ctx):
|
||||||
|
return ctx.message.author == battleP2
|
||||||
|
|
||||||
|
return commands.check(predicate)
|
29
cogs/utils/config.py
Normal file
29
cogs/utils/config.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import yaml
|
||||||
|
import pymysql.cursors
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
with open("/home/phxntx5/public_html/Bonfire/config.yml", "r") as f:
|
||||||
|
global_config = yaml.load(f)
|
||||||
|
|
||||||
|
db_default = global_config.get("db_default")
|
||||||
|
db_boops = global_config.get("db_boops")
|
||||||
|
nsfwChannels = global_config.get("nsfw_channel")
|
||||||
|
connection = pymysql.connect(host=global_config.get("db_host"), user=global_config.get("db_user"),
|
||||||
|
password=global_config.get("db_user_pass"), charset='utf8mb4',
|
||||||
|
cursorclass=pymysql.cursors.DictCursor)
|
||||||
|
|
||||||
|
botDescription = global_config.get("description")
|
||||||
|
commandPrefix = global_config.get("command_prefix")
|
||||||
|
|
||||||
|
battleWins = global_config.get("battleWins", [])
|
||||||
|
defaultStatus = global_config.get("default_status", "")
|
||||||
|
botToken = global_config.get("bot_token", "")
|
||||||
|
ownerID = global_config.get("owner_id", "")
|
||||||
|
|
||||||
|
modCommands = global_config.get("modCommands", {})
|
||||||
|
adminCommands = global_config.get("adminCommands", {})
|
||||||
|
openCommands = global_config.get("openCommands", {})
|
||||||
|
ownerCommands = global_config.get("ownerCommands", {})
|
||||||
|
voiceCommands = global_config.get("voiceCommands", {})
|
Loading…
Reference in a new issue