Updated some files

This commit is contained in:
davfsa 2018-06-21 20:04:07 +02:00
parent 8f70fcc142
commit fe143678fe
6 changed files with 130 additions and 820 deletions

View File

@ -1,10 +1,9 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import asyncio
from discord.ext import commands from discord.ext import commands
import discord import discord
import asyncio
class BasicCommands: class BasicCommands:
def __init__(self, bot): def __init__(self, bot):
@ -12,83 +11,58 @@ class BasicCommands:
@commands.command() @commands.command()
async def tutorial(self, ctx): async def tutorial(self, ctx):
await ctx.send( await ctx.send(f"Hello, {ctx.author.display_name}. Welcome to Sebi's Bot Tutorials. \nFirst off, would you like a quick walkthrough on the server channels?")
f"Hello, {ctx.author.display_name}. Welcome to Sebi's Bot Tutorials. \nFirst off, would you like a quick walkthrough on the server channels?"
) channel_list = {'channel-1' : self.bot.get_channel(333149949883842561).mention,
'd.py-rewrite-start' : self.bot.get_channel(386419285439938560).mention,
'js-klasa-start' : self.bot.get_channel(341816240186064897).mention,
'async2rewrite-start' : self.bot.get_channel(392223495389577217).mention,
'd.js' : self.bot.get_channel(436771798303113217).mention}
channel_list = { bots_channels = (self.bot.get_channel(339112602867204097).mention,
"channel-1": self.bot.get_channel(333149949883842561).mention, self.bot.get_channel(411586546551095296).mention)
"d.py-rewrite-start": self.bot.get_channel(386419285439938560).mention,
"js-klasa-start": self.bot.get_channel(341816240186064897).mention,
"d.js": self.bot.get_channel(436771798303113217).mention,
}
bots_channels = ( help_channels = (self.bot.get_channel(425315253153300488).mention,
self.bot.get_channel(339112602867204097).mention, self.bot.get_channel(392215236612194305).mention,
self.bot.get_channel(411586546551095296).mention, self.bot.get_channel(351034776985141250).mention)
)
help_channels = (
self.bot.get_channel(425315253153300488).mention,
self.bot.get_channel(392215236612194305).mention,
self.bot.get_channel(351034776985141250).mention,
)
def check(m): def check(m):
return ( return True if m.author.id == ctx.author.id and m.channel.id == ctx.channel.id else False
True
if m.author.id == ctx.author.id and m.channel.id == ctx.channel.id msg = await self.bot.wait_for('message', check = check, timeout = 15)
else False
)
msg = await self.bot.wait_for("message", check=check, timeout=15) agree = ("yes", "yep", "non't", "ya", "ye", "yup", "ok", "why not")
agree = ("yes", "yep", "yesn't", "ya", "ye")
if msg is None: if msg is None:
await ctx.send( await ctx.send("Sorry, {ctx.author.mention}, you didn't reply on time. You can run the command again when you're free :)")
"Sorry, {ctx.author.mention}, you didn't reply on time. You can run the command again when you're free :)"
)
else: else:
if msg.content.lower() in agree: if msg.content.lower() in agree:
async with ctx.typing(): async with ctx.typing():
await ctx.send("Alrighty-Roo... Check your DMs!") await ctx.send("Alrighty-Roo... Check your DMs!")
await ctx.author.send("Alrighty-Roo...") await ctx.author.send("Alrighty-Roo...")
await ctx.author.send( await ctx.author.send(f"To start making your bot from scratch, you first need to head over to {channel_list['channel-1']}"
f"To start making your bot from scratch, you first need to head over to {channel_list['channel-1']}" " (Regardless of the language you're gonna use).")
" (Regardless of the language you're gonna use)."
)
await asyncio.sleep(0.5) await asyncio.sleep(0.5)
await ctx.author.send( await ctx.author.send(f"After you have a bot account, you can either continue with {channel_list['d.py-rewrite-start']} "
f"After you have a bot account, you can either continue with {channel_list['d.py-rewrite-start']}" f"if you want to make a bot in discord.py rewrite __or__ go to {channel_list['js-klasa-start']} or "
f"if you want to make a bot in discord.py rewrite __or__ go to {channel_list['js-klasa-start']} or " f"{channel_list['d.js']} for making a bot in JavaScript."
f"{channel_list['d.js']} for making a bot in JavaScript." f"If you already have old Discord.py async code and you want to use it with the new Rewrite versions, head to {channel_list['async2rewrite-start']}")
)
await ctx.author.send("...Read all the tutorials and still need help? You have two ways to get help.")
await ctx.author.send(
"...Read all the tutorials and still need help? You have two ways to get help."
)
await asyncio.sleep(1.5) await asyncio.sleep(1.5)
await ctx.author.send( await ctx.author.send("**Method-1**\nThis is the best method of getting help. You help yourself.\n"
"**Method-1**\nThis is the best method of getting help. You help yourself.\n" f"To do so, head over to a bots dedicated channel (either {bots_channels[0]} or {bots_channels[1]})"
f"To do so, head over to a bots dedicated channel (either {bots_channels[0]} or {bots_channels[1]})" " and type `?rtfm rewrite thing_you_want_help_with`.\nThis will trigger the bot R.Danny Bot and will "
" and type `?rtfm rewrite thing_you_want_help_with`.\nThis will trigger the bot R.Danny Bot and will" "give you links on your query on the official discord.py rewrite docs. *PS: Let the page completely load*")
"give you links on your query on the official discord.py rewrite docs. *PS: Let the page completely load*"
)
await asyncio.sleep(5) await asyncio.sleep(5)
await ctx.author.send( await ctx.author.send("**Method-2**\nIf you haven't found anything useful with Method-1, feel free to ask your question "
"**Method-2**\nIf you haven't found anything useful with Method-1, feel free to ask your question " f"in any of the related help channels. ({', '.join(help_channels)})\nMay the force be with you!!")
f"in any of the related help channels. ({', '.join(help_channels)})\nMay the force be with you!!"
)
else: else:
return await ctx.send( return await ctx.send("Session terminated. You can run this command again whenever you want.")
"Session terminated. You can run this command again whenever you want."
)
def setup(bot): def setup(bot):
bot.add_cog(BasicCommands(bot)) bot.add_cog(BasicCommands(bot))

