async def next_turn(self): if not self.turns: self.rounds -= 1 if not self.rounds: self.queue.put_nowait( TabooMsg(TabooMsg.Type.game_over) ) else: self.turns = self.players[:] if self.rounds: self.current_card = self.cards.pop() self.giver = self.turns.pop(0) description = 'Is Team\'s {} turn.'.format( 'A' if self.giver in self.team_a else 'B' ) description += "\n<@{}> is the **giver**.".format(self.giver) await self.bot.send_message( self.channel, embed=utils.get_embed( description, title='Time\'s over' ) ) await self.dm_current_card() await self.bot.send_message( self.channel, utils.get_embed( "The card was\n" + self.format_card(self.current_card) ) )
async def dm_current_card(self): if not self.current_card or not self.giver: return card = self.format_card(self.current_card) giver = self.get_player(self.giver) team = self.team_a if self.giver not in self.team_a else self.team_b await self.bot.send_message( giver, "You're the *giver*. Try to make your team guess the word." ) await self.bot.send_message( giver, embed=utils.get_embed(card) ) for player in team: member = self.get_player(player) await self.bot.send_message( member, "The card is." ) await self.bot.send_message( member, embed=utils.get_embed(card) )
async def delete_card(self, context, *args): """ Removes a card from the database. Usage: \taboo delcard <card_name> """ if len(args) < 1: await self.bot.say("No arguments passed.") else: card = args[0].upper().strip() server_id = context.message.server.id server_db = utils.get_dir() + 'db/{}.db'.format(server_id) connection = sqlite3.connect(server_db) cursor = connection.cursor() cursor.execute("SELECT TABOO FROM CARDS WHERE CARD LIKE '{}'".format(card)) taboo_ = cursor.fetchone() taboo_ = taboo_[0] if taboo_ else None if taboo_ is not None: cursor.execute("DELETE FROM CARDS WHERE CARD LIKE '{}'".format(card)) await self.bot.say(embed=utils.get_embed( TabooGame.format_card((card, taboo_)), 'Card deleted.' )) else: await self.bot.say(embed=utils.get_embed( "The card {} does not exists in the database.".format(card) )) cursor.close() connection.commit() connection.close()
async def load_extension(ext_name: str): """ Loads an extension. Bot owner only. """ if not os.path.exists('gally/extensions/{}/ext.py'.format(ext_name)): await bot.say(embed=utils.get_embed( "The extension '{}' could not be loaded `ext.py` does not exists.". format(ext_name))) return if os.path.exists('gally/extensions/{}/requirements.txt'.format(ext_name)): pip.main([ 'install', '-r', 'gally/extensions/{}/requirements.txt'.format(ext_name) ]) ext_path = 'gally.extensions.{}.ext'.format(ext_name) bot_db = utils.get_dir() + 'bot.db' connection = sqlite3.connect(bot_db) connection.execute( "REPLACE INTO EXTENSIONS(NAME) VALUES('{}')".format(ext_name)) connection.commit() connection.close() bot.load_extension(ext_path) await bot.say( embed=utils.get_embed("Extension `{}` loaded".format(ext_name)))
async def remove_admin(context): """ Remove a bot administrator. Admins only. Usage: \removeadmin <@user> """ mentions = context.message.mentions server_id = context.message.server.id if not len(mentions): await bot.say('No arguments passed after the command') return admins = utils.get_admins(server_id) server_db = utils.get_dir() + 'db/{}.db'.format(server_id) connection = sqlite3.connect(server_db) cursor = connection.cursor() for mention in mentions: if mention.id not in admins: bot.say(embed=utils.get_embed("{} was not an admin.".format( mention.mention))) else: cursor.execute("DELETE FROM ADMINS WHERE ID LIKE '{}'".format( mention.id)) await bot.say(embed=utils.get_embed( "{} was removed from the admin list".format(mention.mention))) cursor.close() connection.commit() connection.close()
async def list_loaded_extensions(): """ Lists all the loaded extensions. Bot owner only """ extensions_ = bot.extensions if not extensions_: await bot.say(embed=utils.get_embed('There are not extensions loaded')) return message = '' for i, extension in enumerate(extensions_): message += '{}. {}\n'.format(i + 1, extension) await bot.say(embed=utils.get_embed(message, title='Extensions'))
async def delete(self, context, number): """ Deletes a quote from the database. Admins only Usage: \\q[uote] del <quote number> """ if not utils.is_number(number): await self.bot.say("No number passed as argument") return number = int(number) server_db = utils.get_db(context.message.server.id) connection = sqlite3.connect(server_db) cursor = connection.cursor() cursor.execute("SELECT * FROM QUOTES WHERE ROWID={}".format(number)) quote = cursor.fetchone() if quote: cursor.execute("DELETE FROM QUOTES WHERE ROWID={}".format(number)) await self.bot.say(embed=utils.get_embed('Quote deleted')) else: await self.bot.say( "There is no quote with the number {}".format(number)) cursor.close() connection.commit() connection.close()
async def list_conf(context): """ List the bot settings. Admins only. Usage: \listconf """ server_db = utils.get_dir() + 'db/{}.db'.format(context.message.server.id) connection = sqlite3.connect(server_db) cursor = connection.cursor() cursor.execute("SELECT * FROM SETTINGS") settings = cursor.fetchall() message = '```' for setting, value in settings: message += '\n{:<20} - {:<20}'.format(setting, value) message += '\n```' await bot.say(embed=utils.get_embed(message, 'Configuration')) cursor.close() connection.close()
async def set_timer(self, context, *args): """ Sets the durations per turn in seconds. Admins only. Usage: \taboo settime <seconds> """ server_id = context.message.server.id if not len(args): await self.bot.say("No arguments were passed to the command.") return if not utils.is_number(args[0]): await self.bot.say("Argument must be a number.") return if int(args[0]) < 60: await self.bot.say("Turns must be at least 60 seconds long.") return utils.set_setting(server_id, 'TABOO_SECONDS', args[0]) await self.bot.say(embed=utils.get_embed( "Setting updated. A turn will finish after {} seconds.".format(args[0]) ))
async def join(self, context): """ Adds you to the game. Usage: \taboo join """ server_id = context.message.server.id author = context.message.author if server_id not in self.games: await self.bot.say("There's not game currently taking place") return taboo_game = self.games[server_id] if taboo_game.playing: await self.bot.say("Can't add a player when a game is taking place.") return if author.id in taboo_game.players: await self.bot.say("{} you're already in the game dummy.".format( context.message.author.mention )) return taboo_game.add_player(author.id) await self.bot.say(embed=utils.get_embed( "{} was added to the game.\nThere are currently {} players in the game".format( author.mention, len(taboo_game.players) ) ))
async def set_rounds(self, context, *args): """ Sets the number of rounds per game. Admins only. Usage: \taboo setrounds <rounds> """ server_id = context.message.server.id if not len(args): await self.bot.say("No arguments were passed to the command.") return if not utils.is_number(args[0]): await self.bot.say("Argument must be a number.") return if len(args[0]) > 3: await self.bot.say("Number must be lower than 999.") if int(args[0]) < 1: await self.bot.say("You need at lest 1 round to play the game.") return utils.set_setting(server_id, 'TABOO_ROUNDS', args[0]) await self.bot.say(embed=utils.get_embed( "Setting updated. A game will finish after {} rounds.".format(args[0]) ))
async def leave(self, context): """ Removes you from the game. Usage: \taboo leave """ server_id = context.message.server.id author = context.message.author if server_id not in self.games: await self.bot.say("There's not game currently taking place.") return taboo_game = self.games[server_id] if taboo_game.playing: await self.bot.say("Can't remove a player when a game is taking place.") return if author.id not in taboo_game.players: await self.bot.say("You're not in the game dummy.".format( context.message.author.mention )) return taboo_game.remove_player(author.id) await self.bot.say(embed=utils.get_embed( "{} left the game :cry:\nThere are currently {} players in the game".format( author.mention, len(taboo_game.players) ) ))
async def add_card(self, context, *args): """ Add a new card to the database. Usage: \taboo addcard <card_name> <taboo1> <taboo2> <taboo3> <taboo4> ... """ if len(args) == 0: await self.bot.say("No arguments passed.") elif len(args) < 5: await self.bot.say("You need at least 4 taboo words to add a new card.") else: card = args[0].upper().strip() taboo_ = [str(word).upper().strip() for word in args[1:]] server_id = context.message.server.id server_db = utils.get_dir() + 'db/{}.db'.format(server_id) connection = sqlite3.connect(server_db) cursor = connection.cursor() cursor.execute("SELECT CARD FROM CARDS WHERE CARD LIKE '{}'".format(card)) if cursor.fetchone() is not None: await self.bot.say("The card {} already exists in the database".format(card)) else: cursor.execute( "INSERT INTO CARDS VALUES(?, ?)", (card, '|'.join(taboo_))) await self.bot.say(embed=utils.get_embed( TabooGame.format_card((card, '|'.join(taboo_))), "Card added." )) cursor.close() connection.commit() connection.close()
async def replace_card(self, context, *args): """ Replace all the taboo words of a card. If the card does not exists it is added to the database instead. Usage: \taboo replcard <card_name> <taboo1> <taboo2> <taboo3> <taboo4> """ if len(args) == 0: await self.bot.say("No arguments passed.") elif len(args) < 5: await self.bot.say("You need at least 4 taboo words to add a new card.") else: card = args[0].upper().strip() taboo_ = [word.upper().strip() for word in args[1:]] server_id = context.message.server.id server_db = utils.get_dir() + 'db/{}.db'.format(server_id) connection = sqlite3.connect(server_db) cursor = connection.cursor() cursor.execute( "REPLACE INTO CARDS(CARD, TABOO) values(?, ?)", (card, '|'.join(taboo_))) await self.bot.say(embed=utils.get_embed( TabooGame.format_card((card, '|'.join(taboo_))), 'Card replaced.' )) cursor.close() connection.commit() connection.close()
async def list_available_extension(): """ List all the available extensions. Bot owner only. """ extensions = '' i = 1 for path in os.listdir('gally/extensions'): if os.path.isdir('gally/extensions/' + path): if os.path.exists('gally/extensions/' + path + '/ext.py'): extensions += '\n{}. {}'.format(i, path) i += 1 await bot.say(embed=utils.get_embed(extensions, 'Available extensions'))
async def reload_extension(ext_name): """ Realoads an extension. Bot owner only. """ if not os.path.exists('gally/extensions/{}/ext.py'.format(ext_name)): await bot.say(embed=utils.get_embed( "The extension '{}' could not be loaded `ext.py` does not exists.". format(ext_name))) return if os.path.exists('gally/extensions/{}/requirements.txt'.format(ext_name)): pip.main([ 'install', '-r', 'gally/extensions/{}/requirements.txt'.format(ext_name) ]) ext_path = 'gally.extensions.{}.ext'.format(ext_name) bot.unload_extension(ext_path) bot.load_extension(ext_path) await bot.say( embed=utils.get_embed("Extension `{}` reloaded".format(ext_name)))
async def unload_extension(ext_name): """ Unloads and extension. Bot owner only. """ if not os.path.exists('gally/extensions/{}/ext.py'.format(ext_name)): await bot.say(embed=utils.get_embed( "The extension '{}' could not be loaded `ext.py` does not exists.". format(ext_name))) return ext_path = 'gally.extensions.{}.ext'.format(ext_name) bot_db = utils.get_dir() + 'bot.db' connection = sqlite3.connect(bot_db) connection.execute( "DELETE FROM EXTENSIONS WHERE NAME LIKE '{}'".format(ext_name)) connection.commit() connection.close() bot.unload_extension(ext_path) await bot.say( embed=utils.get_embed("Extension `{}` unloaded".format(ext_name)))
async def list_admins(context): """ List all the bot's administrators. Admins only. Usage: \listadmins """ admins = utils.get_admins(context.message.server.id) message = '' for i, admin in enumerate(admins): message += "{}. <@{}>\n".format(i + 1, admin) await bot.say(embed=utils.get_embed(message, 'Admins'))
async def set_channel(self, context): """ Sets the channel to be used for the game. Admins only. Usage: \taboo setchannel <#channel> """ server_id = context.message.server.id channel_mentions = context.message.channel_mentions if not len(channel_mentions): await self.bot.say("No channel passed as argument.") return utils.set_setting(server_id, 'TABOO_CHANNEL', channel_mentions[0].id) await self.bot.say(embed=utils.get_embed( "The bot will listen to the channel {} when playing taboo.".format( channel_mentions[0].mention ) ))
async def guess(self, word, author_id): if author_id == self.giver: return team = self.team_a if self.giver in self.team_a else self.team_b if author_id not in team: return word = word.upper().strip() if editdistance.eval(word, self.current_card[0]) < 2: await self.bot.send_message( self.channel, embed=utils.get_embed( 'The word was **{}**'.format(self.current_card[0]), title='Correct' ) ) self.current_card = self.cards.pop() self.score() await self.dm_current_card()
async def skip_card(self): await self.bot.send_message( self.channel, embed=utils.get_embed(self.format_card(self.current_card), 'Card skipped') ) self.score(True) self.current_card = self.cards.pop()
async def game_loop(self): inactive_time = 0.0 time = 0.0 minutes = 5 await self.bot.send_message( self.channel, embed=utils.get_embed("New game created.\nType `\\taboo join` to enter the game") ) while True: await asyncio.sleep(0.01) time += 0.01 message = self.queue.get_nowait() if not self.queue.empty() else TabooMsg() # Quit game if message.type == TabooMsg.Type.stop: await self.bot.send_message( self.channel, embed=utils.get_embed('Game cancelled.') ) break # Start game if message.type == TabooMsg.Type.start: if len(self.players) < 4: await self.bot.send_message( self.channel, embed=utils.get_embed('You need at least 4 players to start a new game.') ) self.send_message(TabooMsg.Type.stop) continue random.shuffle(self.cards) self.current_card = self.cards.pop() random.shuffle(self.players) for i, player in enumerate(self.players): if i % 2 == 0: self.team_a.append(player) else: self.team_b.append(player) self.turns = self.players[:] self.giver = self.turns.pop(0) await self.dm_current_card() description = 'Is Team\'s {} turn.'.format( 'A' if self.giver in self.team_a else 'B' ) description += "\n<@{}> is the **giver**.".format(self.giver) embed = Embed(description=description, title='Game has started', color=Color.magenta()) embed.add_field(name='Team A', value=self.get_team('a')) embed.add_field(name='Team B', value=self.get_team('b')) await self.bot.send_message( self.channel, embed=embed ) self.playing = True continue if not self.playing: if time > 60: time = 0 minutes -= 1 if minutes: await self.bot.send_message( self.channel, embed=utils.get_embed( "{} minutes before the game starts.".format(minutes) ) ) else: self.queue.put_nowait(TabooMsg(TabooMsg.Type.start)) else: # # Inactive time # if message.type == TabooMsg.Type.none: # inactive_time += 0.01 # if inactive_time > self.seconds: # await self.bot.send_message( # self.channel, embed=utils.get_embed("Game canceled due to inactivity.") # ) # break # else: # inactive_time = 0 # Next turn if time > self.seconds: await self.next_turn() time = 0 # Guess card elif message.type == TabooMsg.Type.guess: if (self.giver in self.team_a and message.author in self.team_a) or\ (self.giver in self.team_b and message.author in self.team_b): await self.guess(message.content, message.author) # Skip card elif message.type == TabooMsg.Type.skip_card: if self.giver == message.author: await self.skip_card() await self.dm_current_card() # Buzz elif message.type == TabooMsg.Type.buzz: team = self.team_a if self.giver not in self.team_b else self.team_b if message.author in team: await self.buzz(message.content) # Game Over elif message.type == TabooMsg.Type.game_over: embed = Embed(title='Game Over!') if self.team_a_score > self.team_b_score: embed.description = "The winner is Team A :tada:" for i, member in enumerate(self.team_a): embed.description += '\n{}. <@{}>'.format(i+1, member) elif self.team_b_score > self.team_a_score: embed.description = "The winner is Team B :tada:" for i, member in enumerate(self.team_b): embed.description += '\n{}. <@{}>'.format(i + 1, member) else: embed.description = "Nobody won! Everyone's a looser :tada:" await self.bot.send_message(self.channel, embed=embed) break self.callback(self.server_id)
async def repo(): """ Links the bot's git repository. """ await bot.say( embed=utils.get_embed("https://github.com/Kremor/gally", 'Repo'))