Update to work with the rewrite: Batch 1
This commit is contained in:
parent
4b4649b0de
commit
23e69a01c6
|
@ -34,17 +34,17 @@ class Blackjack:
|
|||
# When we're done with the game, we need to delete the game itself and remove it's instance from games
|
||||
# To do this, it needs to be able to access this instance of Blackjack
|
||||
game = Game(self.bot, message, self)
|
||||
self.games[message.server.id] = game
|
||||
self.games[message.guild.id] = game
|
||||
|
||||
@commands.group(pass_context=True, no_pm=True, aliases=['bj'], invoke_without_command=True)
|
||||
@commands.group(no_pm=True, aliases=['bj'], invoke_without_command=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def blackjack(self, ctx):
|
||||
"""Creates a game/joins the current running game of blackjack
|
||||
|
||||
EXAMPLE: !blackjack
|
||||
RESULT: A new game of blackjack!"""
|
||||
# Get this server's game if it exists
|
||||
game = self.games.get(ctx.message.server.id)
|
||||
# Get this guild's game if it exists
|
||||
game = self.games.get(ctx.message.guild.id)
|
||||
# If it doesn't, start one
|
||||
if game is None:
|
||||
self.create_game(ctx.message)
|
||||
|
@ -54,15 +54,15 @@ class Blackjack:
|
|||
# If it worked, they're ready to play
|
||||
if status:
|
||||
fmt = "{} has joined the game of blackjack, and will be able to play next round!"
|
||||
await self.bot.say(fmt.format(ctx.message.author.display_name))
|
||||
await ctx.send(fmt.format(ctx.message.author.display_name))
|
||||
else:
|
||||
# Otherwise, lets check *why* they couldn't join
|
||||
if game.playing(ctx.message.author):
|
||||
await self.bot.say("You are already playing! Wait for your turn!")
|
||||
await ctx.send("You are already playing! Wait for your turn!")
|
||||
else:
|
||||
await self.bot.say("There are already a max number of players playing/waiting to play!")
|
||||
await ctx.send("There are already a max number of players playing/waiting to play!")
|
||||
|
||||
@blackjack.command(pass_context=True, no_pm=True, name='leave', aliases=['quit'])
|
||||
@blackjack.command(no_pm=True, name='leave', aliases=['quit'])
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def blackjack_leave(self, ctx):
|
||||
"""Leaves the current game of blackjack
|
||||
|
@ -70,37 +70,37 @@ class Blackjack:
|
|||
EXAMPLE: !blackjack leave
|
||||
RESULT: You stop losing money in blackjack"""
|
||||
|
||||
# Get this server's game if it exists
|
||||
game = self.games.get(ctx.message.server.id)
|
||||
# Get this guild's game if it exists
|
||||
game = self.games.get(ctx.message.guild.id)
|
||||
|
||||
if game is None:
|
||||
await self.bot.say("There are currently no games of Blackjack running!")
|
||||
await ctx.send("There are currently no games of Blackjack running!")
|
||||
return
|
||||
|
||||
status = game.leave(ctx.message.author)
|
||||
if status:
|
||||
await self.bot.say("You have left the game, and will be removed at the end of this round")
|
||||
await ctx.send("You have left the game, and will be removed at the end of this round")
|
||||
else:
|
||||
await self.bot.say("Either you have already bet, or you are not even playing right now!")
|
||||
await ctx.send("Either you have already bet, or you are not even playing right now!")
|
||||
|
||||
@blackjack.command(pass_context=True, no_pm=True, name='forcestop', aliases=['stop'])
|
||||
@utils.custom_perms(manage_server=True)
|
||||
@blackjack.command(no_pm=True, name='forcestop', aliases=['stop'])
|
||||
@utils.custom_perms(manage_guild=True)
|
||||
async def blackjack_stop(self, ctx):
|
||||
"""Forces the game to stop, mostly for use if someone has gone afk
|
||||
|
||||
EXAMPLE: !blackjack forcestop
|
||||
RESULT: No more blackjack spam"""
|
||||
|
||||
# Get this server's game if it exists
|
||||
game = self.games.get(ctx.message.server.id)
|
||||
# Get this guild's game if it exists
|
||||
game = self.games.get(ctx.message.guild.id)
|
||||
|
||||
if game is None:
|
||||
await self.bot.say("There are currently no games of Blackjack running!")
|
||||
await ctx.send("There are currently no games of Blackjack running!")
|
||||
return
|
||||
|
||||
game.task.cancel()
|
||||
del self.games[ctx.message.server.id]
|
||||
await self.bot.say("The blackjack game running here has just ended")
|
||||
del self.games[ctx.message.guild.id]
|
||||
await ctx.send("The blackjack game running here has just ended")
|
||||
|
||||
|
||||
def FOIL(a, b):
|
||||
|
@ -226,7 +226,7 @@ class Game:
|
|||
async def game_task(self):
|
||||
"""The task to handle the entire game"""
|
||||
while len(self.players) > 0:
|
||||
await self.bot.send_message(self.channel, "A new round has started!!")
|
||||
await self.channel.send("A new round has started!!")
|
||||
|
||||
# First wait for bets
|
||||
await self.bet_task()
|
||||
|
@ -253,25 +253,25 @@ class Game:
|
|||
await self.cleanup()
|
||||
|
||||
# If we reach the end of this loop, that means there are no more players
|
||||
del self.bj.games[self.channel.server.id]
|
||||
del self.bj.games[self.channel.guild.id]
|
||||
|
||||
async def dealer_task(self):
|
||||
"""The task handling the dealer's play after all players have stood"""
|
||||
fmt = "It is the dealer's turn to play\n\n{}".format(self.dealer)
|
||||
msg = await self.bot.send_message(self.channel, fmt)
|
||||
msg = await self.channel.send(fmt)
|
||||
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
if self.dealer.bust:
|
||||
fmt = msg.content + "\n\nDealer has busted!!"
|
||||
await self.bot.edit_message(msg, fmt)
|
||||
await msg.edit(content=fmt)
|
||||
return
|
||||
for num in self.dealer.count:
|
||||
if num > 16:
|
||||
return
|
||||
self.hit(self.dealer)
|
||||
fmt = "It is the dealer's turn to play\n\n{}".format(self.dealer)
|
||||
msg = await self.bot.edit_message(msg, fmt)
|
||||
msg = await msg.edit(content=fmt)
|
||||
|
||||
async def round_task(self):
|
||||
"""The task handling the round itself, asking each person to hit or stand"""
|
||||
|
@ -280,21 +280,25 @@ class Game:
|
|||
# A differen task will handle if a player hit blackjack to start (so they would not be 'playing')
|
||||
|
||||
# Our check to make sure a valid 'command' was provided
|
||||
check = lambda m: m.content.lower() in ['hit', 'stand', 'double']
|
||||
def check(m):
|
||||
if m.channel == self.channel && m.author = player.member:
|
||||
return m.content.lower() in ['hit', 'stand', 'double']
|
||||
else:
|
||||
return False
|
||||
|
||||
# First lets handle the blackjacks
|
||||
for entry in [p for p in self.players if p['status'] == 'blackjack']:
|
||||
player = entry['player']
|
||||
fmt = "You got a blackjack {0.member.mention}!\n\n{0}".format(player)
|
||||
|
||||
await self.bot.send_message(self.channel, fmt)
|
||||
await self.channel.send(fmt)
|
||||
# Loop through each player (as long as their status is playing) and they have bet chips
|
||||
for entry in [p for p in self.players if p['status'] == 'playing' and hasattr(p['player'], 'bet')]:
|
||||
player = entry['player']
|
||||
|
||||
# Let them know it's their turn to play
|
||||
fmt = "It is your turn to play {0.member.mention}\n\n{0}".format(player)
|
||||
await self.bot.send_message(self.channel, fmt)
|
||||
await self.channel.send(fmt)
|
||||
|
||||
# If they're not playing anymore (i.e. they busted, are standing, etc.) then we don't want to keep asking
|
||||
# them to hit or stand
|
||||
|
@ -302,37 +306,28 @@ class Game:
|
|||
|
||||
# Ask if they want to hit or stand
|
||||
fmt = "Hit, stand, or double?"
|
||||
await self.bot.send_message(self.channel, fmt)
|
||||
msg = await self.bot.wait_for_message(timeout=60, author=player.member, channel=self.channel,
|
||||
check=check)
|
||||
await self.channel.send(fmt)
|
||||
|
||||
# If they took to long, make them stand so the next person can play
|
||||
if msg is None:
|
||||
await self.bot.send_message(self.channel, "Took to long! You're standing!")
|
||||
try:
|
||||
msg = await self.bot.wait_for('message', timeout=60, check=check)
|
||||
except asyncio.TimeoutError:
|
||||
await self.channel.send("Took to long! You're standing!")
|
||||
entry['status'] = 'stand'
|
||||
# If they want to hit
|
||||
elif 'hit' in msg.content.lower():
|
||||
self.hit(player)
|
||||
await self.bot.send_message(self.channel, player)
|
||||
# If they want to stand
|
||||
elif 'stand' in msg.content.lower():
|
||||
self.stand(player)
|
||||
elif 'double' in msg.content.lower():
|
||||
self.double(player)
|
||||
await self.bot.send_message(self.channel, player)
|
||||
# TODO: Handle double, split
|
||||
else:
|
||||
# If they want to hit
|
||||
if 'hit' in msg.content.lower():
|
||||
self.hit(player)
|
||||
await self.channel.send(player)
|
||||
# If they want to stand
|
||||
elif 'stand' in msg.content.lower():
|
||||
self.stand(player)
|
||||
elif 'double' in msg.content.lower():
|
||||
self.double(player)
|
||||
await self.channel.send(player)
|
||||
# TODO: Handle double, split
|
||||
|
||||
async def bet_task(self):
|
||||
"""Performs the task of betting"""
|
||||
|
||||
def check(_msg):
|
||||
"""Makes sure the message provided is within the min and max bets"""
|
||||
try:
|
||||
msg_length = int(_msg.content)
|
||||
return self.min_bet <= msg_length <= self.max_bet
|
||||
except ValueError:
|
||||
return _msg.content.lower() == 'skip'
|
||||
|
||||
# There is one situation that we want to allow that means we cannot loop through players like normally would
|
||||
# be the case: Betting has started; while one person is betting, another joins This means our list has
|
||||
# changed, and neither based on the length or looping through the list itself will handle this To handle
|
||||
|
@ -348,28 +343,43 @@ class Game:
|
|||
entry = players[0]
|
||||
player = entry['player']
|
||||
|
||||
def check(_msg):
|
||||
"""Makes sure the message provided is within the min and max bets"""
|
||||
if _msg.channel == self.channel and _msg.author == player.member:
|
||||
try:
|
||||
msg_length = int(_msg.content)
|
||||
return self.min_bet <= msg_length <= self.max_bet
|
||||
except ValueError:
|
||||
return _msg.content.lower() == 'skip'
|
||||
else:
|
||||
return false
|
||||
|
||||
fmt = "Your turn to bet {0.member.mention}, your current chips are: {0.chips}\n" \
|
||||
"Current min bet is {1}, current max bet is {2}\n" \
|
||||
"Place your bet now (please provide only the number;" \
|
||||
"'skip' if you would like to leave this game)".format(player, self.min_bet, self.max_bet)
|
||||
await self.bot.send_message(self.channel, fmt)
|
||||
msg = await self.bot.wait_for_message(timeout=60, author=player.member, channel=self.channel, check=check)
|
||||
|
||||
if msg is None:
|
||||
await self.bot.send_message(self.channel, "You took too long! You're sitting this round out")
|
||||
await self.channel.send(fmt)
|
||||
|
||||
try:
|
||||
msg = await self.bot.wait_for("message", timeout=60, check=check)
|
||||
except asyncio.TimeoutError:
|
||||
await self.channel.send("You took too long! You're sitting this round out")
|
||||
entry['status'] = 'stand'
|
||||
elif msg.content.lower() == 'skip':
|
||||
await self.bot.send_message(self.channel, "Alright, you've been removed from the game")
|
||||
self.leave(player.member)
|
||||
else:
|
||||
num = int(msg.content)
|
||||
# Set the new bet, and remove it from this players chip total
|
||||
if num <= player.chips:
|
||||
player.bet = num
|
||||
player.chips -= num
|
||||
entry['status'] = 'bet'
|
||||
if msg.content.lower() == 'skip':
|
||||
await self.channel.send("Alright, you've been removed from the game")
|
||||
self.leave(player.member)
|
||||
else:
|
||||
await self.bot.send_message(self.channel, "You can't bet more than you have!!")
|
||||
num = int(msg.content)
|
||||
# Set the new bet, and remove it from this players chip total
|
||||
if num <= player.chips:
|
||||
player.bet = num
|
||||
player.chips -= num
|
||||
entry['status'] = 'bet'
|
||||
else:
|
||||
await self.channel.send("You can't bet more than you have!!")
|
||||
|
||||
# Call this so that we can correct the list, if someone has left or join
|
||||
self.player_cleanup()
|
||||
|
||||
|
@ -464,7 +474,7 @@ class Game:
|
|||
# Add that to the main string
|
||||
fmt += "Blackjacks: {}\n".format(_fmt)
|
||||
|
||||
await self.bot.send_message(self.channel, fmt)
|
||||
await self.channel.send(fmt)
|
||||
|
||||
# Do the same for the dealers hand
|
||||
cards = list(self.dealer.hand.draw(self.dealer.hand.count))
|
||||
|
@ -481,10 +491,10 @@ class Game:
|
|||
self.players.extend(self._added_players)
|
||||
self._added_players.clear()
|
||||
|
||||
# What we want to do is remove any players that are in the game and have left the server
|
||||
# What we want to do is remove any players that are in the game and have left the guild
|
||||
for entry in self.players:
|
||||
m = entry['player'].member
|
||||
if m not in self.channel.server.members:
|
||||
if m not in self.channel.guild.members:
|
||||
self._removed_players.append(entry['player'])
|
||||
|
||||
# Remove the players who left
|
||||
|
|
|
@ -10,7 +10,7 @@ from enum import Enum
|
|||
class Chess:
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
# Our format for games is going to be a little different, because we do want to allow multiple games per server
|
||||
# Our format for games is going to be a little different, because we do want to allow multiple games per guild
|
||||
# Format should be {'server_id': [Game, Game, Game]}
|
||||
self.games = {}
|
||||
|
||||
|
@ -91,18 +91,18 @@ class Chess:
|
|||
return MoveStatus.invalid
|
||||
|
||||
def get_game(self, player):
|
||||
"""Provides the game this player is playing, in this server"""
|
||||
server_games = self.games.get(player.server.id, [])
|
||||
for game in server_games:
|
||||
"""Provides the game this player is playing, in this guild"""
|
||||
guild_games = self.games.get(player.guild.id, [])
|
||||
for game in guild_games:
|
||||
if player in game.challengers.values():
|
||||
return game
|
||||
|
||||
return None
|
||||
|
||||
def in_game(self, player):
|
||||
"""Checks to see if a player is playing in a game right now, in this server"""
|
||||
server_games = self.games.get(player.server.id, [])
|
||||
for game in server_games:
|
||||
"""Checks to see if a player is playing in a game right now, in this guild"""
|
||||
guild_games = self.games.get(player.guild.id, [])
|
||||
for game in guild_games:
|
||||
if player in game.challengers.values():
|
||||
return True
|
||||
|
||||
|
@ -111,13 +111,13 @@ class Chess:
|
|||
def start_game(self, player1, player2):
|
||||
game = Game(player1, player2)
|
||||
try:
|
||||
self.games[player1.server.id].append(game)
|
||||
self.games[player1.guild.id].append(game)
|
||||
except KeyError:
|
||||
self.games[player1.server.id] = [game]
|
||||
self.games[player1.guild.id] = [game]
|
||||
|
||||
return game
|
||||
|
||||
@commands.group(pass_contxt=True, invoke_without_command=True)
|
||||
@commands.group(invoke_without_command=True)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def chess(self, ctx, *, move):
|
||||
"""Moves a piece based on the notation provided
|
||||
|
@ -142,45 +142,45 @@ class Chess:
|
|||
EXAMPLE: !rook to d4"""
|
||||
result = self.play(ctx.message.author, move)
|
||||
if result is MoveStatus.invalid:
|
||||
await self.bot.say("That was an invalid move!")
|
||||
await ctx.send("That was an invalid move!")
|
||||
elif result is MoveStatus.wrong_turn:
|
||||
await self.bot.say("It is not your turn to play on your game in this server!")
|
||||
await ctx.send("It is not your turn to play on your game in this guild!")
|
||||
elif result is MoveStatus.no_game:
|
||||
await self.bot.say("You are not currently playing a game on this server!")
|
||||
await ctx.send("You are not currently playing a game on this guild!")
|
||||
elif result is MoveStatus.valid:
|
||||
game = self.get_game(ctx.message.author)
|
||||
link = game.draw_board()
|
||||
await self.bot.upload(link)
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.command()
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def chess_start(self, ctx, player2: discord.Member):
|
||||
"""Starts a chess game with another player
|
||||
You can play one game on a single server at a time
|
||||
You can play one game on a single guild at a time
|
||||
|
||||
EXAMPLE: !chess start @Victim
|
||||
RESULT: A new chess game! Good luck~"""
|
||||
|
||||
# Lets first check our permissions; we're not going to create a text based board
|
||||
# So we need to be able to attach files in order to send the board
|
||||
if not ctx.message.channel.permissions_for(ctx.message.server.me).attach_files:
|
||||
await self.bot.say(
|
||||
if not ctx.message.channel.permissions_for(ctx.message.guild.me).attach_files:
|
||||
await ctx.send(
|
||||
"I need to be able to send pictures to provide the board! Please ask someone with mange roles permission, to grant me attach files permission if you want to play this")
|
||||
return
|
||||
|
||||
# Make sure the author and player 2 are not in a game already
|
||||
if self.in_game(ctx.message.author):
|
||||
await self.bot.say("Sorry, but you can only be in one game per server at a time")
|
||||
await ctx.send("Sorry, but you can only be in one game per guild at a time")
|
||||
return
|
||||
|
||||
if self.in_game(player2):
|
||||
await self.bot.say("Sorry, but {} is already in a game on this server!".format(player2.display_name))
|
||||
await ctx.send("Sorry, but {} is already in a game on this guild!".format(player2.display_name))
|
||||
return
|
||||
|
||||
# Start the game
|
||||
game = self.start_game(ctx.message.author, player2)
|
||||
player1 = game.challengers.get('white')
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
"{} you have started a chess game with {}\n\n{} will be white this game, and is going first.\nIf you need information about the notation used to play, run {}help chess".format(
|
||||
ctx.message.author.display_name, player2.display_name, ctx.prefix))
|
||||
|
||||
|
@ -209,7 +209,7 @@ class Game:
|
|||
self.reset_board()
|
||||
|
||||
# The point of chess revolves around the king's position
|
||||
# Due to this, we're going to use the king's position a lot, so lets save this variable
|
||||
# Due to this, we're going to use the king's position a lot, so lets save this variable
|
||||
self.w_king_pos = (0, 4)
|
||||
self.b_king_pos = (7, 4)
|
||||
|
||||
|
@ -388,7 +388,7 @@ class Game:
|
|||
def check(self):
|
||||
"""Checks our current board, and checks (based on whose turn it is) if we're in a 'check' state"""
|
||||
# To check for a check, what we should do is loop through the board
|
||||
# Then check if it's the the current players turn's piece, and compare to moving to the king's position
|
||||
# Then check if it's the the current players turn's piece, and compare to moving to the king's position
|
||||
for x, row in enumerate(self.board):
|
||||
for y, piece in enumerate(row):
|
||||
if self.white_turn and re.search('B.', piece) and self.valid_move((x, y), self.b_king_pos):
|
||||
|
|
98
cogs/core.py
98
cogs/core.py
|
@ -23,30 +23,7 @@ class Core:
|
|||
self.results_per_page = 10
|
||||
self.commands = None
|
||||
|
||||
def find_command(self, command):
|
||||
# This method ensures the command given is valid. We need to loop through commands
|
||||
# As self.bot.commands only includes parent commands
|
||||
# So we are splitting the command in parts, looping through the commands
|
||||
# And getting the subcommand based on the next part
|
||||
# If we try to access commands of a command that isn't a group
|
||||
# We'll hit an AttributeError, meaning an invalid command was given
|
||||
# If we loop through and don't find anything, cmd will still be None
|
||||
# And we'll report an invalid was given as well
|
||||
cmd = None
|
||||
|
||||
for part in command.split():
|
||||
try:
|
||||
if cmd is None:
|
||||
cmd = self.bot.commands.get(part)
|
||||
else:
|
||||
cmd = cmd.commands.get(part)
|
||||
except AttributeError:
|
||||
cmd = None
|
||||
break
|
||||
|
||||
return cmd
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def help(self, ctx, *, message=None):
|
||||
"""This command is used to provide a link to the help URL.
|
||||
|
@ -65,7 +42,7 @@ class Core:
|
|||
try:
|
||||
page = int(message)
|
||||
except:
|
||||
cmd = self.find_command(message)
|
||||
cmd = self.bot.get_command(message)
|
||||
|
||||
if cmd is None:
|
||||
entries = sorted(utils.get_all_commands(self.bot))
|
||||
|
@ -73,7 +50,7 @@ class Core:
|
|||
pages = utils.Pages(self.bot, message=ctx.message, entries=entries)
|
||||
await pages.paginate(start_page=page)
|
||||
except utils.CannotPaginate as e:
|
||||
await self.bot.say(str(e))
|
||||
await ctx.send(str(e))
|
||||
else:
|
||||
# Get the description for a command
|
||||
description = cmd.help
|
||||
|
@ -100,11 +77,11 @@ class Core:
|
|||
if subcommands:
|
||||
embed.add_field(name='Subcommands', value="\n".join(subcommands), inline=False)
|
||||
|
||||
await self.bot.say(embed=embed)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def motd(self, *, date=None):
|
||||
async def motd(self, ctx, *, date=None):
|
||||
"""This command can be used to print the current MOTD (Message of the day)
|
||||
This will most likely not be updated every day, however messages will still be pushed to this every now and then
|
||||
|
||||
|
@ -126,10 +103,10 @@ class Core:
|
|||
motd = latest_motd['motd']
|
||||
# This will be hit if we do not have any entries for motd
|
||||
except TypeError:
|
||||
await self.bot.say("No message of the day!")
|
||||
await ctx.send("No message of the day!")
|
||||
else:
|
||||
fmt = "Last updated: {}\n\n{}".format(date, motd)
|
||||
await self.bot.say(fmt)
|
||||
await ctx.send(fmt)
|
||||
else:
|
||||
try:
|
||||
r_filter = pendulum.parse(date)
|
||||
|
@ -137,18 +114,18 @@ class Core:
|
|||
date = motd[0]['date']
|
||||
motd = motd[0]['motd']
|
||||
fmt = "Message of the day for {}:\n\n{}".format(date, motd)
|
||||
await self.bot.say(fmt)
|
||||
await ctx.send(fmt)
|
||||
# This one will be hit if we return None for that day
|
||||
except TypeError:
|
||||
await self.bot.say("No message of the day for {}!".format(date))
|
||||
await ctx.send("No message of the day for {}!".format(date))
|
||||
# This will be hit if pendulum fails to parse the date passed
|
||||
except ValueError:
|
||||
now = pendulum.utcnow().to_date_string()
|
||||
await self.bot.say("Invalid date format! Try like {}".format(now))
|
||||
await ctx.send("Invalid date format! Try like {}".format(now))
|
||||
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def calendar(self, month: str = None, year: int = None):
|
||||
async def calendar(self, ctx, month: str = None, year: int = None):
|
||||
"""Provides a printout of the current month's calendar
|
||||
Provide month and year to print the calendar of that year and month
|
||||
|
||||
|
@ -176,30 +153,23 @@ class Core:
|
|||
else:
|
||||
month = months.get(month.lower())
|
||||
if month is None:
|
||||
await self.bot.say("Please provide a valid Month!")
|
||||
await ctx.send("Please provide a valid Month!")
|
||||
return
|
||||
# If year was not passed, use the current year
|
||||
if year is None:
|
||||
year = datetime.datetime.today().year
|
||||
# Here we create the actual "text" calendar that we are printing
|
||||
cal = calendar.TextCalendar().formatmonth(year, month)
|
||||
await self.bot.say("```\n{}```".format(cal))
|
||||
await ctx.send("```\n{}```".format(cal))
|
||||
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def info(self):
|
||||
async def info(self, ctx):
|
||||
"""This command can be used to print out some of my information"""
|
||||
# fmt is a dictionary so we can set the key to it's output, then print both
|
||||
# The only real use of doing it this way is easier editing if the info
|
||||
# in this command is changed
|
||||
|
||||
bot_data = await utils.get_content('bot_data')
|
||||
total_data = {'member_count': 0,
|
||||
'server_count': 0}
|
||||
for entry in bot_data:
|
||||
total_data['member_count'] += entry['member_count']
|
||||
total_data['server_count'] += entry['server_count']
|
||||
|
||||
# Create the original embed object
|
||||
opts = {'title': 'Dev Server',
|
||||
'description': 'Join the server above for any questions/suggestions about me.',
|
||||
|
@ -207,8 +177,8 @@ class Core:
|
|||
embed = discord.Embed(**opts)
|
||||
|
||||
# Add the normal values
|
||||
embed.add_field(name='Total Servers', value=total_data['server_count'])
|
||||
embed.add_field(name='Total Members', value=total_data['member_count'])
|
||||
embed.add_field(name='Total Servers', value=len(self.bot.servers))
|
||||
embed.add_field(name='Total Members', value=len(set(self.bot.get_all_members())))
|
||||
|
||||
# Count the variable values; hangman, tictactoe, etc.
|
||||
hm_games = len(self.bot.get_cog('Hangman').games)
|
||||
|
@ -233,20 +203,20 @@ class Core:
|
|||
embed.add_field(name='Uptime', value=(pendulum.utcnow() - self.bot.uptime).in_words())
|
||||
embed.set_footer(text=self.bot.description)
|
||||
|
||||
await self.bot.say(embed=embed)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def uptime(self):
|
||||
async def uptime(self, ctx):
|
||||
"""Provides a printout of the current bot's uptime
|
||||
|
||||
EXAMPLE: !uptime
|
||||
RESULT: A BAJILLION DAYS"""
|
||||
await self.bot.say("Uptime: ```\n{}```".format((pendulum.utcnow() - self.bot.uptime).in_words()))
|
||||
await ctx.send("Uptime: ```\n{}```".format((pendulum.utcnow() - self.bot.uptime).in_words()))
|
||||
|
||||
@commands.command(aliases=['invite'])
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def addbot(self):
|
||||
async def addbot(self, ctx):
|
||||
"""Provides a link that you can use to add me to a server
|
||||
|
||||
EXAMPLE: !addbot
|
||||
|
@ -261,13 +231,17 @@ class Core:
|
|||
perms.embed_links = True
|
||||
perms.read_message_history = True
|
||||
perms.attach_files = True
|
||||
perms.speak = True
|
||||
perms.connect = True
|
||||
perms.attach_files = True
|
||||
perms.add_reactions = True
|
||||
app_info = await self.bot.application_info()
|
||||
await self.bot.say("Use this URL to add me to a server that you'd like!\n{}"
|
||||
await ctx.send("Use this URL to add me to a server that you'd like!\n{}"
|
||||
.format(discord.utils.oauth_url(app_info.id, perms)))
|
||||
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def doggo(self):
|
||||
async def doggo(self, ctx):
|
||||
"""Use this to print a random doggo image.
|
||||
|
||||
EXAMPLE: !doggo
|
||||
|
@ -275,7 +249,7 @@ class Core:
|
|||
# Find a random image based on how many we currently have
|
||||
f = random.SystemRandom().choice(glob.glob('images/doggo*'))
|
||||
with open(f, 'rb') as f:
|
||||
await self.bot.upload(f)
|
||||
await ctx.send(file=f)
|
||||
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
|
@ -287,11 +261,11 @@ class Core:
|
|||
# Find a random image based on how many we currently have
|
||||
f = random.SystemRandom().choice(glob.glob('images/snek*'))
|
||||
with open(f, 'rb') as f:
|
||||
await self.bot.upload(f)
|
||||
await ctx.send(file=f)
|
||||
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def joke(self):
|
||||
async def joke(self, ctx):
|
||||
"""Prints a random riddle
|
||||
|
||||
EXAMPLE: !joke
|
||||
|
@ -302,13 +276,13 @@ class Core:
|
|||
try:
|
||||
fortune = subprocess.check_output(
|
||||
fortune_command.split()).decode("utf-8")
|
||||
await self.bot.say(fortune)
|
||||
await ctx.send(fortune)
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def roll(self, ctx, notation: str = "d6"):
|
||||
"""Rolls a die based on the notation given
|
||||
|
@ -325,7 +299,7 @@ class Core:
|
|||
# Check if something like ed3 was provided, or something else entirely
|
||||
# was provided
|
||||
except (AttributeError, ValueError):
|
||||
await self.bot.say("Please provide the die notation in #d#!")
|
||||
await ctx.send("Please provide the die notation in #d#!")
|
||||
return
|
||||
|
||||
# Dice will be None if d# was provided, assume this means 1d#
|
||||
|
@ -334,13 +308,13 @@ class Core:
|
|||
# have it set
|
||||
dice = int(dice)
|
||||
if dice > 10:
|
||||
await self.bot.say("I'm not rolling more than 10 dice, I have tiny hands")
|
||||
await ctx.send("I'm not rolling more than 10 dice, I have tiny hands")
|
||||
return
|
||||
if num > 100:
|
||||
await self.bot.say("What die has more than 100 sides? Please, calm down")
|
||||
await ctx.send("What die has more than 100 sides? Please, calm down")
|
||||
return
|
||||
if num <= 1:
|
||||
await self.bot.say("A {} sided die? You know that's impossible right?".format(num))
|
||||
await ctx.send("A {} sided die? You know that's impossible right?".format(num))
|
||||
return
|
||||
|
||||
value_str = ", ".join(str(random.SystemRandom().randint(1, num))
|
||||
|
@ -350,7 +324,7 @@ class Core:
|
|||
fmt = '{0.message.author.name} has rolled a {2} sided die and got the number {3}!'
|
||||
else:
|
||||
fmt = '{0.message.author.name} has rolled {1}, {2} sided dice and got the numbers {3}!'
|
||||
await self.bot.say(fmt.format(ctx, dice, num, value_str))
|
||||
await ctx.send(fmt.format(ctx, dice, num, value_str))
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
|
22
cogs/da.py
22
cogs/da.py
|
@ -59,9 +59,7 @@ class Deviantart:
|
|||
try:
|
||||
for entry in content:
|
||||
user = discord.utils.get(self.bot.get_all_members(), id=entry['member_id'])
|
||||
|
||||
# If we're sharded, we might not be able to find this user.
|
||||
# If the bot is not in the server with the member either
|
||||
# If the bot is not in the server with the member, we might not be able to find this user.
|
||||
if user is None:
|
||||
continue
|
||||
|
||||
|
@ -97,7 +95,7 @@ class Deviantart:
|
|||
result['title'],
|
||||
result['author']['username'],
|
||||
result['url'])
|
||||
await self.bot.send_message(user, fmt)
|
||||
await user.sendfmt)
|
||||
# Now we can update the user's last updated for this DA
|
||||
# We want to do this whether or not our last if statement was met
|
||||
r_filter = {'member_id': user.id}
|
||||
|
@ -110,12 +108,12 @@ class Deviantart:
|
|||
|
||||
@commands.group()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def da(self):
|
||||
async def da(self, ctx):
|
||||
"""This provides a sort of 'RSS' feed for subscribed to artists.
|
||||
Subscribe to artists, and I will PM you when new posts come out from these artists"""
|
||||
pass
|
||||
|
||||
@da.command(pass_context=True, name='sub', aliases=['add', 'subscribe'])
|
||||
@da.command(name='sub', aliases=['add', 'subscribe'])
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def da_sub(self, ctx, *, username):
|
||||
"""This can be used to add a feed to your notifications.
|
||||
|
@ -130,7 +128,7 @@ class Deviantart:
|
|||
if content is None:
|
||||
entry = {'member_id': ctx.message.author.id, 'subbed': [username], 'last_updated': {}}
|
||||
await utils.add_content('deviantart', entry, r_filter)
|
||||
await self.bot.say("You have just subscribed to {}!".format(username))
|
||||
await ctx.send("You have just subscribed to {}!".format(username))
|
||||
elif content[0]['subbed'] is None or username not in content[0]['subbed']:
|
||||
if content[0]['subbed'] is None:
|
||||
sub_list = [username]
|
||||
|
@ -138,9 +136,9 @@ class Deviantart:
|
|||
content[0]['subbed'].append(username)
|
||||
sub_list = content[0]['subbed']
|
||||
await utils.update_content('deviantart', {'subbed': sub_list}, r_filter)
|
||||
await self.bot.say("You have just subscribed to {}!".format(username))
|
||||
await ctx.send("You have just subscribed to {}!".format(username))
|
||||
else:
|
||||
await self.bot.say("You are already subscribed to that user!")
|
||||
await ctx.send("You are already subscribed to that user!")
|
||||
|
||||
@da.command(pass_context=True, name='unsub', aliases=['delete', 'remove', 'unsubscribe'])
|
||||
@utils.custom_perms(send_messages=True)
|
||||
|
@ -153,13 +151,13 @@ class Deviantart:
|
|||
content = await utils.get_content('deviantart', r_filter)
|
||||
|
||||
if content is None or content[0]['subbed'] is None:
|
||||
await self.bot.say("You are not subscribed to anyone at the moment!")
|
||||
await ctx.send("You are not subscribed to anyone at the moment!")
|
||||
elif username in content[0]['subbed']:
|
||||
content[0]['subbed'].remove(username)
|
||||
await utils.update_content('deviantart', {'subbed': content[0]['subbed']}, r_filter)
|
||||
await self.bot.say("You have just unsubscribed from {}!".format(username))
|
||||
await ctx.send("You have just unsubscribed from {}!".format(username))
|
||||
else:
|
||||
await self.bot.say("You are not subscribed to that user!")
|
||||
await ctx.send("You are not subscribed to that user!")
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
|
|
@ -19,7 +19,7 @@ class Music:
|
|||
async def on_voice_state_update(self, before, after):
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def progress(self, ctx):
|
||||
"""Provides the progress of the current song
|
||||
|
@ -28,7 +28,7 @@ class Music:
|
|||
RESULT: 532 minutes! (Hopefully not)"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def join(self, ctx, *, channel: discord.Channel):
|
||||
"""Joins a voice channel.
|
||||
|
@ -37,7 +37,7 @@ class Music:
|
|||
RESULT: I'm in the Music voice channel!"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def summon(self, ctx):
|
||||
"""Summons the bot to join your voice channel.
|
||||
|
@ -46,7 +46,7 @@ class Music:
|
|||
RESULT: I'm in your voice channel!"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def play(self, ctx, *, song: str):
|
||||
"""Plays a song.
|
||||
|
@ -61,7 +61,7 @@ class Music:
|
|||
"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(kick_members=True)
|
||||
async def volume(self, ctx, value: int = None):
|
||||
"""Sets the volume of the currently playing song.
|
||||
|
@ -70,7 +70,7 @@ class Music:
|
|||
RESULT: My volume is now set to 50"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(kick_members=True)
|
||||
async def pause(self, ctx):
|
||||
"""Pauses the currently played song.
|
||||
|
@ -79,7 +79,7 @@ class Music:
|
|||
RESULT: I'm paused!"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(kick_members=True)
|
||||
async def resume(self, ctx):
|
||||
"""Resumes the currently played song.
|
||||
|
@ -88,7 +88,7 @@ class Music:
|
|||
RESULT: Ain't paused no more!"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(kick_members=True)
|
||||
async def stop(self, ctx):
|
||||
"""Stops playing audio and leaves the voice channel.
|
||||
|
@ -98,7 +98,7 @@ class Music:
|
|||
RESULT: No more music"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def eta(self, ctx):
|
||||
"""Provides an ETA on when your next song will play
|
||||
|
@ -107,7 +107,7 @@ class Music:
|
|||
RESULT: 5,000 days! Lol have fun"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def queue(self, ctx):
|
||||
"""Provides a printout of the songs that are in the queue.
|
||||
|
@ -121,7 +121,7 @@ class Music:
|
|||
RESULT: A list of shitty songs you probably don't wanna listen to"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def queuelength(self, ctx):
|
||||
"""Prints the length of the queue
|
||||
|
@ -130,7 +130,7 @@ class Music:
|
|||
RESULT: Probably 10 songs"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def skip(self, ctx):
|
||||
"""Vote to skip a song. The song requester can automatically skip.
|
||||
|
@ -142,7 +142,7 @@ class Music:
|
|||
"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(kick_members=True)
|
||||
async def modskip(self, ctx):
|
||||
"""Forces a song skip, can only be used by a moderator
|
||||
|
@ -151,7 +151,7 @@ class Music:
|
|||
RESULT: No more terrible song :D"""
|
||||
pass
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, enabled=False)
|
||||
@commands.command(no_pm=True, enabled=False)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def playing(self, ctx):
|
||||
"""Shows info about the currently played song.
|
||||
|
|
|
@ -48,38 +48,17 @@ class StatsUpdate:
|
|||
log.info('bots.discord.pw statistics returned {} for {}'.format(resp.status, payload))
|
||||
|
||||
async def on_server_join(self, server):
|
||||
r_filter = {'shard_id': config.shard_id}
|
||||
server_count = len(self.bot.servers)
|
||||
member_count = len(set(self.bot.get_all_members()))
|
||||
entry = {'server_count': server_count, 'member_count': member_count, "shard_id": config.shard_id}
|
||||
# Check if this was successful, if it wasn't, that means a new shard was added and we need to add that entry
|
||||
if not await config.update_content('bot_data', entry, r_filter):
|
||||
await config.add_content('bot_data', entry, r_filter)
|
||||
self.bot.loop.create_task(self.update())
|
||||
|
||||
async def on_server_leave(self, server):
|
||||
r_filter = {'shard_id': config.shard_id}
|
||||
server_count = len(self.bot.servers)
|
||||
member_count = len(set(self.bot.get_all_members()))
|
||||
entry = {'server_count': server_count, 'member_count': member_count, "shard_id": config.shard_id}
|
||||
# Check if this was successful, if it wasn't, that means a new shard was added and we need to add that entry
|
||||
if not await config.update_content('bot_data', entry, r_filter):
|
||||
await config.add_content('bot_data', entry, r_filter)
|
||||
self.bot.loop.create_task(self.update())
|
||||
|
||||
async def on_ready(self):
|
||||
r_filter = {'shard_id': config.shard_id}
|
||||
server_count = len(self.bot.servers)
|
||||
member_count = len(set(self.bot.get_all_members()))
|
||||
entry = {'server_count': server_count, 'member_count': member_count, "shard_id": config.shard_id}
|
||||
# Check if this was successful, if it wasn't, that means a new shard was added and we need to add that entry
|
||||
if not await config.update_content('bot_data', entry, r_filter):
|
||||
await config.add_content('bot_data', entry, r_filter)
|
||||
self.bot.loop.create_task(self.update())
|
||||
|
||||
async def on_member_join(self, member):
|
||||
server = member.server
|
||||
r_filter = {'server_id': server.id}
|
||||
guild = member.guild
|
||||
r_filter = {'server_id': guild.id}
|
||||
notifications = await config.get_content('user_notifications', r_filter)
|
||||
|
||||
try:
|
||||
|
@ -91,12 +70,12 @@ class StatsUpdate:
|
|||
if not channel_id:
|
||||
return
|
||||
|
||||
channel = server.get_channel(channel_id)
|
||||
await self.bot.send_message(channel, "Welcome to the '{0.server.name}' server {0.mention}!".format(member))
|
||||
channel = guild.get_channel(channel_id)
|
||||
await channel.send("Welcome to the '{0.server.name}' server {0.mention}!".format(member))
|
||||
|
||||
async def on_member_remove(self, member):
|
||||
server = member.server
|
||||
r_filter = {'server_id': server.id}
|
||||
guild = member.guild
|
||||
r_filter = {'server_id': guild.id}
|
||||
notifications = await config.get_content('user_notifications', r_filter)
|
||||
|
||||
try:
|
||||
|
@ -109,9 +88,7 @@ class StatsUpdate:
|
|||
return
|
||||
|
||||
channel = server.get_channel(channel_id)
|
||||
await self.bot.send_message(channel,
|
||||
"{0} has left the server, I hope it wasn't because of something I said :c".format(
|
||||
member.display_name))
|
||||
await channelsend("{0} has left the server, I hope it wasn't because of something I said :c".format(member.display_name))
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
|
|
@ -104,10 +104,10 @@ class Hangman:
|
|||
def create(self, word, ctx):
|
||||
# Create a new game, then save it as the server's game
|
||||
game = Game(word)
|
||||
self.games[ctx.message.server.id] = game
|
||||
self.games[ctx.message.guild.id] = game
|
||||
return game
|
||||
|
||||
@commands.group(aliases=['hm'], pass_context=True, no_pm=True, invoke_without_command=True)
|
||||
@commands.group(aliases=['hm'], no_pm=True, invoke_without_command=True)
|
||||
@commands.cooldown(1, 7, BucketType.user)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def hangman(self, ctx, *, guess):
|
||||
|
@ -115,10 +115,10 @@ class Hangman:
|
|||
|
||||
EXAMPLE: !hangman e (or) !hangman The Phrase!
|
||||
RESULT: Hopefully a win!"""
|
||||
game = self.games.get(ctx.message.server.id)
|
||||
game = self.games.get(ctx.message.guild.id)
|
||||
if not game:
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
await self.bot.say("There are currently no hangman games running!")
|
||||
await ctx.send("There are currently no hangman games running!")
|
||||
return
|
||||
|
||||
# Check if we are guessing a letter or a phrase. Only one letter can be guessed at a time
|
||||
|
@ -128,7 +128,7 @@ class Hangman:
|
|||
if len(guess) == 1:
|
||||
if guess in game.guessed_letters:
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
await self.bot.say("That letter has already been guessed!")
|
||||
await ctx.send("That letter has already been guessed!")
|
||||
# Return here as we don't want to count this as a failure
|
||||
return
|
||||
if game.guess_letter(guess):
|
||||
|
@ -143,16 +143,16 @@ class Hangman:
|
|||
|
||||
if game.win():
|
||||
fmt += " You guys got it! The word was `{}`".format(game.word)
|
||||
del self.games[ctx.message.server.id]
|
||||
del self.games[ctx.message.guild.id]
|
||||
elif game.failed():
|
||||
fmt += " Sorry, you guys failed...the word was `{}`".format(game.word)
|
||||
del self.games[ctx.message.server.id]
|
||||
del self.games[ctx.message.guild.id]
|
||||
else:
|
||||
fmt += str(game)
|
||||
|
||||
await self.bot.say(fmt)
|
||||
await ctx.send(fmt)
|
||||
|
||||
@hangman.command(name='create', aliases=['start'], no_pm=True, pass_context=True)
|
||||
@hangman.command(name='create', aliases=['start'], no_pm=True)
|
||||
@checks.custom_perms(send_messages=True)
|
||||
async def create_hangman(self, ctx):
|
||||
"""This is used to create a new hangman game
|
||||
|
@ -163,16 +163,16 @@ class Hangman:
|
|||
|
||||
# Only have one hangman game per server, since anyone
|
||||
# In a server (except the creator) can guess towards the current game
|
||||
if self.games.get(ctx.message.server.id) is not None:
|
||||
await self.bot.say("Sorry but only one Hangman game can be running per server!")
|
||||
if self.games.get(ctx.message.guild.id) is not None:
|
||||
await ctx.send("Sorry but only one Hangman game can be running per server!")
|
||||
return
|
||||
|
||||
game = self.create(random.SystemRandom().choice(phrases), ctx)
|
||||
# Let them know the game has started, then print the current game so that the blanks are shown
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
"Alright, a hangman game has just started, you can start guessing now!\n{}".format(str(game)))
|
||||
|
||||
@hangman.command(name='delete', aliases=['stop', 'remove', 'end'], pass_context=True, no_pm=True)
|
||||
@hangman.command(name='delete', aliases=['stop', 'remove', 'end'], no_pm=True)
|
||||
@checks.custom_perms(kick_members=True)
|
||||
async def stop_game(self, ctx):
|
||||
"""Force stops a game of hangman
|
||||
|
@ -181,12 +181,12 @@ class Hangman:
|
|||
|
||||
EXAMPLE: !hangman stop
|
||||
RESULT: No more men being hung"""
|
||||
if self.games.get(ctx.message.server.id) is None:
|
||||
await self.bot.say("There are no Hangman games running on this server!")
|
||||
if self.games.get(ctx.message.guild.id) is None:
|
||||
await ctx.send("There are no Hangman games running on this server!")
|
||||
return
|
||||
|
||||
del self.games[ctx.message.server.id]
|
||||
await self.bot.say("I have just stopped the game of Hangman, a new should be able to be started now!")
|
||||
del self.games[ctx.message.guild.id]
|
||||
await ctx.send("I have just stopped the game of Hangman, a new should be able to be started now!")
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
|
|
@ -85,7 +85,7 @@ class Interaction:
|
|||
self.battles = {}
|
||||
|
||||
def user_battling(self, ctx, player2=None):
|
||||
battling = self.battles.get(ctx.message.server.id)
|
||||
battling = self.battles.get(ctx.message.guild.id)
|
||||
|
||||
# If no one is battling, obviously the user is not battling
|
||||
if battling is None:
|
||||
|
@ -101,14 +101,14 @@ class Interaction:
|
|||
|
||||
# Handles removing the author from the dictionary of battles
|
||||
def battling_off(self, ctx):
|
||||
battles = self.battles.get(ctx.message.server.id) or {}
|
||||
battles = self.battles.get(ctx.message.guild.id) or {}
|
||||
player_id = ctx.message.author.id
|
||||
# Create a new dictionary, exactly the way the last one was setup
|
||||
# But don't include any that have the author's ID
|
||||
self.battles[ctx.message.server.id] = {p1: p2 for p1, p2 in battles.items() if
|
||||
self.battles[ctx.message.guild.id] = {p1: p2 for p1, p2 in battles.items() if
|
||||
not p2 == player_id and not p1 == player_id}
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def hug(self, ctx, user: discord.Member = None):
|
||||
"""Makes me hug a person!
|
||||
|
@ -119,9 +119,9 @@ class Interaction:
|
|||
user = ctx.message.author
|
||||
|
||||
fmt = random.SystemRandom().choice(hugs)
|
||||
await self.bot.say(fmt.format(user.display_name))
|
||||
await ctx.send(fmt.format(user.display_name))
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def avatar(self, ctx, member: discord.Member = None):
|
||||
"""Provides an image for the provided person's avatar (yours if no other member is provided)
|
||||
|
@ -133,21 +133,21 @@ class Interaction:
|
|||
member = ctx.message.author
|
||||
|
||||
url = member.avatar_url
|
||||
if ctx.message.server.me.permissions_in(ctx.message.channel).attach_files:
|
||||
if ctx.message.guild.me.permissions_in(ctx.message.channel).attach_files:
|
||||
file = await utils.download_image(url)
|
||||
if file is None:
|
||||
await self.bot.say(url)
|
||||
await ctx.send(url)
|
||||
else:
|
||||
if '.gif' in url:
|
||||
filename = 'avatar.gif'
|
||||
else:
|
||||
filename = 'avatar.webp'
|
||||
file = utils.convert_to_jpeg(file)
|
||||
await self.bot.upload(file, filename=filename)
|
||||
await ctx.send(file=file, filename=filename)
|
||||
else:
|
||||
await self.bot.say(url)
|
||||
await ctx.send(url)
|
||||
|
||||
@commands.group(pass_context=True, no_pm=True, invoke_without_command=True)
|
||||
@commands.group(no_pm=True, invoke_without_command=True)
|
||||
@commands.cooldown(1, 180, BucketType.user)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def battle(self, ctx, player2: discord.Member):
|
||||
|
@ -157,29 +157,29 @@ class Interaction:
|
|||
RESULT: A battle to the death"""
|
||||
if ctx.message.author.id == player2.id:
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
await self.bot.say("Why would you want to battle yourself? Suicide is not the answer")
|
||||
await ctx.send("Why would you want to battle yourself? Suicide is not the answer")
|
||||
return
|
||||
if self.bot.user.id == player2.id:
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
await self.bot.say("I always win, don't even try it.")
|
||||
await ctx.send("I always win, don't even try it.")
|
||||
return
|
||||
if self.user_battling(ctx, player2):
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
await self.bot.say("You or the person you are trying to battle is already in a battle!")
|
||||
await ctx.send("You or the person you are trying to battle is already in a battle!")
|
||||
return
|
||||
|
||||
# Add the author and player provided in a new battle
|
||||
battles = self.battles.get(ctx.message.server.id) or {}
|
||||
battles = self.battles.get(ctx.message.guild.id) or {}
|
||||
battles[ctx.message.author.id] = player2.id
|
||||
self.battles[ctx.message.server.id] = battles
|
||||
self.battles[ctx.message.guild.id] = battles
|
||||
|
||||
fmt = "{0.message.author.mention} has challenged you to a battle {1.mention}\n" \
|
||||
"{0.prefix}accept or {0.prefix}decline"
|
||||
# Add a call to turn off battling, if the battle is not accepted/declined in 3 minutes
|
||||
self.bot.loop.call_later(180, self.battling_off, ctx)
|
||||
await self.bot.say(fmt.format(ctx, player2))
|
||||
await ctx.send(fmt.format(ctx, player2))
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def accept(self, ctx):
|
||||
"""Accepts the battle challenge
|
||||
|
@ -188,13 +188,13 @@ class Interaction:
|
|||
RESULT: Hopefully the other person's death"""
|
||||
# This is a check to make sure that the author is the one being BATTLED
|
||||
# And not the one that started the battle
|
||||
battles = self.battles.get(ctx.message.server.id) or {}
|
||||
battles = self.battles.get(ctx.message.guild.id) or {}
|
||||
p1 = [p1_id for p1_id, p2_id in battles.items() if p2_id == ctx.message.author.id]
|
||||
if len(p1) == 0:
|
||||
await self.bot.say("You are not currently being challenged to a battle!")
|
||||
await ctx.send("You are not currently being challenged to a battle!")
|
||||
return
|
||||
|
||||
battleP1 = discord.utils.find(lambda m: m.id == p1[0], ctx.message.server.members)
|
||||
battleP1 = discord.utils.find(lambda m: m.id == p1[0], ctx.message.guild.members)
|
||||
battleP2 = ctx.message.author
|
||||
|
||||
# Get a random win message from our list
|
||||
|
@ -205,13 +205,13 @@ class Interaction:
|
|||
# Randomize the order of who is printed/sent to the update system
|
||||
# All we need to do is change what order the challengers are printed/added as a paramater
|
||||
if random.SystemRandom().randint(0, 1):
|
||||
await self.bot.say(fmt.format(battleP1.mention, battleP2.mention))
|
||||
await ctx.send(fmt.format(battleP1.mention, battleP2.mention))
|
||||
await utils.update_records('battle_records', battleP1, battleP2)
|
||||
else:
|
||||
await self.bot.say(fmt.format(battleP2.mention, battleP1.mention))
|
||||
await ctx.send(fmt.format(battleP2.mention, battleP1.mention))
|
||||
await utils.update_records('battle_records', battleP2, battleP1)
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def decline(self, ctx):
|
||||
"""Declines the battle challenge
|
||||
|
@ -220,20 +220,20 @@ class Interaction:
|
|||
RESULT: You chicken out"""
|
||||
# This is a check to make sure that the author is the one being BATTLED
|
||||
# And not the one that started the battle
|
||||
battles = self.battles.get(ctx.message.server.id) or {}
|
||||
battles = self.battles.get(ctx.message.guild.id) or {}
|
||||
p1 = [p1_id for p1_id, p2_id in battles.items() if p2_id == ctx.message.author.id]
|
||||
if len(p1) == 0:
|
||||
await self.bot.say("You are not currently being challenged to a battle!")
|
||||
await ctx.send("You are not currently being challenged to a battle!")
|
||||
return
|
||||
|
||||
battleP1 = discord.utils.find(lambda m: m.id == p1[0], ctx.message.server.members)
|
||||
battleP1 = discord.utils.find(lambda m: m.id == p1[0], ctx.message.guild.members)
|
||||
battleP2 = ctx.message.author
|
||||
|
||||
# There's no need to update the stats for the members if they declined the battle
|
||||
self.battling_off(ctx)
|
||||
await self.bot.say("{0} has chickened out! What a loser~".format(battleP2.mention, battleP1.mention))
|
||||
await ctx.send("{0} has chickened out! What a loser~".format(battleP2.mention, battleP1.mention))
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@commands.cooldown(1, 180, BucketType.user)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def boop(self, ctx, boopee: discord.Member = None, *, message = ""):
|
||||
|
@ -244,18 +244,18 @@ class Interaction:
|
|||
booper = ctx.message.author
|
||||
if boopee is None:
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
await self.bot.say("You try to boop the air, the air boops back. Be afraid....")
|
||||
await ctx.send("You try to boop the air, the air boops back. Be afraid....")
|
||||
return
|
||||
# To keep formatting easier, keep it either "" or the message with a space in front
|
||||
if message is not None:
|
||||
message = " " + message
|
||||
if boopee.id == booper.id:
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
await self.bot.say("You can't boop yourself! Silly...")
|
||||
await ctx.send("You can't boop yourself! Silly...")
|
||||
return
|
||||
if boopee.id == self.bot.user.id:
|
||||
ctx.command.reset_cooldown(ctx)
|
||||
await self.bot.say("Why the heck are you booping me? Get away from me >:c")
|
||||
await ctx.send("Why the heck are you booping me? Get away from me >:c")
|
||||
return
|
||||
|
||||
r_filter = {'member_id': booper.id}
|
||||
|
@ -275,7 +275,7 @@ class Interaction:
|
|||
amount = 1
|
||||
|
||||
fmt = "{0.mention} has just booped {1.mention}{3}! That's {2} times now!"
|
||||
await self.bot.say(fmt.format(booper, boopee, amount, message))
|
||||
await ctx.send(fmt.format(booper, boopee, amount, message))
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
|
|
@ -17,13 +17,15 @@ class Links:
|
|||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(pass_context=True, aliases=['g'])
|
||||
@commands.command(aliases=['g'])
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def google(self, ctx, *, query: str):
|
||||
"""Searches google for a provided query
|
||||
|
||||
EXAMPLE: !g Random cat pictures!
|
||||
RESULT: Links to sites with random cat pictures!"""
|
||||
await ctx.message.channel.trigger_typing()
|
||||
|
||||
url = "https://www.google.com/search"
|
||||
|
||||
# Turn safe filter on or off, based on whether or not this is a nsfw channel
|
||||
|
@ -43,7 +45,7 @@ class Links:
|
|||
data = await utils.request(url, payload=params, attr='text')
|
||||
|
||||
if data is None:
|
||||
await self.bot.send_message(ctx.message.channel, "I failed to connect to google! (That can happen??)")
|
||||
await ctx.send("I failed to connect to google! (That can happen??)")
|
||||
return
|
||||
|
||||
# Convert to a BeautifulSoup element and loop through each result clasified by h3 tags with a class of 'r'
|
||||
|
@ -55,7 +57,7 @@ class Links:
|
|||
try:
|
||||
result_url = re.search('(?<=q=).*(?=&sa=)', element.find('a').get('href')).group(0)
|
||||
except AttributeError:
|
||||
await self.bot.say("I couldn't find any results for {}!".format(query))
|
||||
await ctx.send("I couldn't find any results for {}!".format(query))
|
||||
return
|
||||
|
||||
# Get the next sibling, find the span where the description is, and get the text from this
|
||||
|
@ -68,15 +70,17 @@ class Links:
|
|||
fmt += '\n\n**URL**: <{}>\n**Description**: {}'.format(result_url, description)
|
||||
|
||||
fmt = "**Top 3 results for the query** _{}_:{}".format(query, fmt)
|
||||
await self.bot.say(fmt)
|
||||
await ctx.send(fmt)
|
||||
|
||||
@commands.command(aliases=['yt'], pass_context=True)
|
||||
@commands.command(aliases=['yt'])
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def youtube(self, ctx, *, query: str):
|
||||
"""Searches youtube for a provided query
|
||||
|
||||
EXAMPLE: !youtube Cat videos!
|
||||
RESULT: Cat videos!"""
|
||||
await ctx.message.channel.trigger_typing()
|
||||
|
||||
key = utils.youtube_key
|
||||
url = "https://www.googleapis.com/youtube/v3/search"
|
||||
params = {'key': key,
|
||||
|
@ -87,13 +91,13 @@ class Links:
|
|||
data = await utils.request(url, payload=params)
|
||||
|
||||
if data is None:
|
||||
await self.bot.send_message(ctx.message.channel, "Sorry but I failed to connect to youtube!")
|
||||
await ctx.send("Sorry but I failed to connect to youtube!")
|
||||
return
|
||||
|
||||
try:
|
||||
result = data['items'][0]
|
||||
except IndexError:
|
||||
await self.bot.say("I could not find any results with the search term {}".format(query))
|
||||
await ctx.send("I could not find any results with the search term {}".format(query))
|
||||
return
|
||||
|
||||
result_url = "https://youtube.com/watch?v={}".format(result['id']['videoId'])
|
||||
|
@ -101,15 +105,17 @@ class Links:
|
|||
description = result['snippet']['description']
|
||||
|
||||
fmt = "**Title:** {}\n\n**Description:** {}\n\n**URL:** <{}>".format(title, description, result_url)
|
||||
await self.bot.say(fmt)
|
||||
await ctx.send(fmt)
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def wiki(self, ctx, *, query: str):
|
||||
"""Pulls the top match for a specific term from wikipedia, and returns the result
|
||||
|
||||
EXAMPLE: !wiki Test
|
||||
RESULT: A link to the wikipedia article for the word test"""
|
||||
await ctx.message.channel.trigger_typing()
|
||||
|
||||
# All we need to do is search for the term provided, so the action, list, and format never need to change
|
||||
base_url = "https://en.wikipedia.org/w/api.php"
|
||||
params = {"action": "query",
|
||||
|
@ -120,11 +126,11 @@ class Links:
|
|||
data = await utils.request(base_url, payload=params)
|
||||
|
||||
if data is None:
|
||||
await self.bot.send_message(ctx.message.channel, "Sorry but I failed to connect to Wikipedia!")
|
||||
await ctx.send("Sorry but I failed to connect to Wikipedia!")
|
||||
return
|
||||
|
||||
if len(data['query']['search']) == 0:
|
||||
await self.bot.say("I could not find any results with that term, I tried my best :c")
|
||||
await ctx.send("I could not find any results with that term, I tried my best :c")
|
||||
return
|
||||
# Wiki articles' URLs are in the format https://en.wikipedia.org/wiki/[Titlehere]
|
||||
# Replace spaces with %20
|
||||
|
@ -136,36 +142,38 @@ class Links:
|
|||
snippet = re.sub('</span>', '', snippet)
|
||||
snippet = re.sub('"', '"', snippet)
|
||||
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
"Here is the best match I found with the query `{}`:\nURL: <{}>\nSnippet: \n```\n{}```".format(query, url,
|
||||
snippet))
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.command()
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def urban(self, ctx, *, msg: str):
|
||||
"""Pulls the top urbandictionary.com definition for a term
|
||||
|
||||
EXAMPLE: !urban a normal phrase
|
||||
RESULT: Probably something lewd; this is urban dictionary we're talking about"""
|
||||
await ctx.message.channel.trigger_typing()
|
||||
|
||||
url = "http://api.urbandictionary.com/v0/define"
|
||||
params = {"term": msg}
|
||||
try:
|
||||
data = await utils.request(url, payload=params)
|
||||
if data is None:
|
||||
await self.bot.send_message(ctx.message.channel, "Sorry but I failed to connect to urban dictionary!")
|
||||
await ctx.send("Sorry but I failed to connect to urban dictionary!")
|
||||
return
|
||||
|
||||
# List is the list of definitions found, if it's empty then nothing was found
|
||||
if len(data['list']) == 0:
|
||||
await self.bot.say("No result with that term!")
|
||||
await ctx.send("No result with that term!")
|
||||
# If the list is not empty, use the first result and print it's defintion
|
||||
else:
|
||||
await self.bot.say(data['list'][0]['definition'])
|
||||
await ctx.send(data['list'][0]['definition'])
|
||||
# Urban dictionary has some long definitions, some might not be able to be sent
|
||||
except discord.HTTPException:
|
||||
await self.bot.say('```\nError: Definition is too long for me to send```')
|
||||
await ctx.send('```\nError: Definition is too long for me to send```')
|
||||
except KeyError:
|
||||
await self.bot.say("Sorry but I failed to connect to urban dictionary!")
|
||||
await ctx.send("Sorry but I failed to connect to urban dictionary!")
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
|
@ -174,6 +182,8 @@ class Links:
|
|||
|
||||
EXAMPLE: !derpi Rainbow Dash
|
||||
RESULT: A picture of Rainbow Dash!"""
|
||||
await ctx.message.channel.trigger_typing()
|
||||
|
||||
if len(search) > 0:
|
||||
url = 'https://derpibooru.org/search.json'
|
||||
|
||||
|
@ -192,18 +202,16 @@ class Links:
|
|||
else:
|
||||
params['q'] += ", safe"
|
||||
|
||||
await self.bot.say("Looking up an image with those tags....")
|
||||
|
||||
try:
|
||||
# Get the response from derpibooru and parse the 'search' result from it
|
||||
data = await utils.request(url, payload=params)
|
||||
|
||||
if data is None:
|
||||
await self.bot.send_message(ctx.message.channel, "Sorry but I failed to connect to Derpibooru!")
|
||||
await ctx.send("Sorry but I failed to connect to Derpibooru!")
|
||||
return
|
||||
results = data['search']
|
||||
except KeyError:
|
||||
await self.bot.say("No results with that search term, {0}!".format(ctx.message.author.mention))
|
||||
await ctx.send("No results with that search term, {0}!".format(ctx.message.author.mention))
|
||||
return
|
||||
|
||||
# The first request we've made ensures there are results
|
||||
|
@ -215,7 +223,7 @@ class Links:
|
|||
params['page'] = random.SystemRandom().randint(1, pages)
|
||||
data = await utils.request(url, payload=params)
|
||||
if data is None:
|
||||
await self.bot.say("Sorry but I failed to connect to Derpibooru!")
|
||||
await ctx.send("Sorry but I failed to connect to Derpibooru!")
|
||||
return
|
||||
# Now get the results again
|
||||
results = data['search']
|
||||
|
@ -224,14 +232,14 @@ class Links:
|
|||
index = random.SystemRandom().randint(0, len(results) - 1)
|
||||
image_link = 'https://derpibooru.org/{}'.format(results[index]['id'])
|
||||
else:
|
||||
await self.bot.say("No results with that search term, {0}!".format(ctx.message.author.mention))
|
||||
await ctx.send("No results with that search term, {0}!".format(ctx.message.author.mention))
|
||||
return
|
||||
else:
|
||||
# If no search term was provided, search for a random image
|
||||
# .url will be the URL we end up at, not the one requested.
|
||||
# https://derpibooru.org/images/random redirects to a random image, so this is exactly what we want
|
||||
image_link = await utils.request('https://derpibooru.org/images/random', attr='url')
|
||||
await self.bot.say(image_link)
|
||||
await ctx.send(image_link)
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
|
@ -242,19 +250,19 @@ class Links:
|
|||
|
||||
EXAMPLE: !e621 dragon
|
||||
RESULT: A picture of a dragon (hopefully, screw your tagging system e621)"""
|
||||
await ctx.message.channel.trigger_typing()
|
||||
|
||||
|
||||
# This changes the formatting for queries, so we don't
|
||||
# Have to use e621's stupid formatting when using the command
|
||||
|
||||
tags = tags.replace(' ', '_')
|
||||
tags = tags.replace(',_', ' ')
|
||||
|
||||
url = 'https://e621.net/post/index.json'
|
||||
params = {'limit': 320,
|
||||
'tags': tags}
|
||||
# e621 provides a way to change how many images can be shown on one request
|
||||
# This gives more of a chance of random results, however it causes the lookup to take longer than most
|
||||
# Due to this, send a message saying we're looking up the information first
|
||||
await self.bot.say("Looking up an image with those tags....")
|
||||
|
||||
|
||||
r_filter = {'channel_id': ctx.message.channel.id}
|
||||
nsfw_channels = await utils.get_content("nsfw_channels", r_filter)
|
||||
|
@ -266,8 +274,7 @@ class Links:
|
|||
data = await utils.request(url, payload=params)
|
||||
|
||||
if data is None:
|
||||
await self.bot.send_message(ctx.message.channel,
|
||||
"Sorry, I had trouble connecting at the moment; please try again later")
|
||||
await ctx.send("Sorry, I had trouble connecting at the moment; please try again later")
|
||||
return
|
||||
|
||||
# Try to find an image from the list. If there were no results, we're going to attempt to find
|
||||
|
@ -276,9 +283,9 @@ class Links:
|
|||
# i.e. it responded with a 404/504/etc.
|
||||
try:
|
||||
rand_image = data[random.SystemRandom().randint(0, len(data) - 1)]['file_url']
|
||||
await self.bot.say(rand_image)
|
||||
await ctx.send(rand_image)
|
||||
except (ValueError, KeyError):
|
||||
await self.bot.say("No results with that tag {}".format(ctx.message.author.mention))
|
||||
await ctx.send("No results with that tag {}".format(ctx.message.author.mention))
|
||||
return
|
||||
|
||||
|
||||
|
|
215
cogs/mod.py
215
cogs/mod.py
|
@ -16,53 +16,30 @@ class Mod:
|
|||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
def find_command(self, command):
|
||||
# This method ensures the command given is valid. We need to loop through commands
|
||||
# As self.bot.commands only includes parent commands
|
||||
# So we are splitting the command in parts, looping through the commands
|
||||
# And getting the subcommand based on the next part
|
||||
# If we try to access commands of a command that isn't a group
|
||||
# We'll hit an AttributeError, meaning an invalid command was given
|
||||
# If we loop through and don't find anything, cmd will still be None
|
||||
# And we'll report an invalid was given as well
|
||||
cmd = None
|
||||
|
||||
for part in command.split():
|
||||
try:
|
||||
if cmd is None:
|
||||
cmd = self.bot.commands.get(part)
|
||||
else:
|
||||
cmd = cmd.commands.get(part)
|
||||
except AttributeError:
|
||||
cmd = None
|
||||
break
|
||||
|
||||
return cmd
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True, aliases=['nick'])
|
||||
@commands.command(no_pm=True, aliases=['nick'])
|
||||
@utils.custom_perms(kick_members=True)
|
||||
async def nickname(self, ctx, *, name=None):
|
||||
"""Used to set the nickname for Bonfire (provide no nickname and it will reset)
|
||||
|
||||
EXAMPLE: !nick Music Bot
|
||||
RESULT: My nickname is now music bot"""
|
||||
await self.bot.change_nickname(ctx.message.server.me, name)
|
||||
await self.bot.say("\N{OK HAND SIGN}")
|
||||
RESULT: My nickname is now Music Bot"""
|
||||
await ctx.message.server.me.edit(nick=name)
|
||||
await ctx.send("\N{OK HAND SIGN}")
|
||||
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(kick_members=True)
|
||||
async def kick(self, member: discord.Member):
|
||||
async def kick(self, ctx, member: discord.Member):
|
||||
"""Used to kick a member from this server
|
||||
|
||||
EXAMPLE: !kick @Member
|
||||
RESULT: They're kicked from the server?"""
|
||||
try:
|
||||
await self.bot.kick(member)
|
||||
await self.bot.say("\N{OK HAND SIGN}")
|
||||
await member.kick()
|
||||
await ctx.send("\N{OK HAND SIGN}")
|
||||
except discord.Forbidden:
|
||||
await self.bot.say("But I can't, muh permissions >:c")
|
||||
await ctx.send("But I can't, muh permissions >:c")
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(ban_members=True)
|
||||
async def unban(self, ctx, member_id: int):
|
||||
"""Used to unban a member from this server
|
||||
|
@ -74,16 +51,15 @@ class Mod:
|
|||
|
||||
# Lets only accept an int for this method, in order to ensure only an ID is provided
|
||||
# Due to that though, we need to ensure a string is passed as the member's ID
|
||||
member = discord.Object(id=str(member_id))
|
||||
try:
|
||||
await self.bot.unban(ctx.message.server, member)
|
||||
await self.bot.say("\N{OK HAND SIGN}")
|
||||
await discord.http.unban(member.id, ctx.guild.id)
|
||||
await ctx.send("\N{OK HAND SIGN}")
|
||||
except discord.Forbidden:
|
||||
await self.bot.say("But I can't, muh permissions >:c")
|
||||
await ctx.send("But I can't, muh permissions >:c")
|
||||
except discord.HTTPException:
|
||||
await self.bot.say("Sorry, I failed to unban that user!")
|
||||
await ctx.send("Sorry, I failed to unban that user!")
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(ban_members=True)
|
||||
async def ban(self, ctx, *, member):
|
||||
"""Used to ban a member
|
||||
|
@ -95,31 +71,35 @@ class Mod:
|
|||
|
||||
# Lets first check if a user ID was provided, as that will be the easiest case to ban
|
||||
if member.isdigit():
|
||||
# First convert it to a discord object based on the ID that was given
|
||||
member = discord.Object(id=member)
|
||||
# Next, to ban from the server the API takes a server obejct and uses that ID
|
||||
# So set "this" server as the member's server. This creates the "fake" member we need
|
||||
member.server = ctx.message.server
|
||||
try:
|
||||
await discord.http.ban(member, ctx.guild.id)
|
||||
await ctx.send("\N{OK HAND SIGN}")
|
||||
except discord.Forbidden:
|
||||
await ctx.send("But I can't, muh permissions >:c")
|
||||
except discord.HTTPException:
|
||||
await ctx.send("Sorry, I failed to ban that user!")
|
||||
finally:
|
||||
return
|
||||
else:
|
||||
# If no ID was provided, lets try to convert what was given using the internal coverter
|
||||
converter = commands.converter.UserConverter(ctx, member)
|
||||
converter = commands.converter.MemberConverter(ctx, member)
|
||||
try:
|
||||
member = converter.convert()
|
||||
except commands.converter.BadArgument:
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
'{} does not appear to be a valid member. If this member is not in this server, please provide '
|
||||
'their ID'.format(member))
|
||||
return
|
||||
# Now lets try actually banning the member we've been given
|
||||
try:
|
||||
await self.bot.ban(member)
|
||||
await self.bot.say("\N{OK HAND SIGN}")
|
||||
await member.ban()
|
||||
await ctx.send("\N{OK HAND SIGN}")
|
||||
except discord.Forbidden:
|
||||
await self.bot.say("But I can't, muh permissions >:c")
|
||||
await ctx.send("But I can't, muh permissions >:c")
|
||||
except discord.HTTPException:
|
||||
await self.bot.say("Sorry, I failed to ban that user!")
|
||||
await ctx.send("Sorry, I failed to ban that user!")
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(kick_members=True)
|
||||
async def alerts(self, ctx, channel: discord.Channel):
|
||||
"""This command is used to set a channel as the server's 'notifications' channel
|
||||
|
@ -132,10 +112,10 @@ class Mod:
|
|||
'channel_id': channel.id}
|
||||
if not await utils.add_content('server_alerts', entry, r_filter):
|
||||
await utils.update_content('server_alerts', entry, r_filter)
|
||||
await self.bot.say("I have just changed this server's 'notifications' channel"
|
||||
await ctx.send("I have just changed this server's 'notifications' channel"
|
||||
"\nAll notifications will now go to `{}`".format(channel))
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(kick_members=True)
|
||||
async def usernotify(self, ctx, on_off: str):
|
||||
"""This command can be used to set whether or not you want user notificaitons to show
|
||||
|
@ -148,22 +128,21 @@ class Mod:
|
|||
# So we base this channel on it's own and not from alerts
|
||||
# When mod logging becomes available, that will be kept to it's own channel if wanted as well
|
||||
on_off = ctx.message.channel.id if re.search("(on|yes|true)", on_off.lower()) else None
|
||||
r_filter = {'server_id': ctx.message.server.id}
|
||||
entry = {'server_id': ctx.message.server.id,
|
||||
r_filter = {'server_id': ctx.message.guild.id}
|
||||
entry = {'server_id': ctx.message.guild.id,
|
||||
'channel_id': on_off}
|
||||
if not await utils.add_content('user_notifications', entry, r_filter):
|
||||
await utils.update_content('user_notifications', entry, r_filter)
|
||||
fmt = "notify" if on_off else "not notify"
|
||||
await self.bot.say("This server will now {} if someone has joined or left".format(fmt))
|
||||
await ctx.send("This server will now {} if someone has joined or left".format(fmt))
|
||||
|
||||
@commands.group(pass_context=True)
|
||||
@commands.group()
|
||||
async def nsfw(self, ctx):
|
||||
"""Handles adding or removing a channel as a nsfw channel"""
|
||||
# This command isn't meant to do anything, so just send an error if an invalid subcommand is passed
|
||||
if ctx.invoked_subcommand is None:
|
||||
await self.bot.say('Invalid subcommand passed: {0.subcommand_passed}'.format(ctx))
|
||||
pass
|
||||
|
||||
@nsfw.command(name="add", pass_context=True)
|
||||
@nsfw.command(name="add")
|
||||
@utils.custom_perms(kick_members=True)
|
||||
async def nsfw_add(self, ctx):
|
||||
"""Registers this channel as a 'nsfw' channel
|
||||
|
@ -172,11 +151,11 @@ class Mod:
|
|||
RESULT: ;)"""
|
||||
r_filter = {'channel_id': ctx.message.channel.id}
|
||||
if await utils.add_content('nsfw_channels', r_filter, r_filter):
|
||||
await self.bot.say("This channel has just been registered as 'nsfw'! Have fun you naughties ;)")
|
||||
await ctx.send("This channel has just been registered as 'nsfw'! Have fun you naughties ;)")
|
||||
else:
|
||||
await self.bot.say("This channel is already registered as 'nsfw'!")
|
||||
await ctx.send("This channel is already registered as 'nsfw'!")
|
||||
|
||||
@nsfw.command(name="remove", aliases=["delete"], pass_context=True)
|
||||
@nsfw.command(name="remove", aliases=["delete"])
|
||||
@utils.custom_perms(kick_members=True)
|
||||
async def nsfw_remove(self, ctx):
|
||||
"""Removes this channel as a 'nsfw' channel
|
||||
|
@ -185,11 +164,11 @@ class Mod:
|
|||
RESULT: ;("""
|
||||
r_filter = {'channel_id': ctx.message.channel.id}
|
||||
if await utils.remove_content('nsfw_channels', r_filter):
|
||||
await self.bot.say("This channel has just been unregistered as a nsfw channel")
|
||||
await ctx.send("This channel has just been unregistered as a nsfw channel")
|
||||
else:
|
||||
await self.bot.say("This channel is not registered as a ''nsfw' channel!")
|
||||
await ctx.send("This channel is not registered as a ''nsfw' channel!")
|
||||
|
||||
@commands.command(pass_context=True)
|
||||
@commands.command()
|
||||
@utils.custom_perms(kick_members=True)
|
||||
async def say(self, ctx, *, msg: str):
|
||||
"""Tells the bot to repeat what you say
|
||||
|
@ -197,13 +176,13 @@ class Mod:
|
|||
EXAMPLE: !say I really like orange juice
|
||||
RESULT: I really like orange juice"""
|
||||
fmt = "\u200B{}".format(msg)
|
||||
await self.bot.say(fmt)
|
||||
await ctx.send(fmt)
|
||||
try:
|
||||
await self.bot.delete_message(ctx.message)
|
||||
await ctx.message.delete()
|
||||
except:
|
||||
pass
|
||||
|
||||
@commands.group(pass_context=True, invoke_without_command=True, no_pm=True)
|
||||
@commands.group(invoke_without_command=True, no_pm=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def perms(self, ctx, *, command: str = None):
|
||||
"""This command can be used to print the current allowed permissions on a specific command
|
||||
|
@ -212,20 +191,20 @@ class Mod:
|
|||
EXAMPLE: !perms help RESULT: Hopefully a result saying you just need send_messages permissions; otherwise lol
|
||||
this server's admin doesn't like me """
|
||||
if command is None:
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
"Valid permissions are: ```\n{}```".format("\n".join("{}".format(i) for i in valid_perms)))
|
||||
return
|
||||
|
||||
r_filter = {'server_id': ctx.message.server.id}
|
||||
r_filter = {'server_id': ctx.message.guild.id}
|
||||
server_perms = await utils.get_content('custom_permissions', r_filter)
|
||||
try:
|
||||
server_perms = server_perms[0]
|
||||
except TypeError:
|
||||
server_perms = {}
|
||||
cmd = self.find_command(command)
|
||||
cmd = self.bot.get_command(command)
|
||||
|
||||
if cmd is None:
|
||||
await self.bot.say("That is not a valid command!")
|
||||
await ctx.send("That is not a valid command!")
|
||||
return
|
||||
|
||||
perms_value = server_perms.get(cmd.qualified_name)
|
||||
|
@ -240,15 +219,15 @@ class Mod:
|
|||
# Able to manage the server (for the utils on perm commands)
|
||||
for func in cmd.utils:
|
||||
if "is_owner" in func.__qualname__:
|
||||
await self.bot.say("You need to own the bot to run this command")
|
||||
await ctx.send("You need to own the bot to run this command")
|
||||
return
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
"You are required to have `manage_server` permissions to run `{}`".format(cmd.qualified_name))
|
||||
return
|
||||
|
||||
# Perms will be an attribute if custom_perms is found no matter what, so no need to check this
|
||||
perms = "\n".join(attribute for attribute, setting in custom_perms.perms.items() if setting)
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
"You are required to have `{}` permissions to run `{}`".format(perms, cmd.qualified_name))
|
||||
else:
|
||||
# Permissions are saved as bit values, so create an object based on that value
|
||||
|
@ -256,10 +235,10 @@ class Mod:
|
|||
# There's no need to check for errors here, as we ensure a permission is valid when adding it
|
||||
permissions = discord.Permissions(perms_value)
|
||||
needed_perm = [perm[0] for perm in permissions if perm[1]][0]
|
||||
await self.bot.say("You need to have the permission `{}` "
|
||||
await ctx.send("You need to have the permission `{}` "
|
||||
"to use the command `{}` in this server".format(needed_perm, command))
|
||||
|
||||
@perms.command(name="add", aliases=["setup,create"], pass_context=True, no_pm=True)
|
||||
@perms.command(name="add", aliases=["setup,create"], no_pm=True)
|
||||
@commands.has_permissions(manage_server=True)
|
||||
async def add_perms(self, ctx, *msg: str):
|
||||
"""Sets up custom permissions on the provided command
|
||||
|
@ -274,7 +253,7 @@ class Mod:
|
|||
try:
|
||||
permissions = msg[len(msg) - 1]
|
||||
except IndexError:
|
||||
await self.bot.say("Please provide the permissions you want to setup, the format for this must be in:\n"
|
||||
await ctx.send("Please provide the permissions you want to setup, the format for this must be in:\n"
|
||||
"`perms add <command> <permission>`")
|
||||
return
|
||||
|
||||
|
@ -288,15 +267,15 @@ class Mod:
|
|||
try:
|
||||
setattr(perm_obj, permissions, True)
|
||||
except AttributeError:
|
||||
await self.bot.say("{} does not appear to be a valid permission! Valid permissions are: ```\n{}```"
|
||||
await ctx.send("{} does not appear to be a valid permission! Valid permissions are: ```\n{}```"
|
||||
.format(permissions, "\n".join(valid_perms)))
|
||||
return
|
||||
perm_value = perm_obj.value
|
||||
|
||||
cmd = self.find_command(command)
|
||||
cmd = self.bot.get_command(command)
|
||||
|
||||
if cmd is None:
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
"That command does not exist! You can't have custom permissions on a non-existant command....")
|
||||
return
|
||||
|
||||
|
@ -305,12 +284,12 @@ class Mod:
|
|||
# Which means I do not want to check custom permissions at all
|
||||
# Currently the second case is only on adding and removing permissions, to avoid abuse on these
|
||||
for check in cmd.checks:
|
||||
if "is_owner" == check.__name__ or re.search("has_permissions", str(check)) is not None:
|
||||
await self.bot.say("This command cannot have custom permissions setup!")
|
||||
if "is_owner" == check.__name__ or "has_permissions" not in str(check):
|
||||
await ctx.send("This command cannot have custom permissions setup!")
|
||||
return
|
||||
|
||||
r_filter = {'server_id': ctx.message.server.id}
|
||||
entry = {'server_id': ctx.message.server.id,
|
||||
r_filter = {'server_id': ctx.message.guild.id}
|
||||
entry = {'server_id': ctx.message.guild.id,
|
||||
cmd.qualified_name: perm_value}
|
||||
|
||||
# In all other cases, I've used add_content before update_content
|
||||
|
@ -322,10 +301,10 @@ class Mod:
|
|||
|
||||
# Same case as prefixes, for now, trigger a manual update
|
||||
self.bot.loop.create_task(utils.cache['custom_permissions'].update())
|
||||
await self.bot.say("I have just added your custom permissions; "
|
||||
await ctx.send("I have just added your custom permissions; "
|
||||
"you now need to have `{}` permissions to use the command `{}`".format(permissions, command))
|
||||
|
||||
@perms.command(name="remove", aliases=["delete"], pass_context=True, no_pm=True)
|
||||
@perms.command(name="remove", aliases=["delete"], no_pm=True)
|
||||
@commands.has_permissions(manage_server=True)
|
||||
async def remove_perms(self, ctx, *, command: str):
|
||||
"""Removes the custom permissions setup on the command specified
|
||||
|
@ -333,32 +312,32 @@ class Mod:
|
|||
EXAMPLE: !perms remove play
|
||||
RESULT: Freedom!"""
|
||||
|
||||
cmd = self.find_command(command)
|
||||
cmd = self.bot.get_command(command)
|
||||
|
||||
if cmd is None:
|
||||
await self.bot.say(
|
||||
await ctx.send(
|
||||
"That command does not exist! You can't have custom permissions on a non-existant command....")
|
||||
return
|
||||
|
||||
r_filter = {'server_id': ctx.message.server.id}
|
||||
await utils.replace_content('custom_permissions', r.row.without(cmd.qualified_name), r_filter)
|
||||
await self.bot.say("I have just removed the custom permissions for {}!".format(cmd))
|
||||
await ctx.send("I have just removed the custom permissions for {}!".format(cmd))
|
||||
|
||||
# Same case as prefixes, for now, trigger a manual update
|
||||
self.bot.loop.create_task(utils.cache['custom_permissions'].update())
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@utils.custom_perms(manage_server=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(manage_guild=True)
|
||||
async def prefix(self, ctx, *, prefix: str):
|
||||
"""This command can be used to set a custom prefix per server
|
||||
|
||||
EXAMPLE: !prefix new_prefix
|
||||
RESULT: You probably screwing it up and not realizing you now need to do new_prefixprefix"""
|
||||
r_filter = {'server_id': ctx.message.server.id}
|
||||
r_filter = {'server_id': ctx.message.guild.id}
|
||||
if prefix.lower().strip() == "none":
|
||||
prefix = None
|
||||
|
||||
entry = {'server_id': ctx.message.server.id,
|
||||
entry = {'server_id': ctx.message.guild.id,
|
||||
'prefix': prefix}
|
||||
|
||||
if not await utils.add_content('prefixes', entry, r_filter):
|
||||
|
@ -369,9 +348,9 @@ class Mod:
|
|||
else:
|
||||
fmt = "I have just updated the prefix for this server; you now need to call commands with `{0}`. " \
|
||||
"For example, you can call this command again with {0}prefix".format(prefix)
|
||||
await self.bot.say(fmt)
|
||||
await ctx.send(fmt)
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(manage_messages=True)
|
||||
async def purge(self, ctx, limit: int = 100):
|
||||
"""This command is used to a purge a number of messages from the channel
|
||||
|
@ -379,15 +358,15 @@ class Mod:
|
|||
EXAMPLE: !purge 50
|
||||
RESULT: -50 messages in this channel"""
|
||||
if not ctx.message.channel.permissions_for(ctx.message.server.me).manage_messages:
|
||||
await self.bot.say("I do not have permission to delete messages...")
|
||||
await ctx.send("I do not have permission to delete messages...")
|
||||
return
|
||||
try:
|
||||
await self.bot.purge_from(ctx.message.channel, limit=limit)
|
||||
await ctx.message.channel.purge(limit=limit)
|
||||
except discord.HTTPException:
|
||||
await self.bot.send_message(ctx.message.channel, "Detected messages that are too far back for me to delete;" \
|
||||
" I can only bulk delete messages that are under 14 days old.")
|
||||
|
||||
@commands.command(pass_context=True, no_pm=True)
|
||||
@commands.command(no_pm=True)
|
||||
@utils.custom_perms(manage_messages=True)
|
||||
async def prune(self, ctx, limit: int = 100):
|
||||
"""This command can be used to prune messages from certain members
|
||||
|
@ -403,48 +382,48 @@ class Mod:
|
|||
# If no members are provided, assume we're trying to prune our own messages
|
||||
members = ctx.message.mentions
|
||||
if len(members) == 0:
|
||||
members = [ctx.message.server.me]
|
||||
members = [ctx.message.guild.me]
|
||||
# If we're not setting the user to the bot, then we're deleting someone elses messages
|
||||
# To do so, we need manage_messages permission, so check if we have that
|
||||
elif not ctx.message.channel.permissions_for(ctx.message.server.me).manage_messages:
|
||||
await self.bot.say("I do not have permission to delete messages...")
|
||||
await ctx.send("I do not have permission to delete messages...")
|
||||
return
|
||||
|
||||
# Since logs_from will give us any message, not just the user's we need
|
||||
# We'll increment count, and stop deleting messages if we hit the limit.
|
||||
count = 0
|
||||
async for msg in self.bot.logs_from(ctx.message.channel):
|
||||
async for msg in ctx.message.channel.history:
|
||||
if msg.author in members:
|
||||
try:
|
||||
await self.bot.delete_message(msg)
|
||||
await msg.delete()
|
||||
count += 1
|
||||
except discord.NotFound:
|
||||
pass
|
||||
if count >= limit:
|
||||
break
|
||||
msg = await self.bot.say("{} messages succesfully deleted".format(count))
|
||||
await asyncio.sleep(60)
|
||||
msg = await ctx.send("{} messages succesfully deleted".format(count))
|
||||
await asyncio.sleep(5)
|
||||
try:
|
||||
await self.bot.delete_message(msg)
|
||||
await msg.delete()
|
||||
except discord.NotFound:
|
||||
pass
|
||||
|
||||
@commands.group(aliases=['rule'], pass_context=True, no_pm=True, invoke_without_command=True)
|
||||
@commands.group(aliases=['rule'], no_pm=True, invoke_without_command=True)
|
||||
@utils.custom_perms(send_messages=True)
|
||||
async def rules(self, ctx, rule: int = None):
|
||||
"""This command can be used to view the current rules on the server
|
||||
|
||||
EXAMPLE: !rules 5
|
||||
RESULT: Rule 5 is printed"""
|
||||
r_filter = {'server_id': ctx.message.server.id}
|
||||
r_filter = {'server_id': ctx.message.guild.id}
|
||||
rules = await utils.get_content('rules', r_filter)
|
||||
try:
|
||||
rules = rules[0]['rules']
|
||||
except TypeError:
|
||||
await self.bot.say("This server currently has no rules on it! I see you like to live dangerously...")
|
||||
await ctx.send("This server currently has no rules on it! I see you like to live dangerously...")
|
||||
return
|
||||
if len(rules) == 0:
|
||||
await self.bot.say("This server currently has no rules on it! I see you like to live dangerously...")
|
||||
await ctx.send("This server currently has no rules on it! I see you like to live dangerously...")
|
||||
return
|
||||
|
||||
if rule is None:
|
||||
|
@ -453,16 +432,16 @@ class Mod:
|
|||
pages.title = "Rules for {}".format(ctx.message.server.name)
|
||||
await pages.paginate()
|
||||
except utils.CannotPaginate as e:
|
||||
await self.bot.say(str(e))
|
||||
await ctx.send(str(e))
|
||||
else:
|
||||
try:
|
||||
fmt = rules[rule - 1]
|
||||
except IndexError:
|
||||
await self.bot.say("That rules does not exist.")
|
||||
await ctx.send("That rules does not exist.")
|
||||
return
|
||||
await self.bot.say("Rule {}: \"{}\"".format(rule, fmt))
|
||||
await ctx.send("Rule {}: \"{}\"".format(rule, fmt))
|
||||
|
||||
@rules.command(name='add', aliases=['create'], pass_context=True, no_pm=True)
|
||||
@rules.command(name='add', aliases=['create'], no_pm=True)
|
||||
@utils.custom_perms(manage_server=True)
|
||||
async def rules_add(self, ctx, *, rule: str):
|
||||
"""Adds a rule to this server's rules
|
||||
|
@ -476,9 +455,9 @@ class Mod:
|
|||
if not await utils.update_content('rules', update, r_filter):
|
||||
await utils.add_content('rules', entry, r_filter)
|
||||
|
||||
await self.bot.say("I have just saved your new rule, use the rules command to view this server's current rules")
|
||||
await ctx.send("I have just saved your new rule, use the rules command to view this server's current rules")
|
||||
|
||||
@rules.command(name='remove', aliases=['delete'], pass_context=True, no_pm=True)
|
||||
@rules.command(name='remove', aliases=['delete'], no_pm=True)
|
||||
@utils.custom_perms(manage_server=True)
|
||||
async def rules_delete(self, ctx, rule: int):
|
||||
"""Removes one of the rules from the list of this server's rules
|
||||
|
@ -489,9 +468,9 @@ class Mod:
|
|||
r_filter = {'server_id': ctx.message.server.id}
|
||||
update = {'rules': r.row['rules'].delete_at(rule - 1)}
|
||||
if not await utils.update_content('rules', update, r_filter):
|
||||
await self.bot.say("That is not a valid rule number, try running the command again.")
|
||||
await ctx.send("That is not a valid rule number, try running the command again.")
|
||||
else:
|
||||
await self.bot.say("I have just removed that rule from your list of rules!")
|
||||
await ctx.send("I have just removed that rule from your list of rules!")
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
|
Loading…
Reference in a new issue