View File

@ -1,7 +1,6 @@
import discord import discord
from discord.ext import commands from discord.ext import commands
class BotManager: class BotManager:
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
@ -12,88 +11,76 @@ class BotManager:
return return
else: else:
# The member is a bot # The member is a bot
await member.add_roles(discord.utils.get(member.guild.roles, name="Bots")) bot_owner = member.guild.get_member((await self.bot.db_con.fetchval('select owner from bots where id = $1', member.id))
await bot_owner.add_roles(discord.utils.get(member.guild.roles, name='Bot Developers'))
await member.add_roles(discord.utils.get(member.guild.roles, name='Bots'))
try: try:
await member.edit( await member.edit(nick='[' + await self.bot.db_con.fetchval('select prefix from bots where id = $1', member.id)
nick="[" + '] ' + member.name)
+ await self.bot.db_con.fetch(
"select prefix from bots where id = $1", member.id
)
+ "] "
+ member.name
)
except: except:
pass pass
async def on_member_remove(self, member): async def on_member_remove(self, member):
# If the member is not a bot # If the member is not a bot
if member.bot is False: if member.bot is False:
return return
else: else:
# The member is a bot # The member is a bot
await self.bot.db_con.execute("DELETE FROM bots WHERE id = $1", member.id) await self.bot.db_con.execute('DELETE FROM bots WHERE id = $1', member.id)
async def on_member_ban(self, guild, user):
if member.bot is True:
return
else:
# I need to finish this
pass
@commands.command() @commands.command()
async def invite(self, ctx, bot=None, prefix=None): async def invite(self, ctx, bot=None, prefix=None):
bot = await ctx.bot.get_user_info(bot) bot = await ctx.bot.get_user_info(bot)
if not bot: if not bot:
raise Warning( raise Warning('You must include the id of the bot you are trying to invite... Be exact.')
"You must include the id of the bot you are trying to invite... Be exact."
)
if not bot.bot: if not bot.bot:
raise Warning("You can only invite bots.") raise Warning('You can only invite bots.')
if not prefix: if not prefix:
raise Warning("Please provide a prefix") raise Warning('Please provide a prefix')
# Make sure that the bot has not been invited already and it is not being tested # Make sure that the bot has not been invited already and it is not being tested
if ( if await self.bot.db_con.fetch('select count(*) from bots where id = $1', bot.id) == 1:
await self.bot.db_con.fetch( raise Warning('The bot has already been invited or is being tested')
"select count(*) from bots where id = $1", bot.id
)
== 1
):
raise Warning("The bot has already been invited or is being tested")
await self.bot.db_con.execute( await self.bot.db_con.execute('insert into bots (id, owner, prefix) values ($1, $2, $3)',
"insert into bots (id, owner, prefix) values ($1, $2, $3)", bot.id, ctx.author.id, prefix)
bot.id,
ctx.author.id,
prefix,
)
em = discord.Embed(colour=self.bot.embed_color) em = discord.Embed(colour=self.bot.embed_color)
em.title = "Hello {},".format(ctx.author.name) em.title = "Hello {},".format(ctx.author.name)
em.description = "Thanks for inviting your bot! It will be tested and invited shortly. " "Please open your DMs if they are not already so the bot can contact " "you to inform you about the progress of the bot!" em.description = "Thanks for inviting your bot! It will be tested and invited shortly. " \
"Please open your DMs if they are not already so the bot can contact " \
"you to inform you about the progress of the bot!"
await ctx.send(embed=em) await ctx.send(embed=em)
em = discord.Embed(title="Bot invite", colour=discord.Color(0x363941)) em = discord.Embed(title="Bot invite", colour=discord.Color(0x363941))
em.description = discord.utils.oauth_url(client_id, permissions=None, guild=ctx.guild))
em.set_thumbnail(url=bot.avatar_url) em.set_thumbnail(url=bot.avatar_url)
em.add_field(name="Bot name", value=bot.name) em.add_field(name="Bot name", value=bot.name)
em.add_field(name="Bot id", value="`" + str(bot.id) + "`") em.add_field(name="Bot id", value="`" + str(bot.id) + "`")
em.add_field(name="Bot owner", value=ctx.author.mention) em.add_field(name="Bot owner", value=ctx.author.mention)
em.add_field(name="Bot prefix", value="`" + prefix + "`") em.add_field(name="Bot prefix", value="`" + prefix + "`")
await ctx.bot.get_channel(448803675574370304).send(embed=em) await ctx.bot.get_channel(459280759945953300).send(embed=em)
@commands.command(name="claim", aliases=["makemine", "gimme"]) @commands.command(name='claim', aliases=['makemine', 'gimme'])
@commands.cooldown(1, 5, commands.BucketType.user) @commands.cooldown(1, 5, commands.BucketType.user)
async def _claim_bot( async def _claim_bot(self, ctx, bot: discord.Member = None, prefix: str = None, owner: discord.Member = None):
self,
ctx,
bot: discord.Member = None,
prefix: str = None,
owner: discord.Member = None,
):
if not bot: if not bot:
raise Warning( raise Warning('You must include the name of the bot you are trying to claim... Be exact.')
"You must include the name of the bot you are trying to claim... Be exact."
)
if not bot.bot: if not bot.bot:
raise Warning("You can only claim bots.") raise Warning('You can only claim bots.')
if not prefix: if not prefix:
if bot.display_name.startswith("["): if bot.display_name.startswith('['):
prefix = bot.display_name.split("]")[0].strip("[") prefix = bot.display_name.split(']')[0].strip('[')
else: else:
raise Warning("Prefix not provided and can't be found in bot nick.") raise Warning('Prefix not provided and can\'t be found in bot nick.')
if owner is not None and ctx.author.guild_permissions.manage_roles: if owner is not None and ctx.author.guild_permissions.manage_roles:
author_id = owner.id author_id = owner.id
@ -102,126 +89,100 @@ class BotManager:
em = discord.Embed() em = discord.Embed()
if ( if await self.bot.db_con.fetchval('select count(*) from bots where owner = $1', author_id) >= 10:
await self.bot.db_con.fetchval(
"select count(*) from bots where owner = $1", author_id
)
>= 10
):
em.colour = self.bot.error_color em.colour = self.bot.error_color
em.title = "Too Many Bots Claimed" em.title = 'Too Many Bots Claimed'
em.description = "Each person is limited to claiming 10 bots as that is how " "many bots are allowed by the Discord API per user." em.description = 'Each person is limited to claiming 10 bots as that is how ' \
'many bots are allowed by the Discord API per user.'
return await ctx.send(embed=em) return await ctx.send(embed=em)
existing = await self.bot.db_con.fetchrow( existing = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
"select * from bots where id = $1", bot.id
)
if not existing: if not existing:
await self.bot.db_con.execute( await self.bot.db_con.execute('insert into bots (id, owner, prefix) values ($1, $2, $3)',
"insert into bots (id, owner, prefix) values ($1, $2, $3)", bot.id, author_id, prefix)
bot.id,
author_id,
prefix,
)
em.colour = self.bot.embed_color em.colour = self.bot.embed_color
em.title = "Bot Claimed" em.title = 'Bot Claimed'
em.description = f"You have claimed {bot.display_name} with a prefix of {prefix}\n" f"If there is an error please run command again to correct the prefix,\n" f"or {ctx.prefix}unclaim {bot.mention} to unclaim the bot." em.description = f'You have claimed {bot.display_name} with a prefix of {prefix}\n' \
elif existing["owner"] and existing["owner"] != author_id: f'If there is an error please run command again to correct the prefix,\n' \
f'or {ctx.prefix}unclaim {bot.mention} to unclaim the bot.'
elif existing['owner'] and existing['owner'] != author_id:
em.colour = self.bot.error_color em.colour = self.bot.error_color
em.title = "Bot Already Claimed" em.title = 'Bot Already Claimed'
em.description = "This bot has already been claimed by someone else.\n" "If this is actually your bot please let the guild Administrators know." em.description = 'This bot has already been claimed by someone else.\n' \
elif existing["owner"] and existing["owner"] == author_id: 'If this is actually your bot please let the guild Administrators know.'
elif existing['owner'] and existing['owner'] == author_id:
em.colour = self.bot.embed_color em.colour = self.bot.embed_color
em.title = "Bot Already Claimed" em.title = 'Bot Already Claimed'
em.description = "You have already claimed this bot.\n" "If the prefix you provided is different from what is already in the database" " it will be updated for you." em.description = 'You have already claimed this bot.\n' \
if existing["prefix"] != prefix: 'If the prefix you provided is different from what is already in the database' \
await self.bot.db_con.execute( ' it will be updated for you.'
"update bots set prefix = $1 where id = $2", prefix, bot.id if existing['prefix'] != prefix:
) await self.bot.db_con.execute("update bots set prefix = $1 where id = $2", prefix, bot.id)
elif not existing["owner"]: elif not existing['owner']:
await self.bot.db_con.execute( await self.bot.db_con.execute('update bots set owner = $1, prefix = $2 where id = $3',
"update bots set owner = $1, prefix = $2 where id = $3", author_id, prefix, bot.id)
author_id,
prefix,
bot.id,
)
em.colour = self.bot.embed_color em.colour = self.bot.embed_color
em.title = "Bot Claimed" em.title = 'Bot Claimed'
em.description = f"You have claimed {bot.display_name} with a prefix of {prefix}\n" f"If there is an error please run command again to correct the prefix,\n" f"or {ctx.prefix}unclaim {bot.mention} to unclaim the bot." em.description = f'You have claimed {bot.display_name} with a prefix of {prefix}\n' \
f'If there is an error please run command again to correct the prefix,\n' \
f'or {ctx.prefix}unclaim {bot.mention} to unclaim the bot.'
else: else:
em.colour = self.bot.error_color em.colour = self.bot.error_color
em.title = "Something Went Wrong..." em.title = 'Something Went Wrong...'
await ctx.send(embed=em) await ctx.send(embed=em)
@commands.command(name="unclaim") @commands.command(name='unclaim')
@commands.cooldown(1, 5, commands.BucketType.user) @commands.cooldown(1, 5, commands.BucketType.user)
async def _unclaim_bot(self, ctx, bot: discord.Member = None): async def _unclaim_bot(self, ctx, bot: discord.Member = None):
if not bot: if not bot:
raise Warning( raise Warning('You must include the name of the bot you are trying to claim... Be exact.')
"You must include the name of the bot you are trying to claim... Be exact."
)
if not bot.bot: if not bot.bot:
raise Warning("You can only unclaim bots.") raise Warning('You can only unclaim bots.')
em = discord.Embed() em = discord.Embed()
existing = await self.bot.db_con.fetchrow( existing = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
"select * from bots where id = $1", bot.id if not existing or not existing['owner']:
)
if not existing or not existing["owner"]:
em.colour = self.bot.error_color em.colour = self.bot.error_color
em.title = "Bot Not Found" em.title = 'Bot Not Found'
em.description = "That bot is not claimed" em.description = 'That bot is not claimed'
elif ( elif existing['owner'] != ctx.author.id and not ctx.author.guild_permissions.manage_roles:
existing["owner"] != ctx.author.id
and not ctx.author.guild_permissions.manage_roles
):
em.colour = self.bot.error_color em.colour = self.bot.error_color
em.title = "Not Claimed By You" em.title = 'Not Claimed By You'
em.description = "That bot is claimed by someone else.\n" "You can't unclaim someone else's bot" em.description = 'That bot is claimed by someone else.\n' \
'You can\'t unclaim someone else\'s bot'
else: else:
await self.bot.db_con.execute( await self.bot.db_con.execute('update bots set owner = null where id = $1', bot.id)
"update bots set owner = null where id = $1", bot.id
)
em.colour = self.bot.embed_color em.colour = self.bot.embed_color
em.title = "Bot Unclaimed" em.title = 'Bot Unclaimed'
em.description = f"You have unclaimed {bot.display_name}\n" f"If this is an error please reclaim using\n" f'{ctx.prefix}claim {bot.mention} {existing["prefix"]}' em.description = f'You have unclaimed {bot.display_name}\n' \
f'If this is an error please reclaim using\n' \
f'{ctx.prefix}claim {bot.mention} {existing["prefix"]}'
await ctx.send(embed=em) await ctx.send(embed=em)
@commands.command(name="listclaims", aliases=["claimed", "mybots"]) @commands.command(name='listclaims', aliases=['claimed', 'mybots'])
@commands.cooldown(1, 5, commands.BucketType.user) @commands.cooldown(1, 5, commands.BucketType.user)
async def _claimed_bots(self, ctx, usr: discord.Member = None): async def _claimed_bots(self, ctx, usr: discord.Member = None):
if usr is None: if usr is None:
usr = ctx.author usr = ctx.author
bots = await self.bot.db_con.fetch( bots = await self.bot.db_con.fetch('select * from bots where owner = $1', usr.id)
"select * from bots where owner = $1", usr.id
)
if bots: if bots:
em = discord.Embed( em = discord.Embed(title=f'{usr.display_name} has claimed the following bots:',
title=f"{usr.display_name} has claimed the following bots:", colour=self.bot.embed_color)
colour=self.bot.embed_color,
)
for bot in bots: for bot in bots:
member = ctx.guild.get_member(int(bot["id"])) member = ctx.guild.get_member(int(bot['id']))
em.add_field( em.add_field(name=member.display_name, value=f'Stored Prefix: {bot["prefix"]}', inline=False)
name=member.display_name,
value=f'Stored Prefix: {bot["prefix"]}',
inline=False,
)
else: else:
em = discord.Embed( em = discord.Embed(title='You have not claimed any bots.',
title="You have not claimed any bots.", colour=self.bot.embed_color colour=self.bot.embed_color)
)
await ctx.send(embed=em) await ctx.send(embed=em)
@commands.command(name="whowns") @commands.command(name='whowns')
async def _whowns(self, ctx, bot: discord.Member): async def _whowns(self, ctx, bot: discord.Member):
if not bot.bot: if not bot.bot:
await ctx.send("this commands only for bots") await ctx.send('this commands only for bots')
else: else:
owner = await self.bot.db_con.fetchrow( owner = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
"select * from bots where id = $1", bot.id await ctx.send(ctx.guild.get_member(owner['owner']).display_name)
)
await ctx.send(ctx.guild.get_member(owner["owner"]).display_name)
def setup(bot): def setup(bot):

