def __init__(self, participant_id_list: list, game: Game): # Initial list of participants self.__unselected_participants = participant_id_list # Game being played self.__game = game # Amount of games to be played self.__game_type = "bo3" # Get the list of maps for the game being played. self.__unselected_maps = [ m.lower() for m in Config.get_config_property( "tenman", "maps", game.name.lower()) ] self.__map_pick_ban_sequence = [ MapPickBanEntry(s) for s in Config.get_config_property( "tenman", "mapPickBanSequence", game.name.lower(), self.__game_type).split("-") ] self.__teams_manager = None # List of maps to pay self.__picked_maps = [] # Order captains pick players self.__player_pick_sequence = [ TeamStatus.get(s) for s in Config.get_config_property( "tenman", "playerPickSequence").split("-") ] # Flag set when waiting for other team to pick side self.__wait_for_side_pick = False # Team that picks the side self.__side_pick_team = None
async def free(self, ctx: commands.context.Context): """ Removes roles from all participating players SYNOPSIS .tm_free """ captain_a_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamA", "captainRole"), ctx.guild.roles) captain_b_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamB", "captainRole"), ctx.guild.roles) player_a_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamA", "playerRole"), ctx.guild.roles) player_b_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamB", "playerRole"), ctx.guild.roles) await ctx.channel.send(content="Beginning deconstruction.") teams = self.__ongoing.get_teams() for a, b in zip(teams[0].get_players(), teams[1].get_players()): await find(lambda u: u.id == a, ctx.guild.members).remove_roles(captain_a_role, player_a_role) await find(lambda u: u.id == b, ctx.guild.members).remove_roles(captain_b_role, player_b_role) await ctx.channel.send(content="Players freed.") self.__ongoing = None
def main(): cogs = [ "cogs.{0}cog".format(m) for m in Config.get_config_property("modules") ] bot = Goldbot(command_prefix=Config.get_config_property("prefix")) for cog in cogs: bot.load_extension(cog) bot.run(Config.get_config_property("discordApiKey"), bot=True, reconnect=True)
async def make_role_subscribable(self, ctx): if len(ctx.message.role_mentions) < 1: raise commands.BadArgument(message="You are missing required arguments for this command:\n`role " "(@mention)`") if ctx.message.role_mentions[0].name in Config.get_config_property("server", "optionalRoles"): raise commands.BadArgument(message="Role is already a subscribable role.") role_list = Config.get_config_property("server", "optionalRoles") role_list.append(ctx.message.role_mentions[0].name) Config.update_config_property_and_write("server/optionalRoles", role_list) message = "{0} is now a subscribable role!\nSubscribe to the role using `{1}subscribe @{0}`" \ .format(ctx.message.role_mentions[0].name, Config.get_config_property("prefix")) await ctx.channel.send(content=message)
async def get_leaderboard(self, ctx, *args): try: parsed_args = ServerArgParsers.LEADERBOARD_ARG_PARSER.parse_known_args(args)[0] except ArgumentParserError as e: raise commands.ArgumentParsingError(message=e.args[0]) if parsed_args.mobile: headers = ["N", "S", "CS", "LS"] else: headers = ["Name", "Score", "Current Streak", "Longest Streak"] emoji = find(lambda em: str(em) == parsed_args.emoji, ctx.guild.emojis) try: if emoji.name not in Config.get_config_property("server", "leaderboard", "emojiMap").keys(): raise commands.BadArgument("There is no leaderboard associated with the emoji.") relative_path = "{0}/leaderboards/{1}/{2}.json".format(Config.get_config_property("saveDir"), str(ctx.guild.id), emoji.name) with open(str(get_project_dir() / relative_path)) as f: leaderboard_json = json.load(f) entries = sorted(leaderboard_json, key=lambda e: (leaderboard_json[e]["score"], leaderboard_json[e]["current_streak"], leaderboard_json[e]["longest_streak"]), reverse=True) except AttributeError as e: LOGGER.error("ServerCog::leaderboard - Called with default emoji.") raise commands.BadArgument("Leaderboards don't exist for default emojis.") except FileNotFoundError as e: LOGGER.error("ServerCog::leaderboard - No leaderboard data found for called emoji") raise commands.BadArgument("No leaderboard data found for called emoji.") try: entries = entries[0:int(parsed_args.top)] except TypeError: pass except IndexError: LOGGER.warning("Specified a value that was larger than the amount of users with scores") pass except ValueError: LOGGER.error("ServerCog::leaderboard - " + parsed_args.top + " is not an int") raise commands.BadArgument("Bad argument for top parameter. Expected integer.") table = [[find(lambda u: str(u.id) == e, ctx.guild.members).name, leaderboard_json[e]["score"], leaderboard_json[e]["current_streak"], leaderboard_json[e]["longest_streak"]] for e in entries] await ctx.channel.send("{0}*** Leaderboard ***{0}\n```{1}```".format(str(emoji), tabulate(table, headers=headers)))
async def __move_user_to_proper_voice(ctx: commands.context.Context, user: discord.Member, status: TeamStatus): voice = find( lambda v: v.name == Config.get_config_property( "tenman", "team{0}".format(status.name), "voice"), ctx.guild.voice_channels) await user.move_to(voice)
async def __leaderboard_job(self): tz = pytz.timezone(Config.get_config_property("server", "timezone")) await self.wait_until_ready() # List of timers as specified in the config timers = [(datetime.strptime(entry, "%H:%M")).time() for entry in Config.get_config_property( "server", "leaderboard", "emojiMap").values()] # Add the military time equivalents to the list timers.extend([ timer.replace(hour=timer.hour + 12) for timer in timers if timer.hour != 12 ]) timers.sort() # This part only runs once, I want to find the time it started up so I can find the next available time to # schedule the job startup_time = tz.localize(datetime.now()) # shift to the next closest time in the list i = 0 while timers[0] < startup_time.time() and i < len(timers): t = timers[0] timers.remove(t) timers.append(t) i = i + 1 # Make the timers list cycle infinitely timers = cycle(timers) while not self.is_closed(): # At startup or after the job is done sleeping, get the current time so we can calculate how many seconds we # need to wait until the next job current_time = tz.localize(datetime.now()) # Get the next available time in the timer list next_timer = next(timers) timer = current_time.replace(hour=next_timer.hour, minute=next_timer.minute + 2, second=0) if timer.time() < current_time.time(): timer = timer + timedelta(days=1) LOGGER.info( "LeaderboardHandler scheduled to process more entries on " + timer.strftime("%d-%b-%Y (%H:%M)")) # Wait until the next time and then run the job delay = (timer - current_time).total_seconds() await asyncio.sleep(delay) LeaderboardHandler.get_leaderboard_handler().process_entries()
def __process_score_reset(self): base_path = Config.get_config_property("saveDir") + "/leaderboards/307026836066533377/" global_path = base_path + "global.json" global_leaderboard = read_json_safe(global_path) aggregate_scores_dict = {} yesterday = datetime.now() - timedelta(days=1) emoji_time_dict = Config.get_config_property("server", "leaderboard", "emojiMap") try: os.makedirs(base_path + "old/" + str(yesterday.month) + "-" + str(yesterday.year)) except OSError: pass for emoji in emoji_time_dict.keys(): leaderboard_path = base_path + emoji + ".json" try: leaderboard_json = read_json_safe(leaderboard_path) except FileNotFoundError: continue score_sorted = sorted(leaderboard_json, key=lambda e: (leaderboard_json[e]["score"], leaderboard_json[e]["current_streak"], leaderboard_json[e]["longest_streak"]), reverse=True) for i, k in zip(range(len(score_sorted), 0, -1), score_sorted): try: user_global_score = aggregate_scores_dict[k] except KeyError: user_global_score = 0 aggregate_scores_dict[k] = user_global_score + i shutil.move(leaderboard_path, base_path + "old/" + str(yesterday.month) + "-" + str(yesterday.year) + "/" + emoji + ".json") for k in aggregate_scores_dict.keys(): try: user_score = global_leaderboard[k] except KeyError: user_score = 0 user_score = user_score + (aggregate_scores_dict[k] * 10) global_leaderboard[k] = user_score with open(global_path, "w") as f: json.dump(global_leaderboard, f, indent=4)
def add_entry(self, user_id, timestamp, emote): emoji_time_dict = Config.get_config_property("server", "leaderboard", "emojiMap") for entry in self.__unprocessed_entries: if entry["user_id"] == user_id and entry["emote"] == emote: return if emote in emoji_time_dict.keys(): fixed_timestamp = timestamp.time().replace(second=0, microsecond=0) r_time = datetime.strptime(emoji_time_dict[emote], "%H:%M").time() m_time = r_time.replace(hour=r_time.hour + 12) if fixed_timestamp == r_time or fixed_timestamp == m_time or fixed_timestamp == \ r_time.replace(minute=r_time.minute + 1) or fixed_timestamp == m_time.replace(minute=m_time.minute + 1): self.__unprocessed_entries.append({"user_id": user_id, "timestamp": timestamp, "emote": emote}) LOGGER.info("LeaderboardHandler::add_entry - Adding message from " + str(user_id) + " to the message queue for the emote " + emote)
async def on_message(self, message): try: emoji = find(lambda e: str(e) == message.content, message.guild.emojis) except AttributeError: return if emoji is not None: LeaderboardHandler.get_leaderboard_handler().add_entry( message.author.id, message.created_at.replace(tzinfo=pytz.utc).astimezone( pytz.timezone( Config.get_config_property("server", "timezone"))), emoji.name) await self.process_commands(message)
async def init(self, ctx: commands.context.Context, *args): """ Initializes ten man with users in the general channel. Requires 10 users in the general voice channel SYNOPSIS .tm_init [-h] game OPTIONS -h --help Provides help messages during the work flow """ # Check if there is already a game going on and if there is bail if self.__ongoing is not None: raise commands.CommandError("There is already an ongoing ten man.") # Get the arguments from the command message. Game command is necessary (CSGO/Valorant) try: parsed_args = TenManArgParsers.TM_INIT_ARG_PARSER.parse_known_args( args=args)[0] except ArgumentParserError: raise commands.MissingRequiredArgument( inspect.Parameter( name="Game", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)) game = Game.get(parsed_args.game) self.__display_help = parsed_args.help # All players should be in a communal voice channel when this command is called. Get all 10 players in the # voice channel and creates a list of all their ids. general_voice = find( lambda v: v.name == Config.get_config_property( "tenman", "generalVoice"), ctx.guild.voice_channels) member_list = [m.id for m in general_voice.members] member_list = [ 148297442452963329, 727670795081351188, 727672213871919215, 727672966539771934, 645696336469164107 ] # If there are more than 10 or less than 10 members there is going to be a problem # if len(member_list) is not 10: # raise commands.CommandError("There were not enough players in the voice channel to start a ten man.") self.__ongoing = TenMan(participant_id_list=member_list, game=game) # Pretty output for discord embed = discord.Embed(title=ctx.guild.name + " Ten Man", description="Ten Man initialization completed!", color=discord.Color.dark_grey()) logo = self.__resources[game.name.lower() + "Logo"] embed.add_field(name="Game", value=game.name) embed.add_field(name="Type", value="Best of 3") embed.add_field(name="Player Pick Sequence", value=Config.get_config_property( "tenman", "playerPickSequence")) embed.add_field(name="Available Participants", value="\n".join([ find(lambda u: u.id == p, ctx.guild.members).name for p in member_list ])) embed.add_field(name="Available Map Pool", value="\n".join(self.__ongoing.get_remaining_maps()), inline=False) embed.set_image(url=logo) self.__status_message = await ctx.channel.send(embed=embed) if self.__display_help: message = "***Help Message:***\nTen man has been initialized. Now it's time to pick captains. You can do " \ "so by either calling\n`.pick_captains`\nor\n`.pick_captains @captainA @captainB`" await ctx.channel.send(message)
import logging from discord.ext import commands from core.useraccounts import get_account from _global.config import Config from utilities.misc import get_project_dir LOGGER = logging.getLogger("goldlog") SERVER_SAVE_FILE = get_project_dir() / "{0}/server.pkl".format(Config.get_config_property("saveDir")) class UserAccountCog(commands.Cog): def __init__(self, bot): self.bot = bot LOGGER.info("Initialized user account command cog.") @commands.command(name="set_friend_code") async def set_friend_code(self, ctx, friend_code: str): account = get_account(ctx.message.author) if account.set_friend_code(friend_code): await ctx.channel.send(content="Your friend code has been set!") LOGGER.info("UserCommand::get_friend_code called for " + ctx.message.author.name) else: LOGGER.warning("UserCommand::set_friend_code call failed for " + str(ctx.message.author.id) + ". Invalid formatting") raise commands.BadArgument("Incorrect Friend Code formatting. Expecting formats:\n" "`1234-1234-1234`\n`SW-1234-1234-1234`\n`DS-1234-1234-1234`", friend_code) @commands.command(name="get_friend_code") async def get_friend_code(self, ctx): if len(ctx.message.mentions) < 1:
def __role_is_optional(role): return role.name in Config.get_config_property("server", "optionalRoles")
async def subscribable(self, ctx): await ctx.channel.send("```yaml\nsubscribable:\n - {0}```".format("\n - ".join(sorted(Config.get_config_property("server", "optionalRoles")))))
import yaml from discord.ext import commands from discord.ext.commands import UserConverter from cogs.helper.challonge import tournamentcommands from _global.config import Config from utilities.misc import read_save_file, save_file from _global.squadlockeconstants import ENCOUNTER_AREA_DICT, WEATHER_DICT from _global.argparsers.squadlockeargparsers import SquadlockeArgParsers from utilities.discordservices import build_embed from core.model.squadlocke.routeencounter import RouteEncounter from utilities.parsers.serebiiparser import SerebiiParser from _global.argparsers.throwingargumentparser import ArgumentParserError LOGGER = logging.getLogger("goldlog") SQUADLOCKE_DATA_FILE_PATH = Config.get_config_property( "saveDir") + "/squadlocke/sldata.pkl" SQUADLOCKE_ROLE = Config.get_config_property("squadlocke", "role") SQUADLOCKE_NAME = Config.get_config_property("squadlocke", "defaultCheckpointName") SL_SERIALIZE = read_save_file(SQUADLOCKE_DATA_FILE_PATH) PARTICIPANTS = {} if len(SL_SERIALIZE) < 1 else SL_SERIALIZE[0] CHECKPOINT = 1 if len(SL_SERIALIZE) < 2 else SL_SERIALIZE[1] with open("bin/resources/squadlocke/resources.yml") as f: RESOURCES = yaml.load(f, Loader=yaml.FullLoader) save_file([PARTICIPANTS, CHECKPOINT], SQUADLOCKE_DATA_FILE_PATH) class SquadlockeCog(commands.Cog): def __init__(self, bot):
async def pick_captains(self, ctx: commands.context.Context): """ Makes mentioned players captain or selects two captains at random if none are provided SYNOPSIS .tm_pick_captains [@mention @mention] """ # Caller tried to manually select too many captains if len(ctx.message.mentions) > 2: raise commands.TooManyArguments( "Attempted to pick too many captains.") # Create role objects for config captain_a_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamA", "captainRole"), ctx.guild.roles) captain_b_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamB", "captainRole"), ctx.guild.roles) # Get captains either randomly or manually (based on # of mentioned users) captain_ids = ctx.message.raw_mentions captains = self.__ongoing.set_or_pick_captains(captain_ids) captain_a = find(lambda c: c.id == captains[0], ctx.guild.members) captain_b = find(lambda c: c.id == captains[1], ctx.guild.members) await captain_a.add_roles(captain_a_role) await captain_b.add_roles(captain_b_role) # Pretty output for discord embed_a = discord.Embed(title="Captain Selected", color=discord.Color.red()) embed_a.set_thumbnail(url=captain_a.avatar_url) embed_a.add_field(name="Name", value=captain_a.name) embed_a.add_field( name="Selection Type", value="Manual" if len(ctx.message.mentions) == 2 else "Random") embed_a.add_field(name="Ten Man Status", value="[Link](" + self.__status_message.jump_url + ")") embed_b = discord.Embed(title="Captain Selected", color=discord.Color.blue()) embed_b.set_thumbnail(url=captain_b.avatar_url) embed_b.add_field(name="Name", value=captain_b.name) embed_b.add_field( name="Selection Type", value="Manual" if len(ctx.message.mentions) == 2 else "Random") embed_b.add_field(name="Ten Man Status", value="[Link](" + self.__status_message.jump_url + ")") await ctx.channel.send(embed=embed_a) await ctx.channel.send(embed=embed_b) try: await self.__move_user_to_proper_voice(ctx, captain_a, TeamStatus.A) await self.__move_user_to_proper_voice(ctx, captain_b, TeamStatus.B) except discord.errors.HTTPException: pass status_embed = self.__status_message.embeds[0] rp_field = status_embed.fields[3] status_embed.set_field_at( index=3, name=rp_field.name, value="\n".join([ find(lambda u: u.id == rp, ctx.guild.members).name for rp in self.__ongoing.get_remaining_participant_ids() ])) status_embed.insert_field_at(index=4, name="Team A", value=captain_a.name, inline=True) status_embed.insert_field_at(index=5, name="Team B", value=captain_b.name, inline=True) await self.__status_message.edit(embed=status_embed) if self.__display_help: message = "***Help Message***:\nNow that captains have been selected, it is time for the captain of Team" \ "A to pick a player. They can do so by using the command\n`.pick_player @mention`" await ctx.channel.send(message)
class TenManCog(commands.Cog): """ The `Ten Man` module allows members of the discord server to start a ten man. A ten man is a game type where 10 players gather, form two teams, and compete against each other. A ten man can be orchestrated for `Counter-Strike: Global Offensive` or `Valorant` """ def __init__(self, bot: commands.Bot): self.bot = bot # core.model.tenman self.__ongoing = None # Message for displaying the current status of the tenman (teams, map picks, etc.) self.__status_message = None # Print help messages to help new users know which commands need to come next self.__display_help = False with open(str(get_project_dir() / "bin/resources/tenman/resources.yml")) as f: self.__resources = yaml.load(f, Loader=yaml.FullLoader) LOGGER.info("Initialized ten man command cog.") @commands.command(name="tm_init", aliases=["tm_start"]) @commands.has_role(Config.get_config_property("tenman", "organizerRole")) async def init(self, ctx: commands.context.Context, *args): """ Initializes ten man with users in the general channel. Requires 10 users in the general voice channel SYNOPSIS .tm_init [-h] game OPTIONS -h --help Provides help messages during the work flow """ # Check if there is already a game going on and if there is bail if self.__ongoing is not None: raise commands.CommandError("There is already an ongoing ten man.") # Get the arguments from the command message. Game command is necessary (CSGO/Valorant) try: parsed_args = TenManArgParsers.TM_INIT_ARG_PARSER.parse_known_args( args=args)[0] except ArgumentParserError: raise commands.MissingRequiredArgument( inspect.Parameter( name="Game", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)) game = Game.get(parsed_args.game) self.__display_help = parsed_args.help # All players should be in a communal voice channel when this command is called. Get all 10 players in the # voice channel and creates a list of all their ids. general_voice = find( lambda v: v.name == Config.get_config_property( "tenman", "generalVoice"), ctx.guild.voice_channels) member_list = [m.id for m in general_voice.members] member_list = [ 148297442452963329, 727670795081351188, 727672213871919215, 727672966539771934, 645696336469164107 ] # If there are more than 10 or less than 10 members there is going to be a problem # if len(member_list) is not 10: # raise commands.CommandError("There were not enough players in the voice channel to start a ten man.") self.__ongoing = TenMan(participant_id_list=member_list, game=game) # Pretty output for discord embed = discord.Embed(title=ctx.guild.name + " Ten Man", description="Ten Man initialization completed!", color=discord.Color.dark_grey()) logo = self.__resources[game.name.lower() + "Logo"] embed.add_field(name="Game", value=game.name) embed.add_field(name="Type", value="Best of 3") embed.add_field(name="Player Pick Sequence", value=Config.get_config_property( "tenman", "playerPickSequence")) embed.add_field(name="Available Participants", value="\n".join([ find(lambda u: u.id == p, ctx.guild.members).name for p in member_list ])) embed.add_field(name="Available Map Pool", value="\n".join(self.__ongoing.get_remaining_maps()), inline=False) embed.set_image(url=logo) self.__status_message = await ctx.channel.send(embed=embed) if self.__display_help: message = "***Help Message:***\nTen man has been initialized. Now it's time to pick captains. You can do " \ "so by either calling\n`.pick_captains`\nor\n`.pick_captains @captainA @captainB`" await ctx.channel.send(message) @commands.command(name="tm_pick_captains", aliases=["pick_captains"]) @commands.has_role(Config.get_config_property("tenman", "organizerRole")) async def pick_captains(self, ctx: commands.context.Context): """ Makes mentioned players captain or selects two captains at random if none are provided SYNOPSIS .tm_pick_captains [@mention @mention] """ # Caller tried to manually select too many captains if len(ctx.message.mentions) > 2: raise commands.TooManyArguments( "Attempted to pick too many captains.") # Create role objects for config captain_a_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamA", "captainRole"), ctx.guild.roles) captain_b_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamB", "captainRole"), ctx.guild.roles) # Get captains either randomly or manually (based on # of mentioned users) captain_ids = ctx.message.raw_mentions captains = self.__ongoing.set_or_pick_captains(captain_ids) captain_a = find(lambda c: c.id == captains[0], ctx.guild.members) captain_b = find(lambda c: c.id == captains[1], ctx.guild.members) await captain_a.add_roles(captain_a_role) await captain_b.add_roles(captain_b_role) # Pretty output for discord embed_a = discord.Embed(title="Captain Selected", color=discord.Color.red()) embed_a.set_thumbnail(url=captain_a.avatar_url) embed_a.add_field(name="Name", value=captain_a.name) embed_a.add_field( name="Selection Type", value="Manual" if len(ctx.message.mentions) == 2 else "Random") embed_a.add_field(name="Ten Man Status", value="[Link](" + self.__status_message.jump_url + ")") embed_b = discord.Embed(title="Captain Selected", color=discord.Color.blue()) embed_b.set_thumbnail(url=captain_b.avatar_url) embed_b.add_field(name="Name", value=captain_b.name) embed_b.add_field( name="Selection Type", value="Manual" if len(ctx.message.mentions) == 2 else "Random") embed_b.add_field(name="Ten Man Status", value="[Link](" + self.__status_message.jump_url + ")") await ctx.channel.send(embed=embed_a) await ctx.channel.send(embed=embed_b) try: await self.__move_user_to_proper_voice(ctx, captain_a, TeamStatus.A) await self.__move_user_to_proper_voice(ctx, captain_b, TeamStatus.B) except discord.errors.HTTPException: pass status_embed = self.__status_message.embeds[0] rp_field = status_embed.fields[3] status_embed.set_field_at( index=3, name=rp_field.name, value="\n".join([ find(lambda u: u.id == rp, ctx.guild.members).name for rp in self.__ongoing.get_remaining_participant_ids() ])) status_embed.insert_field_at(index=4, name="Team A", value=captain_a.name, inline=True) status_embed.insert_field_at(index=5, name="Team B", value=captain_b.name, inline=True) await self.__status_message.edit(embed=status_embed) if self.__display_help: message = "***Help Message***:\nNow that captains have been selected, it is time for the captain of Team" \ "A to pick a player. They can do so by using the command\n`.pick_player @mention`" await ctx.channel.send(message) @commands.command(name="tm_pick_player", aliases=["pick_player"]) @commands.has_any_role( Config.get_config_property("tenman", "teamA", "captainRole"), Config.get_config_property("tenman", "teamB", "captainRole")) async def pick_player(self, ctx: commands.context.Context): """ Adds player to calling captains team. SYNOPSIS .tm_pick_player @mention """ if len(ctx.message.raw_mentions) > 1: raise commands.TooManyArguments( "Captain attempted to pick too many players.") captain_id = ctx.message.author.id try: pick = ctx.message.mentions[0] except IndexError: raise commands.MissingRequiredArgument(param=inspect.Parameter( name="Player", kind=inspect.Parameter.POSITIONAL_ONLY)) captain_team_status = self.__ongoing.get_captain_team_status( captain_id) last_pick = self.__ongoing.pick_player(pick.id, captain_id) role_config_property = Config.get_config_property( "tenman", "team{0}".format(captain_team_status.name), "playerRole") role = find(lambda r: r.name == role_config_property, ctx.guild.roles) await ctx.message.mentions[0].add_roles(role) embed = discord.Embed(title="Player Selected", color=discord.Color.red() if captain_team_status == TeamStatus.A else discord.Color.blue()) embed.add_field(name="Name", value=ctx.message.mentions[0].name) embed.add_field(name="Picked By", value="Team {0}".format(captain_team_status.name)) embed.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) embed.set_thumbnail(url=pick.avatar_url) await ctx.channel.send(embed=embed) try: await self.__move_user_to_proper_voice(ctx, ctx.message.mentions[0], captain_team_status) except discord.errors.HTTPException: pass status_embed = self.__status_message.embeds[0] team_field = status_embed.fields[4 if captain_team_status == TeamStatus.A else 5] status_embed.set_field_at( index=(4 if captain_team_status == TeamStatus.A else 5), name=team_field.name, value=(team_field.value + "\n" + pick.name)) if last_pick[0] is not None and last_pick[1] is not None: last_pick_profile = find(lambda p: p.id == last_pick[0], ctx.guild.members) role_config_property_lp = Config.get_config_property( "tenman", "team{0}".format(last_pick[1].name), "playerRole") role_lp = find(lambda r: r.name == role_config_property_lp, ctx.guild.roles) await last_pick_profile.add_roles(role_lp) embed_lp = discord.Embed(title="Last Pick", color=discord.Color.red() if last_pick[1] == TeamStatus.A else discord.Color.blue()) embed_lp.set_thumbnail(url=last_pick_profile.avatar_url) embed_lp.add_field(name="Name", value=last_pick_profile.name) embed_lp.add_field(name="Picked for", value="Team {0}".format(last_pick[1].name)) embed_lp.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) await ctx.channel.send(embed=embed_lp) status_embed.remove_field(index=3) status_embed.set_field_at( index=(3 if last_pick[0] == TeamStatus.A else 4), name=team_field.name, value="{0}\n{1}".format(team_field.value, last_pick_profile.name)) status_embed.set_field_at(index=5, name=status_embed.fields[5].name, value=status_embed.fields[5].value, inline=True) else: rp_field = status_embed.fields[3] status_embed.set_field_at( index=3, name=rp_field.name, value="\n".join([ find(lambda u: u.id == rp, ctx.guild.members).name for rp in self.__ongoing.get_remaining_participant_ids() ])) status_embed.set_field_at(index=5, name=status_embed.fields[5].name, value=status_embed.fields[5].value, inline=True) await self.__status_message.edit(embed=status_embed) if self.__display_help: try: message = "***Help Message:***\nIt is Team {0}'s turn to pick the next player.\nThey can do so by " \ "using the command\n`.pick_player @player`".format(self.__ongoing.peek_next_player_pick().name) except IndexError: map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban() message = "***Help Message:***\nIt is now time to move on to the map pick/ban phase. Team " \ "{0.get_team_status().name} can {0.get_mode().name.lower()} the first map.\nThey can do so" \ "by using the command\n`{0.get_mode().name.lower()}_map map`".format(map_pick_ban_entry) await ctx.channel.send(message) @commands.command(name="tm_ban_map", aliases=["ban_map"]) @commands.has_any_role( Config.get_config_property("tenman", "teamA", "captainRole"), Config.get_config_property("tenman", "teamB", "captainRole")) async def ban_map(self, ctx: commands.context.Context, map_name: str): """ Bans map and removes it from the selection pool SYNOPSIS .tm_ban_map map :param map_name: Name of map selected for ban """ map_name = map_name.lower().replace(" ", "") captain_id = ctx.message.author.id status = self.__ongoing.get_captain_team_status(captain_id) decider = self.__ongoing.ban_map(map_name, captain_id) embed = discord.Embed(title="Map Banned", color=discord.Color.red()) embed.set_image(url=self.__resources[map_name]) embed.add_field(name="Map Name", value=map_name.capitalize()) embed.add_field(name="Banned by", value="Team {0}".format(status.name)) embed.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) await ctx.channel.send(embed=embed) status_embed = self.__status_message.embeds[0] banned_text = "{0} - Team {1}".format(map_name.capitalize(), status.name) try: banned_field = status_embed.fields[6] status_embed.set_field_at(index=6, name=banned_field.name, value="{0}\n{1}".format( banned_field.value, banned_text)) except IndexError: status_embed.add_field(name="Ban History", value=banned_text) finally: status_embed.set_field_at(index=5, name=status_embed.fields[5].name, value="\n".join( self.__ongoing.get_remaining_maps())) if decider is not None: embed_decider = discord.Embed(title="Map Picked", color=discord.Color.dark_grey()) embed_decider.set_image(url=self.__resources[decider]) embed_decider.add_field(name="Map Name", value=decider.capitalize()) embed_decider.add_field(name="Type", value="Decider") embed_decider.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) status_embed.add_field(name="Decider", value=decider.capitalize()) status_embed.remove_field(index=5) await ctx.channel.send(embed=embed_decider) await self.__status_message.edit(embed=status_embed) if self.__display_help: map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban() try: message = "It is Team {0.get_team_status().name}'s turn to {0.get_mode().name.lower()} a map." \ "\nThey can do so by using the command\n`. {0.get_mode().name.lower}_map map`"\ .format(map_pick_ban_entry) except IndexError: message = "Map pick/ban phase is over. See you on the server!" await ctx.channel.send(message) @commands.command(name="tm_pick_map", aliases=["pick_map"]) @commands.has_any_role( Config.get_config_property("tenman", "teamA", "captainRole"), Config.get_config_property("tenman", "teamB", "captainRole")) async def pick_map(self, ctx: commands.context.Context, map_name: str): """ Selects map for play SYNOPSIS: .tm_pick_map map :param map_name: Map picked to be played """ map_name = map_name.lower().replace(" ", "") captain_id = ctx.message.author.id status = self.__ongoing.get_captain_team_status(captain_id) self.__ongoing.pick_map(map_name, captain_id) embed = discord.Embed(title="Map Picked", color=discord.Color.green()) embed.set_image(url=self.__resources[map_name]) embed.add_field(name="Map Name", value=map_name.capitalize()) embed.add_field(name="Picked by", value="Team " + status.name) embed.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) await ctx.channel.send(embed=embed) status_embed = self.__status_message.embeds[0] status_embed.add_field(name="Team {0}'s Pick".format(status.name), value=map_name.capitalize()) await self.__status_message.edit(embed=status_embed) if self.__display_help: message = "It is Team {0}'s turn to pick a side.\nThey can do so by using the command\n`.pick_side side`" \ .format(self.__ongoing.get_side_pick_team().name) await ctx.channel.send(message) @commands.command(name="tm_pick_side", aliases=["pick_side"]) @commands.has_any_role( Config.get_config_property("tenman", "teamA", "captainRole"), Config.get_config_property("tenman", "teamB", "captainRole")) async def pick_side(self, ctx: commands.context.Context, side: str): """ Selects start side for team opposite of the one who last picked a map SYNOPSIS .tm_pick_side side :param side: selected side """ captain_id = ctx.message.author.id side, decider = self.__ongoing.pick_side(captain_id, side) status = self.__ongoing.get_captain_team_status(captain_id) status_embed = self.__status_message.embeds[0] pick_field = status_embed.fields[len(status_embed.fields) - 1] status_embed.set_field_at(index=len(status_embed.fields) - 1, name=pick_field.name, value="{0}\n{1}'s Start Side: {2}".format( pick_field.value, status.name, side.name)) await self.__status_message.edit(embed=status_embed) embed = discord.Embed(title="Side Selected", color=discord.Color.red() if status == TeamStatus.A else discord.Color.blue()) embed.set_thumbnail( url=self.__resources["csgo{0}Logo".format(side.name)]) embed.add_field(name="Side", value=side.name) embed.add_field(name="Team", value=status.name) embed.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) await ctx.channel.send(embed=embed) if decider is not None: embed_decider = discord.Embed(title="Map Picked", color=discord.Color.dark_grey()) embed_decider.set_image(url=self.__resources[decider]) embed_decider.add_field(name="Map Name", value=decider.capitalize()) embed_decider.add_field(name="Type", value="Decider") embed_decider.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) status_embed.add_field(name="Decider", value="{0}\nB's Start Side: {1}".format( decider.capitalize(), Side(randint(0, 1)).name)) status_embed.set_field_at(index=5, name="\u200b", value="\u200b") await ctx.channel.send(embed=embed_decider) await self.__status_message.edit(embed=status_embed) if self.__display_help: try: map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban() message = "It is Team {0.get_team_status().name}'s turn to {0.get_mode().name.lower()} a map.\nThey " \ "can do so by using the command\n`.{0.get_mode().name.lower()}_map map`"\ .format(map_pick_ban_entry) except IndexError: message = "Map pick/ban phase is over. See you on the server!" await ctx.channel.send(message) @commands.command(name="tm_free", aliases=["free"]) @commands.has_role(Config.get_config_property("tenman", "organizerRole")) async def free(self, ctx: commands.context.Context): """ Removes roles from all participating players SYNOPSIS .tm_free """ captain_a_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamA", "captainRole"), ctx.guild.roles) captain_b_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamB", "captainRole"), ctx.guild.roles) player_a_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamA", "playerRole"), ctx.guild.roles) player_b_role = find( lambda r: r.name == Config.get_config_property( "tenman", "teamB", "playerRole"), ctx.guild.roles) await ctx.channel.send(content="Beginning deconstruction.") teams = self.__ongoing.get_teams() for a, b in zip(teams[0].get_players(), teams[1].get_players()): await find(lambda u: u.id == a, ctx.guild.members).remove_roles(captain_a_role, player_a_role) await find(lambda u: u.id == b, ctx.guild.members).remove_roles(captain_b_role, player_b_role) await ctx.channel.send(content="Players freed.") self.__ongoing = None @staticmethod async def __move_user_to_proper_voice(ctx: commands.context.Context, user: discord.Member, status: TeamStatus): voice = find( lambda v: v.name == Config.get_config_property( "tenman", "team{0}".format(status.name), "voice"), ctx.guild.voice_channels) await user.move_to(voice)
import requests import logging from _global.config import Config LOGGER = logging.getLogger("goldlog") API_KEY = Config.get_config_property("tournament", "challongeApiKey") CHALLONGE_USERNAME = Config.get_config_property("tournament", "challongeUsername") BASE_URL = "https://" + CHALLONGE_USERNAME + ":" + API_KEY + "@api.challonge.com/v1/" def index_tournaments(): url = BASE_URL + "tournaments.json" r = requests.get(url=url) return r.json() def create_tournament(tournament_name, extra_params): # TODO: Check if the URL is taken and adjust it if it is. params = { "tournament[name]": tournament_name, "tournament[url]": tournament_name } if extra_params is not None: for arg in extra_params: tokens = arg.split('=') trim_underscores = tokens[1].split('_') tokens[1] = "" for token in trim_underscores: tokens[1] += token + " " tokens[1] = tokens[1].strip()
async def pick_player(self, ctx: commands.context.Context): """ Adds player to calling captains team. SYNOPSIS .tm_pick_player @mention """ if len(ctx.message.raw_mentions) > 1: raise commands.TooManyArguments( "Captain attempted to pick too many players.") captain_id = ctx.message.author.id try: pick = ctx.message.mentions[0] except IndexError: raise commands.MissingRequiredArgument(param=inspect.Parameter( name="Player", kind=inspect.Parameter.POSITIONAL_ONLY)) captain_team_status = self.__ongoing.get_captain_team_status( captain_id) last_pick = self.__ongoing.pick_player(pick.id, captain_id) role_config_property = Config.get_config_property( "tenman", "team{0}".format(captain_team_status.name), "playerRole") role = find(lambda r: r.name == role_config_property, ctx.guild.roles) await ctx.message.mentions[0].add_roles(role) embed = discord.Embed(title="Player Selected", color=discord.Color.red() if captain_team_status == TeamStatus.A else discord.Color.blue()) embed.add_field(name="Name", value=ctx.message.mentions[0].name) embed.add_field(name="Picked By", value="Team {0}".format(captain_team_status.name)) embed.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) embed.set_thumbnail(url=pick.avatar_url) await ctx.channel.send(embed=embed) try: await self.__move_user_to_proper_voice(ctx, ctx.message.mentions[0], captain_team_status) except discord.errors.HTTPException: pass status_embed = self.__status_message.embeds[0] team_field = status_embed.fields[4 if captain_team_status == TeamStatus.A else 5] status_embed.set_field_at( index=(4 if captain_team_status == TeamStatus.A else 5), name=team_field.name, value=(team_field.value + "\n" + pick.name)) if last_pick[0] is not None and last_pick[1] is not None: last_pick_profile = find(lambda p: p.id == last_pick[0], ctx.guild.members) role_config_property_lp = Config.get_config_property( "tenman", "team{0}".format(last_pick[1].name), "playerRole") role_lp = find(lambda r: r.name == role_config_property_lp, ctx.guild.roles) await last_pick_profile.add_roles(role_lp) embed_lp = discord.Embed(title="Last Pick", color=discord.Color.red() if last_pick[1] == TeamStatus.A else discord.Color.blue()) embed_lp.set_thumbnail(url=last_pick_profile.avatar_url) embed_lp.add_field(name="Name", value=last_pick_profile.name) embed_lp.add_field(name="Picked for", value="Team {0}".format(last_pick[1].name)) embed_lp.add_field(name="Ten Man Status", value="[Link]({0})".format( self.__status_message.jump_url)) await ctx.channel.send(embed=embed_lp) status_embed.remove_field(index=3) status_embed.set_field_at( index=(3 if last_pick[0] == TeamStatus.A else 4), name=team_field.name, value="{0}\n{1}".format(team_field.value, last_pick_profile.name)) status_embed.set_field_at(index=5, name=status_embed.fields[5].name, value=status_embed.fields[5].value, inline=True) else: rp_field = status_embed.fields[3] status_embed.set_field_at( index=3, name=rp_field.name, value="\n".join([ find(lambda u: u.id == rp, ctx.guild.members).name for rp in self.__ongoing.get_remaining_participant_ids() ])) status_embed.set_field_at(index=5, name=status_embed.fields[5].name, value=status_embed.fields[5].value, inline=True) await self.__status_message.edit(embed=status_embed) if self.__display_help: try: message = "***Help Message:***\nIt is Team {0}'s turn to pick the next player.\nThey can do so by " \ "using the command\n`.pick_player @player`".format(self.__ongoing.peek_next_player_pick().name) except IndexError: map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban() message = "***Help Message:***\nIt is now time to move on to the map pick/ban phase. Team " \ "{0.get_team_status().name} can {0.get_mode().name.lower()} the first map.\nThey can do so" \ "by using the command\n`{0.get_mode().name.lower()}_map map`".format(map_pick_ban_entry) await ctx.channel.send(message)
def process_entries(self): LOGGER.info("LeaderboardHandler::process_entries - Processing leaderboard entries") emoji_time_dict = Config.get_config_property("server", "leaderboard", "emojiMap") today = datetime.now() if today.day == 1: self.__process_score_reset() for emoji in emoji_time_dict.keys(): leaderboard_path = str(get_project_dir() / "{0}/leaderboards/307026836066533377/{1}.json" .format(Config.get_config_property("saveDir"), emoji)) leaderboard_json = read_json_safe(leaderboard_path) entries = [entry for entry in self.__unprocessed_entries if entry["emote"] == emoji] time = datetime.strptime(emoji_time_dict[emoji], "%H:%M") for entry in entries: if (entry["timestamp"].hour == time.hour or entry["timestamp"].hour == time.hour + 12) and entry["timestamp"].minute == time.minute: if entries.index(entry) == 0: score = Config.get_config_property("server", "leaderboard", "scores", "max") else: score = Config.get_config_property("server", "leaderboard", "scores", "default") else: score = Config.get_config_property("server", "leaderboard", "scores", "min") entry["timestamp"] = None try: user_score = leaderboard_json[str(entry["user_id"])] except KeyError: user_score = { "score": 0, "current_streak": 1, "longest_streak": 0, "timestamp": None } if user_score["score"] + score < 0: user_score["score"] = 0 else: user_score["score"] = user_score["score"] + score try: last_timestamp = datetime.strptime(user_score["timestamp"], "%m/%d/%Y") except TypeError: last_timestamp = None try: user_score["timestamp"] = datetime.strftime(entry["timestamp"], "%m/%d/%Y") except TypeError: user_score["timestamp"] = None try: if entry["timestamp"] is None: user_score["current_streak"] = 0 elif (entry["timestamp"].date() - last_timestamp.date()).days == 1: user_score["current_streak"] = user_score["current_streak"] + 1 elif (entry["timestamp"].date() - last_timestamp.date()).days > 1: user_score["current_streak"] = 1 except AttributeError: pass if user_score["current_streak"] > user_score["longest_streak"]: user_score["longest_streak"] = user_score["current_streak"] leaderboard_json[str(entry["user_id"])] = user_score self.__unprocessed_entries.remove(entry) current_day = datetime.now().date() for key in leaderboard_json: try: score = leaderboard_json[key] if (current_day - datetime.strptime(score["timestamp"], "%m/%d/%Y").date()).days > 1: score["current_streak"] = 0 leaderboard_json[key] = score except (KeyError, TypeError): pass with open(leaderboard_path, "w") as f: json.dump(leaderboard_json, f, indent=4)
from utilities.misc import read_save_file, save_file from core.model.accounts.useraccount import UserAccount from _global.config import Config ACCOUNTS_FILE_PATH = Config.get_config_property("saveDir") + "/accounts/accounts.pkl" ACCOUNTS = read_save_file(ACCOUNTS_FILE_PATH) def get_account(prof): if prof.bot: return None return __get_or_create_account(prof.id) def save_accounts(): save_file(ACCOUNTS, ACCOUNTS_FILE_PATH) def __get_or_create_account(_id): return_account = None for account in ACCOUNTS: if account.get_id() == _id: return_account = account break if return_account is None: return_account = __create_account(_id) return return_account def __create_account(_id): account = UserAccount(_id)