async def raid_command(self, ctx, name, tier, boss, time, roster=False): name = self.get_raid_name(name) boss = boss.capitalize() post = await ctx.send('\u200B') raid_id = post.id timestamp = int( time.replace(tzinfo=datetime.timezone.utc).timestamp() ) # Do not use local tz. raid = (raid_id, ctx.channel.id, ctx.guild.id, name, tier, boss, timestamp, roster) add_raid(self.conn, raid) available = _("<Available>") for i in range(len(self.slots_class_names)): assign_player(self.conn, raid_id, i, None, available, ','.join(self.slots_class_names[i])) self.conn.commit() logger.info("Created new raid: {0} at {1}".format(name, time)) embed = self.build_raid_message(ctx.guild, raid_id, "\u200B") await post.edit(embed=embed) emojis = ["\U0001F6E0", "\u26CF", "\u274C", "\u2705"] # Config, pick, cancel, check emojis.extend(self.class_emojis) for emoji in emojis: await post.add_reaction(emoji) await asyncio.sleep(0.25) try: await post.pin() except discord.Forbidden: await ctx.send(_( "Error: Missing 'Manage Messages' permission to pin the raid post." ), delete_after=30) return post.id
async def roster_overwrite(self, author, channel, raid_id): bot = self.bot def check(msg): return author == msg.author text = _( "If you wish to overwrite a default raid slot please respond with the slot number followed by the " "class emojis you would like. Configuration will finish after 20s of no interaction. " ) msg = await channel.send(text) while True: try: reply = await bot.wait_for('message', timeout=20, check=check) except asyncio.TimeoutError: await channel.send(_("Roster configuration finished!"), delete_after=10) break else: await reply.delete() if reply.content[0].isdigit(): index = int(reply.content[0]) if index == 1: if reply.content[1].isdigit(): index = int(reply.content[0:2]) if index <= 0 or index > len(self.slots_class_names): await channel.send(_("No valid slot provided!"), delete_after=10) continue else: await channel.send(_("No slot provided!"), delete_after=10) continue new_classes = [] for name in self.role_names: if name.lower() in reply.content.lower(): new_classes.append(name) if new_classes: if len(new_classes) > 3: await channel.send(_( "You may only provide up to 3 classes per slot."), delete_after=10) continue # allow maximum of 4 classes available = _("<Available>") assign_player(self.conn, raid_id, index - 1, None, available, ','.join(new_classes)) await channel.send( _("Classes for slot {0} updated!").format(index), delete_after=10) await msg.delete()
async def get_players(self, author, channel, raid_id): bot = self.bot def check(reaction, user): return user == author timeout = 60 reaction_limit = 20 reactions = alphabet_emojis() reactions = reactions[:reaction_limit] players = select_rows(self.conn, 'Assignment', 'player_id', raid_id) assigned_ids = [ player[0] for player in players if player[0] is not None ] available = select_players(self.conn, 'player_id, byname', raid_id) default_name = _("<Available>") if not available: await channel.send( _("There are no players to assign for this raid!"), delete_after=10) return if len(available) > reaction_limit: available = available[: reaction_limit] # This only works for the first 20 players. await channel.send( _("**Warning**: removing some noobs from available players!"), delete_after=10) msg_content = _( "Please select the player you want to assign a spot in the raid from the list below using the " "corresponding reaction. Assignment will finish after {0}s of no interaction." ).format(timeout) info_msg = await channel.send(msg_content) msg_content = _("Available players:\n*Please wait... Loading*") player_msg = await channel.send(msg_content) for reaction in reactions[:len(available)]: await player_msg.add_reaction(reaction) class_msg_content = _("Select the class for this player.") class_msg = await channel.send(class_msg_content) for reaction in self.class_emojis: await class_msg.add_reaction(reaction) while True: # Update player msg msg_content = _("Available players:\n") counter = 0 for player in available: if player[0] in assigned_ids: msg_content = msg_content + str( reactions[counter]) + " ~~" + player[1] + "~~\n" else: msg_content = msg_content + str( reactions[counter]) + " " + player[1] + "\n" counter = counter + 1 await player_msg.edit(content=msg_content) # Get player try: (reaction, user) = await bot.wait_for('reaction_add', timeout=timeout, check=check) except asyncio.TimeoutError: await channel.send(_("Player assignment finished!"), delete_after=10) break else: try: index = reactions.index(reaction.emoji) except ValueError: await class_msg.remove_reaction(reaction, user) await channel.send(_("Please select a player first!"), delete_after=10) continue else: await player_msg.remove_reaction(reaction, user) selected_player = available[index] slot = select_one_player(self.conn, 'Assignment', 'slot_id', selected_player[0], raid_id) if slot is not None: # Player already assigned a slot, remove player and reset slot. class_names = ','.join(self.slots_class_names[slot]) assign_player(self.conn, raid_id, slot, None, default_name, class_names) assigned_ids.remove(selected_player[0]) text = _("Removed {0} from the line up!").format( selected_player[1]) await channel.send(text, delete_after=10) await self.update_raid_post(raid_id, channel) continue # Get class try: (reaction, user) = await bot.wait_for('reaction_add', timeout=timeout, check=check) except asyncio.TimeoutError: await channel.send(_("Player assignment finished!"), delete_after=10) break else: if str(reaction.emoji) in self.class_emojis: await class_msg.remove_reaction(reaction, user) signup = select_one_player(self.conn, 'Players', reaction.emoji.name, selected_player[0], raid_id) if not signup: text = _("{0} did not sign up with {1}!").format( selected_player[1], str(reaction.emoji)) await channel.send(text, delete_after=10) continue else: await player_msg.remove_reaction(reaction, user) await channel.send( _("That is not a class, please start over!"), delete_after=10) continue # Check for free slot search = '%' + reaction.emoji.name + '%' slot_id = select_one_slot(self.conn, raid_id, search) if slot_id is None: await channel.send( _("There are no slots available for the selected class."), delete_after=10) else: assign_player(self.conn, raid_id, slot_id, *selected_player, reaction.emoji.name) assigned_ids.append(selected_player[0]) msg_content = _("Assigned {0} to {1}.").format( selected_player[1], str(reaction.emoji)) await channel.send(msg_content, delete_after=10) await self.update_raid_post(raid_id, channel) await info_msg.delete() await player_msg.delete() await class_msg.delete() return
async def raid_update(self, payload): bot = self.bot guild = bot.get_guild(payload.guild_id) channel = guild.get_channel(payload.channel_id) user = payload.member raid_id = payload.message_id emoji = payload.emoji raid_deleted = False if str(emoji) in ["\U0001F6E0", "\u26CF"]: organizer_id = select_one(self.conn, 'Raids', 'organizer_id', raid_id) raid_leader_name = select_one(self.conn, 'Settings', 'raid_leader', guild.id, 'guild_id') if not raid_leader_name: raid_leader_name = self.raid_leader_name raid_leader = await get_role(guild, raid_leader_name) if raid_leader not in user.roles and organizer_id != user.id: error_msg = _( "You do not have permission to change the raid settings. " "You need to have the '{0}' role.").format( raid_leader_name) logger.info("Putting {0} on the naughty list.".format( user.name)) await channel.send(error_msg, delete_after=15) return if str(emoji) == "\u26CF": # Pick emoji roster = select_one(self.conn, 'raids', 'roster', raid_id) if not roster: update_raid(self.conn, 'raids', 'roster', True, raid_id) await channel.send(_("Enabling roster for this raid."), delete_after=10) await self.get_players(user, channel, raid_id) elif str(emoji) == "\U0001F6E0": # Config emoji raid_deleted = await self.configure(user, channel, raid_id) elif str(emoji) == "\u274C": # Cancel emoji assigned_slot = select_one_player(self.conn, 'Assignment', 'slot_id', user.id, raid_id) if assigned_slot is not None: class_name = select_one_player(self.conn, 'Assignment', 'class_name', user.id, raid_id) error_msg = _( "Dearest raid leader, {0} has cancelled their availability. " "Please note they were assigned to {1} in the raid." ).format(user.mention, class_name) await channel.send(error_msg) class_names = ','.join(self.slots_class_names[assigned_slot]) assign_player(self.conn, raid_id, assigned_slot, None, _("<Available>"), class_names) r = select_one_player(self.conn, 'Players', 'byname', user.id, raid_id) if r: delete_raid_player(self.conn, user.id, raid_id) else: add_player_class(self.conn, raid_id, user.id, user.display_name, [], unavailable=1) elif str(emoji) == "\u2705": # Check mark emoji role_names = [ role.name for role in user.roles if role.name in self.role_names ] if role_names: add_player_class(self.conn, raid_id, user.id, user.display_name, role_names) else: error_msg = _( "{0} you have not assigned yourself any class roles." ).format(user.mention) await channel.send(error_msg, delete_after=15) elif emoji.name in self.role_names: add_player_class(self.conn, raid_id, user.id, user.display_name, [emoji.name]) try: role = await get_role(guild, emoji.name) if role not in user.roles: await user.add_roles(role) except discord.Forbidden: await channel.send( _("Error: Missing 'Manage roles' permission to assign the class role." )) self.conn.commit() if raid_deleted: post = await channel.fetch_message(raid_id) await post.delete() return True else: await self.update_raid_post(raid_id, channel) return