View File

@ -1,68 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from discord.ext import commands
import discord
import asyncio
class BasicCommands:
def __init__(self, bot):
self.bot = bot
@commands.command()
async def tutorial(self, ctx):
await ctx.send(f"Hello, {ctx.author.display_name}. Welcome to Sebi's Bot Tutorials. \nFirst off, would you like a quick walkthrough on the server channels?")
channel_list = {'channel-1' : self.bot.get_channel(333149949883842561).mention,
'd.py-rewrite-start' : self.bot.get_channel(386419285439938560).mention,
'js-klasa-start' : self.bot.get_channel(341816240186064897).mention,
'async2rewrite-start' : self.bot.get_channel(392223495389577217).mention,
'd.js' : self.bot.get_channel(436771798303113217).mention}
bots_channels = (self.bot.get_channel(339112602867204097).mention,
self.bot.get_channel(411586546551095296).mention)
help_channels = (self.bot.get_channel(425315253153300488).mention,
self.bot.get_channel(392215236612194305).mention,
self.bot.get_channel(351034776985141250).mention)
def check(m):
return True if m.author.id == ctx.author.id and m.channel.id == ctx.channel.id else False
msg = await self.bot.wait_for('message', check = check, timeout = 15)
agree = ("yes", "yep", "non't", "ya", "ye", "yup", "ok", "why not")
if msg is None:
await ctx.send("Sorry, {ctx.author.mention}, you didn't reply on time. You can run the command again when you're free :)")
else:
if msg.content.lower() in agree:
async with ctx.typing():
await ctx.send("Alrighty-Roo... Check your DMs!")
await ctx.author.send("Alrighty-Roo...")
await ctx.author.send(f"To start making your bot from scratch, you first need to head over to {channel_list['channel-1']}"
" (Regardless of the language you're gonna use).")
await asyncio.sleep(0.5)
await ctx.author.send(f"After you have a bot account, you can either continue with {channel_list['d.py-rewrite-start']} "
f"if you want to make a bot in discord.py rewrite __or__ go to {channel_list['js-klasa-start']} or "
f"{channel_list['d.js']} for making a bot in JavaScript."
f"If you already have old Discord.py async code and you want to use it with the new Rewrite versions, head to {channel_list['async2rewrite-start']}")
await ctx.author.send("...Read all the tutorials and still need help? You have two ways to get help.")
await asyncio.sleep(1.5)
await ctx.author.send("**Method-1**\nThis is the best method of getting help. You help yourself.\n"
f"To do so, head over to a bots dedicated channel (either {bots_channels[0]} or {bots_channels[1]})"
" and type `?rtfm rewrite thing_you_want_help_with`.\nThis will trigger the bot R.Danny Bot and will "
"give you links on your query on the official discord.py rewrite docs. *PS: Let the page completely load*")
await asyncio.sleep(5)
await ctx.author.send("**Method-2**\nIf you haven't found anything useful with Method-1, feel free to ask your question "
f"in any of the related help channels. ({', '.join(help_channels)})\nMay the force be with you!!")
else:
return await ctx.send("Session terminated. You can run this command again whenever you want.")
def setup(bot):
bot.add_cog(BasicCommands(bot))

View File

@ -1,189 +0,0 @@
import discord
from discord.ext import commands
class BotManager:
def __init__(self, bot):
self.bot = bot
async def on_member_join(self, member):
# If the member is not a bot
if member.bot is False:
return
else:
# The member is a bot
bot_owner = member.guild.get_member((await self.bot.db_con.fetchval('select owner from bots where id = $1', member.id))
await bot_owner.add_roles(discord.utils.get(member.guild.roles, name='Bot Developers'))
await member.add_roles(discord.utils.get(member.guild.roles, name='Bots'))
try:
await member.edit(nick='[' + await self.bot.db_con.fetchval('select prefix from bots where id = $1', member.id)
+ '] ' + member.name)
except:
pass
async def on_member_remove(self, member):
# If the member is not a bot
if member.bot is False:
return
else:
# The member is a bot
await self.bot.db_con.execute('DELETE FROM bots WHERE id = $1', member.id)
async def on_member_ban(self, guild, user):
if member.bot is True:
return
else:
# I need to finish this
pass
@commands.command()
async def invite(self, ctx, bot=None, prefix=None):
bot = await ctx.bot.get_user_info(bot)
if not bot:
raise Warning('You must include the id of the bot you are trying to invite... Be exact.')
if not bot.bot:
raise Warning('You can only invite bots.')
if not prefix:
raise Warning('Please provide a prefix')
# Make sure that the bot has not been invited already and it is not being tested
if await self.bot.db_con.fetch('select count(*) from bots where id = $1', bot.id) == 1:
raise Warning('The bot has already been invited or is being tested')
await self.bot.db_con.execute('insert into bots (id, owner, prefix) values ($1, $2, $3)',
bot.id, ctx.author.id, prefix)
em = discord.Embed(colour=self.bot.embed_color)
em.title = "Hello {},".format(ctx.author.name)
em.description = "Thanks for inviting your bot! It will be tested and invited shortly. " \
"Please open your DMs if they are not already so the bot can contact " \
"you to inform you about the progress of the bot!"
await ctx.send(embed=em)
em = discord.Embed(title="Bot invite", colour=discord.Color(0x363941))
em.description = discord.utils.oauth_url(client_id, permissions=None, guild=ctx.guild))
em.set_thumbnail(url=bot.avatar_url)
em.add_field(name="Bot name", value=bot.name)
em.add_field(name="Bot id", value="`" + str(bot.id) + "`")
em.add_field(name="Bot owner", value=ctx.author.mention)
em.add_field(name="Bot prefix", value="`" + prefix + "`")
await ctx.bot.get_channel(459280759945953300).send(embed=em)
@commands.command(name='claim', aliases=['makemine', 'gimme'])
@commands.cooldown(1, 5, commands.BucketType.user)
async def _claim_bot(self, ctx, bot: discord.Member = None, prefix: str = None, owner: discord.Member = None):
if not bot:
raise Warning('You must include the name of the bot you are trying to claim... Be exact.')
if not bot.bot:
raise Warning('You can only claim bots.')
if not prefix:
if bot.display_name.startswith('['):
prefix = bot.display_name.split(']')[0].strip('[')
else:
raise Warning('Prefix not provided and can\'t be found in bot nick.')
if owner is not None and ctx.author.guild_permissions.manage_roles:
author_id = owner.id
else:
author_id = ctx.author.id
em = discord.Embed()
if await self.bot.db_con.fetchval('select count(*) from bots where owner = $1', author_id) >= 10:
em.colour = self.bot.error_color
em.title = 'Too Many Bots Claimed'
em.description = 'Each person is limited to claiming 10 bots as that is how ' \
'many bots are allowed by the Discord API per user.'
return await ctx.send(embed=em)
existing = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
if not existing:
await self.bot.db_con.execute('insert into bots (id, owner, prefix) values ($1, $2, $3)',
bot.id, author_id, prefix)
em.colour = self.bot.embed_color
em.title = 'Bot Claimed'
em.description = f'You have claimed {bot.display_name} with a prefix of {prefix}\n' \
f'If there is an error please run command again to correct the prefix,\n' \
f'or {ctx.prefix}unclaim {bot.mention} to unclaim the bot.'
elif existing['owner'] and existing['owner'] != author_id:
em.colour = self.bot.error_color
em.title = 'Bot Already Claimed'
em.description = 'This bot has already been claimed by someone else.\n' \
'If this is actually your bot please let the guild Administrators know.'
elif existing['owner'] and existing['owner'] == author_id:
em.colour = self.bot.embed_color
em.title = 'Bot Already Claimed'
em.description = 'You have already claimed this bot.\n' \
'If the prefix you provided is different from what is already in the database' \
' it will be updated for you.'
if existing['prefix'] != prefix:
await self.bot.db_con.execute("update bots set prefix = $1 where id = $2", prefix, bot.id)
elif not existing['owner']:
await self.bot.db_con.execute('update bots set owner = $1, prefix = $2 where id = $3',
author_id, prefix, bot.id)
em.colour = self.bot.embed_color
em.title = 'Bot Claimed'
em.description = f'You have claimed {bot.display_name} with a prefix of {prefix}\n' \
f'If there is an error please run command again to correct the prefix,\n' \
f'or {ctx.prefix}unclaim {bot.mention} to unclaim the bot.'
else:
em.colour = self.bot.error_color
em.title = 'Something Went Wrong...'
await ctx.send(embed=em)
@commands.command(name='unclaim')
@commands.cooldown(1, 5, commands.BucketType.user)
async def _unclaim_bot(self, ctx, bot: discord.Member = None):
if not bot:
raise Warning('You must include the name of the bot you are trying to claim... Be exact.')
if not bot.bot:
raise Warning('You can only unclaim bots.')
em = discord.Embed()
existing = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
if not existing or not existing['owner']:
em.colour = self.bot.error_color
em.title = 'Bot Not Found'
em.description = 'That bot is not claimed'
elif existing['owner'] != ctx.author.id and not ctx.author.guild_permissions.manage_roles:
em.colour = self.bot.error_color
em.title = 'Not Claimed By You'
em.description = 'That bot is claimed by someone else.\n' \
'You can\'t unclaim someone else\'s bot'
else:
await self.bot.db_con.execute('update bots set owner = null where id = $1', bot.id)
em.colour = self.bot.embed_color
em.title = 'Bot Unclaimed'
em.description = f'You have unclaimed {bot.display_name}\n' \
f'If this is an error please reclaim using\n' \
f'{ctx.prefix}claim {bot.mention} {existing["prefix"]}'
await ctx.send(embed=em)
@commands.command(name='listclaims', aliases=['claimed', 'mybots'])
@commands.cooldown(1, 5, commands.BucketType.user)
async def _claimed_bots(self, ctx, usr: discord.Member = None):
if usr is None:
usr = ctx.author
bots = await self.bot.db_con.fetch('select * from bots where owner = $1', usr.id)
if bots:
em = discord.Embed(title=f'{usr.display_name} has claimed the following bots:',
colour=self.bot.embed_color)
for bot in bots:
member = ctx.guild.get_member(int(bot['id']))
em.add_field(name=member.display_name, value=f'Stored Prefix: {bot["prefix"]}', inline=False)
else:
em = discord.Embed(title='You have not claimed any bots.',
colour=self.bot.embed_color)
await ctx.send(embed=em)
@commands.command(name='whowns')
async def _whowns(self, ctx, bot: discord.Member):
if not bot.bot:
await ctx.send('this commands only for bots')
else:
owner = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
await ctx.send(ctx.guild.get_member(owner['owner']).display_name)
def setup(bot):
bot.add_cog(BotManager(bot))

View File

@ -1,62 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from discord.ext import commands
import discord
class Moderation:
"""
Moderation Commands
"""
def __init__(self, bot):
self.bot = bot
@commands.command()
async def kick(self, ctx, member: discord.Member = None):
"""
Kick a discord member from your server.
Only contributors can use this command.
Usage:
- kick <discord.member>
"""
await ctx.trigger_typing()
if ctx.author.id not in self.bot.ownerlist:
return await ctx.send('Only my contributors can use me like this :blush:', delete_after=10)
if member is None:
await ctx.send('Are you sure you are capable of this command?')
try:
await member.kick()
await ctx.send(f'You kicked **`{member.name}`** from **`{ctx.guild.name}`**')
except Exception as e:
await ctx.send('You may not use this command, as you do not have permission to do so:\n\n**`{ctx.guild.name}`**'
f'\n\n```py\n{e}\n```')
@commands.command()
async def ban(self, ctx, member: discord.Member = None):
"""
Ban a discord member from your server.
Only contributors can use this command.
Usage:
- ban <discord.member>
"""
await ctx.trigger_typing()
if ctx.author.id not in self.bot.ownerlist:
return await ctx.send('Only my contributors can use me like this :blush:', delete_after=10)
if member is None:
await ctx.send('Are you sure you are capable of this command?')
try:
await member.ban()
await ctx.send(f'You banned **`{member.name}`** from **`{ctx.guild.name}`**')
except Exception as e:
await ctx.send('You may not use this command, as you do not have permission to do so:\n\n**`{ctx.guild.name}`**'
f'\n\n```py\n{e}\n```')
def setup(bot):
bot.add_cog(Moderation(bot))

View File

@ -1,306 +0,0 @@
import asyncio
import inspect
import traceback
import weakref
from typing import Dict
import async_timeout
import dataclasses
import discord
from discord.ext import commands
import youtube_dl
# noinspection PyUnresolvedReferences,PyUnresolvedReferences,PyPackageRequirements
from . utils import noblock
YT_DL_OPTS = {
"format": 'mp3[abr>0]/bestaudio/best',
"ignoreerrors": True,
"default_search": "auto",
"source_address": "0.0.0.0",
'quiet': True
}
# Let it be waiting on an empty queue for about 30 minutes
# before closing the connection from being idle.
IDLE_FOR = 60 * 30
@dataclasses.dataclass(repr=True)
class Request:
"""Track request."""
who: discord.Member
what: str # Referral
title: str # Video title
actual_url: str # Actual URL to play
def __str__(self):
return self.title
def __hash__(self):
return hash(str(self.who.id) + self.what)
# noinspection PyBroadException
class Session:
"""
Each player being run is a session; (E.g. if you open a player in one server and I did in another).
Sessions will have a queue, an event that can fire to stop the current track and move on, and a voice
channel to bind to. This is defined as the voice channel the owner of the session was in when they made the channel.
To create a session, call ``Session.new_session``. Do not call the constructor directly.
Attributes:
ctx: discord.ext.commands.Context
The context of the original command invocation we are creating a session for.
loop: asyncio.AbstractEventLoop
The event loop to run this in.
voice_client: discord.VoiceClient
Voice client we are streaming audio through.
queue: asyncio.Queue
Track queue.
"""
@classmethod
async def new_session(cls, ctx: commands.Context):
"""
Helper to make a new session. Invoke constructor using this, as it handles any errors. It also ensures
we connect immediately.
"""
try:
s = cls(ctx)
await s.connect()
except Exception as ex:
traceback.print_exc()
await ctx.send(f"I couldn't connect! Reason: {str(ex) or type(ex).__qualname__}")
return None
else:
return s
def __init__(self, ctx: commands.Context) -> None:
"""Create a new session."""
if ctx.author.voice is None:
raise RuntimeError('Please enter a voice channel I have access to first.')
# Holds the tasks currently running associated with this.
self.voice_channel = ctx.author.voice.channel
self.ctx: commands.Context = ctx
self.voice_client: discord.VoiceClient = None
self.loop: asyncio.AbstractEventLoop = weakref.proxy(self.ctx.bot.loop)
self.queue = asyncio.Queue()
# Lock-based event to allow firing a handler to advance to the next track.
self._start_next_track_event = asyncio.Event()
self._on_stop_event = asyncio.Event()
self._player: asyncio.Task = None
self._track: asyncio.Task = None
@property
def is_connected(self) -> bool:
return self.voice_client and self.voice_client.is_connected()
async def connect(self) -> None:
"""Connects to the VC."""
if not self.is_connected and not self._player:
# noinspection PyUnresolvedReferences
self.voice_client = await self.voice_channel.connect()
self._start_next_track_event.clear()
self._player = self.__spawn_player()
else:
raise RuntimeError('I already have a voice client/player running.')
async def disconnect(self) -> None:
"""Disconnects from the VC."""
await self.voice_client.disconnect()
self.voice_client = None
def __spawn_player(self) -> asyncio.Task:
"""Starts a new player."""
async def player():
try:
while True:
# Wait on an empty queue for a finite period of time.
with async_timeout.timeout(IDLE_FOR):
request = await self.queue.get()
await self.ctx.send(f'Playing `{request}` requested by {request.who}')
# Clear the skip event if it is set.
self._start_next_track_event.clear()
# Start the player if it was a valid request, else continue to the next track.
if not self.__play(request.actual_url):
await self.ctx.send(f'{request.referral} was a bad request and was skipped.')
continue
await self._start_next_track_event.wait()
if self.voice_client.is_playing():
self.voice_client.stop()
except asyncio.CancelledError:
# Hit when someone kills the player using stop().
print('Requested to stop player', repr(self))
except asyncio.TimeoutError:
await self.ctx.send('Was idle for too long...')
print('Player queue was empty for too long and was stopped', repr(self))
except Exception:
traceback.print_exc()
finally:
if self.voice_client.is_playing():
await self.voice_client.stop()
if self.is_connected:
await self.disconnect()
return self.loop.create_task(player())
def __play(self, url):
"""Tries to play the given URL. If it fails, we return False, else we return True."""
try:
ffmpeg_player = discord.FFmpegPCMAudio(url)
# Play the stream. After we finish, either from being cancelled or otherwise, fire the
# skip track event to start the next track.
self.voice_client.play(ffmpeg_player, after=lambda error: self._start_next_track_event.set())
except Exception:
traceback.print_exc()
return False
else:
return True
def skip(self):
"""Request to skip track."""
self._start_next_track_event.set()
def stop(self):
"""Request to stop playing."""
if self._player:
self._player.cancel()
self._on_stop_event.set()
self._on_stop_event.clear()
def on_exit(self, func):
"""Decorates a function to invoke it on exit."""
async def callback():
await self._on_stop_event.wait()
inspect.iscoroutinefunction(func) and await func() or func()
self.loop.create_task(callback())
return func
# noinspection PyBroadException
class PlayerCog:
def __init__(self):
self.sessions: Dict[discord.Guild, Session] = {}
# noinspection PyMethodMayBeStatic
async def __local_check(self, ctx):
return ctx.guild
@commands.command()
async def join(self, ctx):
if ctx.guild not in self.sessions:
p = await Session.new_session(ctx)
if p:
self.sessions[ctx.guild] = p
@p.on_exit
def when_terminated():
try:
self.sessions.pop(ctx.guild)
finally:
return
await ctx.send("*hacker voice*\n**I'm in.**", delete_after=15)
else:
await ctx.send(f'I am already playing in {self.sessions[ctx.guild].voice_channel.mention}')
# noinspection PyNestedDecorators
@staticmethod
@noblock.no_block
def _get_video_meta(referral):
downloader = youtube_dl.YoutubeDL(YT_DL_OPTS)
info = downloader.extract_info(referral, download=False)
return info
@commands.command()
async def queue(self, ctx):
if ctx.guild not in self.sessions:
return await ctx.send('Please join me into a voice channel first.')
sesh = self.sessions[ctx.guild]
if sesh.queue.empty():
return await ctx.send(
'There is nothing in the queue at the moment!\n\n'
'Add something by running `<>play https://url` or `<>play search term`!')
# We cannot faff around with the actual queue so make a shallow copy of the internal
# non-async dequeue.
# noinspection PyProtectedMember
agenda = sesh.queue._queue.copy()
message = ['**Queue**']
for i, item in enumerate(list(agenda)[:15]):
message.append(f'`{i+1: >2}: {item.title} ({item.who})`')
if len(agenda) >= 15:
message.append('')
message.append(f'There are {len(agenda)} items in the queue currently.')
await ctx.send('\n'.join(message)[:2000])
@commands.command()
async def play(self, ctx, *, referral):
if ctx.guild not in self.sessions:
return await ctx.send('Please join me into a voice channel first.')
try:
try:
info = await self._get_video_meta(referral)
# If it was interpreted as a search, it appears this happens?
# The documentation is so nice.
if info.get('_type') == 'playlist':
info = info['entries'][0]
# ...wait... did I say nice? I meant "non existent."
url = info['url']
title = info.get('title') or referral
except IndexError:
return await ctx.send('No results...', delete_after=15)
except Exception as ex:
return await ctx.send(f"Couldn't add this to the queue... reason: {ex!s}")
await self.sessions[ctx.guild].queue.put(Request(ctx.author, referral, title, url))
await ctx.send(f'Okay. Queued `{title or referral}`.')
except KeyError:
await ctx.send('I am not playing in this server.')
@commands.command()
async def stop(self, ctx):
try:
await self.sessions[ctx.guild].stop()
except KeyError:
await ctx.send('I am not playing in this server.')
except TypeError:
await ctx.send("I wasn't playing anything, but okay.", delete_after=15)
@commands.command()
async def skip(self, ctx):
try:
self.sessions[ctx.guild].skip()
try:
await ctx.message.add_reaction('\N{OK HAND SIGN}')
except discord.Forbidden:
await ctx.send('\N{OK HAND SIGN}')
except KeyError:
await ctx.send('I am not playing in this server.')
@commands.command()
async def disconnect(self, ctx):
await self.sessions[ctx.guild].stop()
await self.disconnect()
def setup(bot):
bot.add_cog(PlayerCog())