def load(self, ctx): super(UtilityCommands, self).load(ctx) with open("league_api/data/version.json") as data_file: data = json.load(data_file) self.version = data["version"] self.guild_list = dict() self.league_helper = LeagueHelper()
def on_cm_graph(self, event, summoner_name=None, region=None): """Displays a graph of the summoners top 5 champions by mastery""" region = LeagueHelper.validate_region(region, event) if region: cm_graph = ChampionMasteryGraph(self.league_helper.watcher, region, LeagueHelper.get_champion_data()) if summoner_name is not None: filepath = "cm-" + summoner_name + ".png" else: filepath = "cm-default.png" self._graph_renderer(event, cm_graph, summoner_name, region, filepath)
def on_live_game(self, event, summoner_name=None, region=None): '''Displays the live game info if a summoner is in a game. Supports all game types and ranked modes''' # Prevent command quit on no region given if the discord user has bound a summoner to there account if region is None and summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists(region, summoner_name, event, event.msg.author.id) if summoner: spectate_info = self.league_helper.user_in_game( region, summoner["id"]) if spectate_info: game_info = GameInfo(self.league_helper) game_info.display_live_game(event.msg.channel, region, spectate_info) else: event.msg.reply("This summoner `" + summoner["name"] + " " + region + "` is not currently in a game!")
def on_patch(self, event, version=None): '''Displays the latest patch notes for League of Legends''' s = "." if not version: version = s.join(LeagueHelper.get_champion_data()["version"].split( ".", 2)[:2]) version_url = version.replace(".", "") patch_url = "http://na.leagueoflegends.com/en/news/game-updates/patch/patch-" + version_url + "-notes" version_url = "http://ddragon.leagueoflegends.com/api/versions.json" with urllib.request.urlopen(version_url) as url: raw_json = json.loads(url.read().decode()) versionExists = False for patch in raw_json: if patch.startswith(version): versionExists = True if not versionExists: event.msg.reply( "This is not a valid patch number. Try ~patch for the most recent patch notes!" ) return embed = CacheHelper.getZileanEmbed( title="League of Legends Patch Notes", description=version + " Patch Notes", footer=version + " Patch Notes") embed.add_field(name="Notes", value=patch_url) event.msg.reply(embed=embed)
def on_ability(self, event, champion_name, ability="all"): ''' Displays information about a specific champions ability ''' champions = LeagueHelper.get_champion_data() game_info = GameInfo(self.league_helper) abilities = ["q", "w", "e", "r", "passive", "all"] champ_found = False if ability.lower() in ["ult", "ultimate"]: ability = "r" elif ability.lower() not in abilities: event.msg.reply( "This is not a valid ability, Try from one of these " + str(abilities)) return for key, name in champions["keys"].items(): if champion_name.lower() == name.lower(): champ_found = True if ability == "all": game_info.display_champ(event.msg.channel, champions["version"], champions["data"][name]) else: game_info.display_ability(event.msg.channel, champions["version"], champions["data"][name], ability) if not champ_found: event.msg.reply( "This champion does not exist! Try ~ability Akali Q as an example..." )
def on_track(self, event, summoner_name=None, region=None): '''Adds a summoner for Zilean to track whether they are in a live game''' if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") if region is None and summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists( region, summoner_name, author_id=event.msg.author.id) if summoner is False: event.msg.reply("This summoner `" + summoner_name + "` does not exist on `" + region + "` Maybe try another region!") return self._add_summoner(event, region, summoner)
def on_iam(self, event, summoner_name=None, region=None): '''Set a default summoner for yourself that all league commands will use if you leave their summoner name and region arguments blank''' summoner_binds = LiveDataHelper.load_summoner_binds() author_id = str(event.author.id) if summoner_name is None and region is None: if LiveDataHelper.user_is_bound(summoner_binds, author_id): summoner_tuple = summoner_binds[author_id] event.msg.reply("You are `" + summoner_tuple[0] + " " + summoner_tuple[1] + "` If you want to change this type ~iam [summoner_name] [region]") else: event.msg.reply("You have not bound a summoner to your discord user! To do this type `~iam [summoner_name] [region]`") elif (summoner_name is not None) and (region is not None): region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists(region, summoner_name, event) if summoner is False: return summoner_tuple = (summoner["name"], region) summoner_binds[author_id] = summoner_tuple LiveDataHelper.save_summoner_binds(summoner_binds) event.msg.reply("You have updated your summoner, You are `" + summoner["name"] + " " + region + "`") else: event.msg.reply("You must enter both a summoner name and region!")
def on_remove(self, event, summoner_name=None, region=None): '''Removes a summoner that is being tracked by Zilean''' if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") if region is None and summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) summoner_name = LiveDataHelper.get_user_bound_name( str(event.msg.author.id)) region = LeagueHelper.validate_region(region, event, send_event_msg=False) if not self._summoner_is_tracked(event.guild.id, summoner_name, region): event.msg.reply( "This summoner `" + summoner_name + " " + region + "` is not being tracked. Track them by ~tracker add <region> <summoner_name>" ) return self._remove_summoner(event, region, summoner_name)
def on_kp_graph(self, event, summoner_name=None, region=None): """Displays a graph of your kill participation percentage over the last 20 games played""" region = LeagueHelper.validate_region(region, event) if region: kp_graph = KillParticipationGraph(self.league_helper.watcher, region, LeagueHelper.get_champion_data()) if summoner_name is not None: filepath = "kp-" + summoner_name + ".png" else: filepath = "kp-default.png" self._graph_renderer(event, kp_graph, summoner_name, region, filepath, match_validation=True)
def on_cw_graph(self, event, summoner_name=None, region=None): """Displays a graph of your wins per individual champion over the last 20 games played""" region = LeagueHelper.validate_region(region, event) if region: cw_graph = ChampionWinsGraph(self.league_helper.watcher, region, LeagueHelper.get_champion_data()) if summoner_name is not None: filepath = "cw-" + summoner_name + ".png" else: filepath = "cw-default.png" self._graph_renderer(event, cw_graph, summoner_name, region, filepath, match_validation=True)
def on_gpm_graph(self, event, summoner_name=None, region=None): """Displays a graph of the league games played per month per year""" region = LeagueHelper.validate_region(region, event) if region: gpm_graph = GamesPerMonthGraph(self.league_helper.watcher, region) if summoner_name is not None: filepath = "gpm-" + summoner_name + ".png" else: filepath = "gpm-default.png" self._graph_renderer(event, gpm_graph, summoner_name, region, filepath, match_validation=True)
def on_item(self, event, item_name): '''Searches and displays the corresponding league of legends item''' items = LeagueHelper.get_item_data() game_info = GameInfo(self.league_helper) item_found = False for key, value in items["data"].items(): if item_name.lower() in value["name"].lower( ) and len(item_name) > 3: game_info.display_item(event.msg.channel, items["version"], items["data"][key]) item_found = True if not item_found: event.msg.reply("This item does not exist...")
def _display_region_status(self, event, region): region = LeagueHelper.validate_region(region) if region is None: event.msg.reply( "Please enter a valid **region**: *EUW, NA, EUN, JP, LAN, LAS, OCE, TR, RU, KR* :warning:" ) return embed = CacheHelper.getZileanEmbed( title="Zilean Bot", footer="League of Legends Server Status for " + region, description="Type ~status to see every regions status!") endpoint_status = self.league_helper.watcher.lol_status.shard_data( region) embed.add_field(name=endpoint_status["name"] + " (" + endpoint_status["slug"].upper() + ")", value="Server Status") services = endpoint_status["services"] for service in endpoint_status["services"]: embed.add_field(name=service["name"], value=self._emojify_status(service["status"]), inline=True) if len(service["incidents"]) != 0: embed.add_field(name="Incidents", value=str(len(service["incidents"])), inline=True) incident_msg = "" for incident in service["incidents"]: if len(incident["updates"]) != 0: recent_update = incident["updates"][0] incident_msg += incident["created_at"][ 0:10] + " " + recent_update["severity"].upper( ) + ": " + recent_update["content"] + "\n" embed.add_field(name="Incident Description", value=incident_msg, inline=True) else: embed.add_field(name="Incidents", value="No incidents!", inline=True) embed.add_field(name="Incident Description", value="N/A", inline=True) event.msg.reply(embed=embed)
def on_build(self, event, champion_name): '''Displays the highest winrate championGG build for the given champion''' champions = LeagueHelper.get_champion_data() champ_found = False for key, name in champions["keys"].items(): if champion_name.lower() == name.lower(): champion_builder = ChampionGGHelper() champion_builder.generate_build(event, champions["data"][name], champions["version"]) champ_found = True if not champ_found: event.msg.reply( "This champion does not exist! Try ~champion Akali as an example..." )
def on_champion(self, event, champion_name): '''Searches and displays the corresponding league of legends champion''' champions = LeagueHelper.get_champion_data() game_info = GameInfo(self.league_helper) champ_found = False for key, name in champions["keys"].items(): if champion_name.lower() == name.lower(): game_info.display_champ(event.msg.channel, champions["version"], champions["data"][name]) champ_found = True if not champ_found: event.msg.reply( "This champion does not exist! Try ~champion Akali as an example..." )
def on_auto(self, event, region, summoner_name): '''Toggles a summoner that is being tracked to auto-display there game''' # Need to rework this command! event.msg.reply( "This command is currently being rehauled. For more information join the support server: https://discord.gg/ZjAyh7N" ) return # TODO: Rework this command if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") region = LeagueHelper.validate_region(region) if not self._summoner_is_tracked(event.guild.id, summoner_name, region): event.msg.reply( "This summoner is not being tracked. Track them by ~tracker add <region> <summoner_name>" ) return tracker = self.tracker guild_id = str(event.guild.id) summoner_list = tracker[guild_id] auto_message = "no longer being auto-displayed :x:" for index, summoner_tuple in enumerate(summoner_list): if summoner_tuple[1] == summoner_name.lower( ) and region == summoner_tuple[2]: summoner_tuple = summoner_list[index] summoner_list[index] = (summoner_tuple[0], summoner_tuple[1], summoner_tuple[2], not summoner_tuple[3] ) # Invert the current bool if summoner_list[index][3]: auto_message = "now being auto-displayed :white_check_mark:" tracker[guild_id] = summoner_list self.update_tracker(tracker) event.msg.reply("The summoner `" + summoner_name + "` is " + auto_message)
def on_region(self, event, region=None): '''Sets the overall default region for League of Legends commands''' region_binds = LiveDataHelper.load_region_binds() endpoints = str(LeagueHelper.API_ENDPOINTS).replace("[","").replace("'","").replace("]", "") if region is None: if LiveDataHelper.guild_has_region(region_binds, str(event.guild.id)): event.msg.reply("The current default region for League of Legends commands is: `" + region_binds[str(event.guild.id)] + "`") else: event.msg.reply("This server does not currently have a default region for League of Legends commands.\nTry ~region [region] where the region is one of the following: `" + endpoints + "`") else: region = LeagueHelper.validate_region(region, event, send_event_msg=False) if region is None: event.msg.reply("You have entered an invalid region, please enter one of the following: `" + endpoints + "`") return region_binds = LiveDataHelper.load_region_binds() region_binds[str(event.guild.id)] = region LiveDataHelper.save_region_binds(region_binds) event.msg.reply("The default region for League of Legends commands is now `" + region + "`")
class UtilityCommands(Plugin): def load(self, ctx): super(UtilityCommands, self).load(ctx) with open("league_api/data/version.json") as data_file: data = json.load(data_file) self.version = data["version"] self.guild_list = dict() self.league_helper = LeagueHelper() @Plugin.command("info") def on_info(self, event): """Displays information about the bot""" guild_list = self.client.state.guilds user_list = self.client.state.users channel_list = self.client.state.channels embed = CacheHelper.getZileanEmbed(title="Zilean Bot Info", footer="Bot Information", description="A discord bot that tracks time spent playing league and other statistics :hourglass_flowing_sand: https://samuel-maddock.github.io/Zilean/") embed.add_field(name="Version:", value=self.version) embed.add_field(name="Developed using:", value="https://github.com/pseudonym117/Riot-Watcher https://github.com/b1naryth1ef/disco") embed.add_field(name="Guilds Connected: ", value=len(guild_list), inline=True) embed.add_field(name="Users Connected: ", value=len(user_list), inline=True) embed.add_field(name="Channels Connected: ", value=len(channel_list), inline=True) embed.add_field(name="If you enjoy the bot please upvote it below:heart_exclamation:", value="https://discordbots.org/bot/459139146544578571") embed.add_field(name="If you have feature suggestions/spotted some bugs", value="Join the support server: https://discord.gg/ZjAyh7N") embed.add_field(name="Use ~help for a list of commands!", value=":wave:") event.msg.reply(embed=embed) @Plugin.command("help") def on_help(self, event): """Displays help and command information about Zilean""" embed = CacheHelper.getZileanEmbed(title="Zilean Command List", footer="Zilean Commands", description="Note that [arg] is a required argument and (arg) is an optional argument") embed.add_field(name="Zilean Commands", value="You can view the commands by following the link below" + "\nhttps://samuel-maddock.github.io/Zilean/#command-section") embed.add_field(name="If you enjoy the bot please upvote it below:heart_exclamation:", value="https://discordbots.org/bot/459139146544578571") embed.add_field(name="If you have feature suggestions/spotted some bugs", value="Join the support server: https://discord.gg/ZjAyh7N") event.msg.author.open_dm().send_message(embed=embed) event.msg.author.open_dm().send_message(embed=self.get_notification()) event.msg.reply("Check your DMs for more information... :cyclone:") @Plugin.command("changelog") def on_changelog(self, event): '''Displays a list of recent changes to Zilean''' embed = self.get_notification() event.msg.reply(embed=embed) @Plugin.command("uptime") def on_uptime(self, event): '''Displays how long Zilean has been online for''' uptime = datetime.now() - self.start_time hours = str(uptime.seconds//3600) minutes = str((uptime.seconds//60)%60) seconds = str(uptime.seconds%60) if (hours == "0"): hours = "00" if (minutes=="0"): minutes = "00" uptime_string = str(uptime.days) + " Days, " + hours + ":" + minutes + ":" + seconds + " (Hrs/Min/Sec)" embed = CacheHelper.getZileanEmbed(title="Zilean Uptime", footer="Zilean Bot", description="Zilean has been online for: " + uptime_string) event.msg.reply(embed=embed) @Plugin.command("commands", aliases=["cmd", "cmds", "command"]) def on_commands(self, event): """Displays the link to the commands""" event.msg.reply("Zilean Commands: https://samuel-maddock.github.io/Zilean/#command-section :hourglass_flowing_sand:") @Plugin.command("ping") def on_ping(self, event): """A basic ping command, returns the latency in milliseconds""" delta = datetime.now() - event.msg.timestamp delta_tuple = math.modf(delta.total_seconds()) ms = round(delta_tuple[0] * 1000) event.msg.reply("Pong! " + str(ms) + "ms") @Plugin.command("bind") def on_bind(self, event): '''Binds Zilean to the current text channel to be used during live game alerts''' if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") guild = event.guild channel = event.channel channel_binds = LiveDataHelper.load_guild_binds() if LiveDataHelper.guild_is_binded(channel_binds, str(guild.id)): if channel_binds[str(guild.id)] == channel.id: event.msg.reply("Zilean is already bound to this channel: `#" + channel.name + "`") return channel_binds[str(guild.id)] = channel.id LiveDataHelper.save_guild_binds(channel_binds) event.msg.reply("The tracker messages are now bound to the following text channel: `#" + channel.name + "`") @Plugin.command("region", "[region:str]") def on_region(self, event, region=None): '''Sets the overall default region for League of Legends commands''' region_binds = LiveDataHelper.load_region_binds() endpoints = str(LeagueHelper.API_ENDPOINTS).replace("[","").replace("'","").replace("]", "") if region is None: if LiveDataHelper.guild_has_region(region_binds, str(event.guild.id)): event.msg.reply("The current default region for League of Legends commands is: `" + region_binds[str(event.guild.id)] + "`") else: event.msg.reply("This server does not currently have a default region for League of Legends commands.\nTry ~region [region] where the region is one of the following: `" + endpoints + "`") else: region = LeagueHelper.validate_region(region, event, send_event_msg=False) if region is None: event.msg.reply("You have entered an invalid region, please enter one of the following: `" + endpoints + "`") return region_binds = LiveDataHelper.load_region_binds() region_binds[str(event.guild.id)] = region LiveDataHelper.save_region_binds(region_binds) event.msg.reply("The default region for League of Legends commands is now `" + region + "`") @Plugin.command("iam", "[summoner_name:str] [region:str]") def on_iam(self, event, summoner_name=None, region=None): '''Set a default summoner for yourself that all league commands will use if you leave their summoner name and region arguments blank''' summoner_binds = LiveDataHelper.load_summoner_binds() author_id = str(event.author.id) if summoner_name is None and region is None: if LiveDataHelper.user_is_bound(summoner_binds, author_id): summoner_tuple = summoner_binds[author_id] event.msg.reply("You are `" + summoner_tuple[0] + " " + summoner_tuple[1] + "` If you want to change this type ~iam [summoner_name] [region]") else: event.msg.reply("You have not bound a summoner to your discord user! To do this type `~iam [summoner_name] [region]`") elif (summoner_name is not None) and (region is not None): region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists(region, summoner_name, event) if summoner is False: return summoner_tuple = (summoner["name"], region) summoner_binds[author_id] = summoner_tuple LiveDataHelper.save_summoner_binds(summoner_binds) event.msg.reply("You have updated your summoner, You are `" + summoner["name"] + " " + region + "`") else: event.msg.reply("You must enter both a summoner name and region!") @Plugin.listen("Ready") def on_ready(self, event): self.start_time = datetime.now() self.client.update_presence(Status.ONLINE, Game(type=GameType.watching, name="you play League of Legends")) command_list = self.generate_command_list() self.update_command_list(command_list) atexit.register(self.on_bot_shutdown) # Register bot shutdown hook @Plugin.schedule(CACHE_SCHEDULE) def on_cache_update(self): CacheHelper.update_static_data() @Plugin.listen("GuildCreate") def on_guild_create(self, event): self.guild_list[str(event.guild.id)] = (event.guild.name, event.guild.id) logger = CacheHelper.get_logger("GuildCreate") logger.zilean("New Guild Created: " + event.guild.name + " " + str(event.guild.id)) @Plugin.listen("GuildDelete") def on_guild_remove(self, event): guild_list = self.guild_list guild = guild_list[str(event.id)] guild_list.pop(str(event.id)) logger = CacheHelper.get_logger("GuildRemove") logger.zilean("Guild Removed: " + guild[0] + " " + str(guild[1])) channel_binds = LiveDataHelper.load_guild_binds() channel_bind = channel_binds.pop(str(event.id), None) if channel_bind: logger.zilean("Guild-Channel bind has been removed for " + guild[0] + " " + str(guild[1])) LiveDataHelper.save_guild_binds(channel_binds) @Plugin.listen("MessageCreate") def on_message_create(self, event): content = event.message.content if content == "<@459139146544578571>": event.message.reply("Type ~help and ~info to get started!") @Plugin.pre_command() def on_command_event(self, command, event, args, kwargs): CacheHelper.log_command(command, event) return event def on_bot_shutdown(self): CacheHelper.save_guilds(self.guild_list) logger = CacheHelper.get_logger("ShutdownHook") logger.zilean("Bot Shutdown - Guild List saved successfully") # Send restart messages to those who have bound the bot to a channel ''' channel_binds = LiveDataHelper.load_guild_binds() for guild_id in channel_binds.keys(): try: channel = self.bot.client.state.channels[channel_binds[guild_id]] channel.send_message("Zilean is restarting - The bot is updating, please be patient... :recycle:") except KeyError as err: logger = CacheHelper.get_logger("GuildBindError") logger.zilean("Guild ID failed to be removed when the bot was offline: " + str(guild_id)) ''' def generate_command_list(self): command_list = dict() for name, plugin in self.bot.plugins.items(): command_list[name] = list() for command in plugin.commands: prefix = self.bot.config.commands_prefix cmd_description = command.get_docstring() cmd_usage = list() args = "" if command.group: prefix += command.group + " " if command.args: for arg in command.args.args: if arg.required: args += "[" + arg.name + "] " else: args += "(" + arg.name + ") " if len(command.triggers) > 1: for trigger in command.triggers: cmd_usage.append(prefix + trigger + " " + args) else: cmd_usage.append(prefix + command.name + " " + args) cmd_name = prefix + command.name command_list.setdefault(name, []).append((cmd_name, cmd_usage, cmd_description)) return command_list def update_command_list(self, command_list): with open("docs/commandList.json", "w") as data_file: json.dump(command_list, data_file) logger = CacheHelper.get_logger("CommandList") logger.zilean("Command List Generated") def get_notification(self): embed = CacheHelper.getZileanEmbed(title="Recent Zilean Changes (" + self.version + ")", footer="Zilean Update", description= "For previous updates and changes go to the changelog here:\nhttps://samuel-maddock.github.io/Zilean/changelog.html\n\n" + "You can now bind a League of Legends summoner to your discord user by using the ~iam command. Try **~iam [summoner_name] [region]** to get started!\n\n" + "If you do this any command that requires a summoner name and region will work without writing those arguments eg ~match_history will display your own match history.\n\n" + "In order to support adding a default LoL region, the command structure for some commands have changed!" "\n\n" "For many LoL commands you used to state **[region] [summoner_name]** but now the order is **[summoner_name] (region)**." "\n\n" "The region is only optional if you set a default region for your server using **~region [league region]**" "\n\n**Note that you need to remove any spaces from a summoner name for the commands to work!**") embed.color = 0xFF3B73 return embed
def load(self, ctx): super(GameTrackerCommands, self).load(ctx) self.league_helper = LeagueHelper() self.tracker = self.load_tracker()
class GameTrackerCommands(Plugin): def load(self, ctx): super(GameTrackerCommands, self).load(ctx) self.league_helper = LeagueHelper() self.tracker = self.load_tracker() @Plugin.pre_command() def on_command_event(self, command, event, args, kwargs): CacheHelper.log_command(command, event) return event def load_tracker(self): with open("league_api/data/live/tracker.json") as tracker_file: return json.load(tracker_file) def update_tracker(self, tracker): with open("league_api/data/live/tracker.json", "w") as tracker_file: json.dump(tracker, tracker_file) self.tracker = tracker @Plugin.command("tracker") def on_tracker(self, event): '''Displays the list of tracked summoners and whether they are in game''' if len(event.args) >= 1: return if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") tracker = self.tracker if not self._guild_is_tracked(str(event.msg.guild.id)): event.msg.reply( "You are currently not tracking any players! Try ~tracker add [summoner_name] [region] to begin..." ) return self._display_track(tracker[str(event.msg.guild.id)], event.msg.channel) @Plugin.command("add", '[summoner_name:str] [region:str]', group="tracker") def on_track(self, event, summoner_name=None, region=None): '''Adds a summoner for Zilean to track whether they are in a live game''' if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") if region is None and summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists( region, summoner_name, author_id=event.msg.author.id) if summoner is False: event.msg.reply("This summoner `" + summoner_name + "` does not exist on `" + region + "` Maybe try another region!") return self._add_summoner(event, region, summoner) @Plugin.command("remove", '[summoner_name:str] [region:str]', group="tracker") def on_remove(self, event, summoner_name=None, region=None): '''Removes a summoner that is being tracked by Zilean''' if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") if region is None and summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) summoner_name = LiveDataHelper.get_user_bound_name( str(event.msg.author.id)) region = LeagueHelper.validate_region(region, event, send_event_msg=False) if not self._summoner_is_tracked(event.guild.id, summoner_name, region): event.msg.reply( "This summoner `" + summoner_name + " " + region + "` is not being tracked. Track them by ~tracker add <region> <summoner_name>" ) return self._remove_summoner(event, region, summoner_name) @Plugin.command("reset", group="tracker") def on_reset(self, event): '''Removes all of the summoners that are being tracked by Zilean''' if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") if self._guild_is_tracked(event.msg.guild.id): event.msg.reply( "The tracker list for this guild has been reset :sparkles:") self.tracker[str(event.msg.guild.id)] = list() self.update_tracker(self.tracker) else: event.msg.reply( "The tracker list for this guild is empty! Use ~tracker add <region> <summoner_name> to get started..." ) @Plugin.command("auto", "<region:str> <summoner_name:str...>", group="tracker") def on_auto(self, event, region, summoner_name): '''Toggles a summoner that is being tracked to auto-display there game''' # Need to rework this command! event.msg.reply( "This command is currently being rehauled. For more information join the support server: https://discord.gg/ZjAyh7N" ) return # TODO: Rework this command if event.msg.channel.is_dm: return event.msg.reply("You must use this command in a guild!") region = LeagueHelper.validate_region(region) if not self._summoner_is_tracked(event.guild.id, summoner_name, region): event.msg.reply( "This summoner is not being tracked. Track them by ~tracker add <region> <summoner_name>" ) return tracker = self.tracker guild_id = str(event.guild.id) summoner_list = tracker[guild_id] auto_message = "no longer being auto-displayed :x:" for index, summoner_tuple in enumerate(summoner_list): if summoner_tuple[1] == summoner_name.lower( ) and region == summoner_tuple[2]: summoner_tuple = summoner_list[index] summoner_list[index] = (summoner_tuple[0], summoner_tuple[1], summoner_tuple[2], not summoner_tuple[3] ) # Invert the current bool if summoner_list[index][3]: auto_message = "now being auto-displayed :white_check_mark:" tracker[guild_id] = summoner_list self.update_tracker(tracker) event.msg.reply("The summoner `" + summoner_name + "` is " + auto_message) @Plugin.schedule(TRACKER_SCHEDULE, init=False) def on_schedule_track(self): tracker = self.tracker channel_binds = LiveDataHelper.load_guild_binds() game_info = GameInfo(self.league_helper) if len(tracker) == 0: return for guild_id in channel_binds.keys(): guild_id = str(guild_id) if self._guild_is_tracked(guild_id): channel = self.bot.client.state.channels.get( channel_binds[guild_id]) if channel is not None: # Prevents errors if the bot has left a guild, but the guild id still persits in the binds summoner_list = tracker[guild_id] logger = CacheHelper.get_logger("TrackerMessage") self._display_track(tracker[guild_id], channel) logger.zilean( "Tracker: " + guild_id + " " + self.bot.client.state.guilds.get(int(guild_id)).name) def _display_track(self, summoner_list, channel): game_found = False has_live_games = False summoner_names = "" regions = "" in_game = "" footer = "" connection_failure = False for summoner in summoner_list: summoner_failed = False auto_display = summoner[3] summoner_names += summoner[1] + "\n" regions += summoner[2] + "\n" try: spectate_info = self.league_helper.user_in_game( summoner[2], summoner[0]) except ConnectionError as e: logger = CacheHelper.get_logger("TrackerError") logger.zilean("Could not connect to the Riot API. Summoner: " + summoner[1] + "Channel: " + channel.name) summoner_failed = True connection_failure = True if spectate_info and not summoner_failed: in_game += "**Yes** | " + self.boolMsg(auto_display) + "\n" if auto_display: game_info = GameInfo(self.league_helper) game_info.display_live_game(channel, summoner[2], spectate_info) has_live_games = True elif not summoner_failed: in_game += "No | " + self.boolMsg(auto_display) + "\n" else: in_game += "Summoner info cannot be retrieved at this time\n" if connection_failure: footer = "Error retrieving one or more summoners info" if not has_live_games: footer = "No one is currently in a live game :(" else: footer = "To view a summoner in game use ~game_info <region> <summoner_name>" description = "This message is automatically displayed every " + str(int(TRACKER_SCHEDULE/60)) + " minutes!" + \ "\n If auto-display is turned on for a summoner their game is automatically displayed" embed = CacheHelper.getZileanEmbed( title=":eye: Tracking Live Games... :eye:", description=description, footer=footer) embed.add_field(name="Summoner Name", value=summoner_names, inline=True) embed.add_field(name="Region", value=regions, inline=True) embed.add_field(name="In Game | Auto-Display", value=in_game, inline=True) if connection_failure: embed.add_field( name="Connection Issue", value= "One or more summoners info could not be retrieved. Please try again in a few minutes." ) try: channel.send_message(embed=embed) except ConnectionError as e: logger = CacheHelper.get_logger("TrackerError") logger.zilean( "Tracker message failed to send. Could not connect to the Discord API" ) except APIException as e: logger = CacheHelper.get_logger("TrackerError") logger.zilean("APIException - " + str(e.status_code)) def boolMsg(self, bool): if bool: return "**Yes**" else: return "No" def _guild_is_tracked(self, guild_id): tracker = self.tracker try: a = tracker[str(guild_id)] if len(a) == 0: return False else: return True except KeyError as err: return False def _summoner_is_tracked(self, guild_id, summoner_name, region): if not self._guild_is_tracked(guild_id): return False tracker = self.tracker summoner_info_list = tracker[str(guild_id)] for summoner_tuple in summoner_info_list: if summoner_name.lower() == summoner_tuple[1].replace( " ", "").lower() and region == summoner_tuple[2]: return True return False def _add_summoner(self, event, region, summoner, is_auto=False): guild_id = str(event.guild.id) data = (summoner["id"], summoner["name"].lower(), region, is_auto) tracker = self.tracker summoner_list = list() if self._guild_is_tracked(guild_id): if self._summoner_is_tracked(guild_id, summoner["name"], region): event.msg.reply("This summoner is already being tracked: `" + summoner["name"] + "`") return else: summoner_list = tracker[guild_id] if len(summoner_list) >= 10: event.msg.reply( "You are already tracking the maximum number (10) of summoners! Use ~tracker remove [region] [summoner_name] to remove a summoner" ) return summoner_list.append(data) tracker[guild_id] = summoner_list self.update_tracker(tracker) event.msg.reply( "The summoner `" + summoner["name"] + " " + region + "` is now being tracked, tracking messages will be displayed every " + str(int(TRACKER_SCHEDULE / 60)) + " minutes :eye:") channel_binds = LiveDataHelper.load_guild_binds() if LiveDataHelper.guild_is_binded(channel_binds, guild_id): channel = self.bot.client.state.channels.get( channel_binds[guild_id]) event.msg.reply( "You will receive track alerts on the current bound text channel: `#" + channel.name + "`") else: channel = event.msg.channel channel_binds[str(guild_id)] = channel.id LiveDataHelper.save_guild_binds(channel_binds) event.msg.reply( "The tracker messages are now bound to the following text channel: `#" + channel.name + "`" + "\n" + "Use ~bind to change the bound text channel") def _remove_summoner(self, event, region, summoner_name): tracker = self.tracker guild_id = str(event.guild.id) summoner_list = tracker[guild_id] for index, summoner_tuple in enumerate(summoner_list): if summoner_tuple[1] == summoner_name.lower( ) and summoner_tuple[2] == region: summoner_name = summoner_tuple[1] del summoner_list[index] tracker[guild_id] = summoner_list self.update_tracker(tracker) event.msg.reply("The summoner `" + summoner_name + " " + region + "` is no longer being tracked.")
def display_past_game(self, channel, region, match, summoner_id): # Find the current game mode that is being played using a CDragon json match["gameQueueConfigId"] = match["queueId"] description, queue_name, pick_type, is_ranked = self._get_queue_info( region, match) game_epoch = match["gameCreation"] game_duration = datetime.timedelta(seconds=match["gameDuration"]) game_date = datetime.datetime.fromtimestamp(game_epoch / 1000).strftime('%d-%m-%Y') champion_data = LeagueHelper.get_champion_data() image_url = "http://ddragon.leagueoflegends.com/cdn/" + champion_data[ "version"] + "/img/champion/" for participant in match["participantIdentities"]: if participant["player"]["currentAccountId"] == summoner_id: target_player = participant for participant in match["participants"]: if participant["participantId"] == target_player["participantId"]: target_champion_id = participant["championId"] target_stats = str(participant["stats"]["kills"]) + "/" + str( participant["stats"]["deaths"]) + "/" + str( participant["stats"]["assists"]) target_team = participant["teamId"] for team in match["teams"]: if team["teamId"] == target_team: match_outcome = team["win"] if match_outcome == "Fail": match_outcome = "Defeat" embed_color = 16711686 else: match_outcome = "Victory" embed_color = 65286 target_champion = champion_data["keys"][str(target_champion_id)] embed = CacheHelper.getZileanEmbed(title="Match History Game Info", description=queue_name) embed.set_thumbnail(url=image_url + target_champion + ".png") embed.color = embed_color embed.add_field(name="Summoner Name", value=target_player["player"]["summonerName"], inline=True) embed.add_field(name="Champion", value=target_champion, inline=True) embed.add_field(name="k/d/a", value=target_stats, inline=True) embed.add_field(name="Match Outcome", value=match_outcome, inline=True) embed.add_field(name="Game Duration:", value=str(game_duration), inline=True) embed.add_field(name="Game Date:", value=game_date, inline=True) embed.add_field( name="More Info", value= "http://matchhistory.euw.leagueoflegends.com/en/#match-details/" + region + "/" + str(match["gameId"]) + "/" + str(summoner_id) + "?tab=overview") channel.send_message(embed=embed)
def display_live_game(self, channel, region, spectate_info): channel.send_message("Game found generating live info...") if spectate_info["gameType"] == "CUSTOM_GAME": channel.send_message( "Custom game spectating is not supported SOONtm") return champion_data = LeagueHelper.get_champion_data() team_info = list() for participant in spectate_info["participants"]: champ_info = (participant["teamId"], participant["summonerName"], champion_data["keys"][str( participant["championId"])], participant["summonerId"]) team_info.append(champ_info) blue_names = "" blue_champs = "" red_names = "" red_champs = "" blue_rank = "" red_rank = "" # Find the current game mode that is being played using a CDragon json # Currently the CDragon json needs to be updated manually -> TODO description, queue_name, pick_type, is_ranked = self._get_queue_info( region, spectate_info) # Find the summoners names, champions and ranks on each team for participant in team_info: ranked_positions = self.league_helper.watcher.league.positions_by_summoner( region, participant[3]) rank, rank_type = self._get_rank_by_queue(queue_name, is_ranked, ranked_positions) if participant[0] == 100: blue_names += participant[1] + "\n" blue_champs += participant[2] + "\n" blue_rank += rank + "\n" else: red_names += participant[1] + "\n" red_champs += participant[2] + "\n" red_rank += rank + "\n" # Find the list of banned champions for both teams blue_ban, red_ban = self._get_banned_champions( spectate_info["bannedChampions"], champion_data) if description == "": description = "Playing an unknown gamemode/map -> Please update queue.json " # Format all of the live game info using a discord embed message embed = CacheHelper.getZileanEmbed(title="Live Game Info", description=description, footer="Live Game Info") embed.add_field(name=":large_blue_circle: Blue Team", value=blue_names, inline=True) embed.add_field(name="Rank", value=blue_rank, inline=True) embed.add_field(name="Champions:", value=blue_champs, inline=True) embed.add_field(name=":red_circle: Red Team", value=red_names, inline=True) embed.add_field(name="Rank", value=red_rank, inline=True) embed.add_field(name="Champions:", value=red_champs, inline=True) if "DRAFT" in pick_type: embed.add_field( name=":no_entry_sign: Red Team Bans :no_entry_sign:", value=red_ban, inline=True) embed.add_field( name=":no_entry_sign: Blue Team Bans :no_entry_sign:", value=blue_ban, inline=True) channel.send_message(embed=embed)
def on_summoner(self, event, summoner_name=None, region=None): '''Displays information about a League of Legends summoner''' # TODO: Tidy this up... # Prevent command quit on no region given if the discord user has bound a summoner to there account if region is None and summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists(region, summoner_name, event, event.msg.author.id) if not summoner: return version = LeagueHelper.get_champion_data()["version"] embed = CacheHelper.getZileanEmbed( title="Summoner Profile: ", footer="Displaying summoner info for " + summoner["name"], description=summoner["name"] + " " + region) embed.set_thumbnail(url="http://ddragon.leagueoflegends.com/cdn/" + version + "/img/profileicon/" + str(summoner["profileIconId"]) + ".png") embed.add_field(name="Summoner Level", value=str(summoner["summonerLevel"])) ranked_positions = self.league_helper.watcher.league.positions_by_summoner( region, summoner["id"]) ranks_array = ["RANKED SOLO 5x5", "RANKED FLEX TT", "RANKED FLEX SR"] for rank in ranked_positions: rank_name = rank["queueType"].replace("_", " ") embed.add_field(name="Queue Type", value=rank_name, inline=True) ranks_array.remove(rank_name) winrate = round( (rank["wins"] / (rank["wins"] + rank["losses"])) * 100) rank_msg = rank["tier"] + " " + rank["rank"] + " (" + str( rank["leaguePoints"]) + "lp)" winrate_msg = " | " + str(winrate) + "%" winloss_msg = " | W:" + str(rank["wins"]) + " L:" + str( rank["losses"]) embed.add_field(name="Rank | Wins/Losses | Winrate", value=rank_msg + winloss_msg + winrate_msg, inline=True) for rank in ranks_array: embed.add_field(name="Queue Type", value=rank, inline=True) embed.add_field(name="Rank | Wins/Losses | Winrate", value="UNRANKED", inline=True) try: matchlist = self.league_helper.watcher.match.matchlist_by_account( region, summoner["accountId"]) match = self.league_helper.watcher.match.by_id( region, matchlist["matches"][0]["gameId"]) for participant in match["participantIdentities"]: if participant["player"]["currentAccountId"] == summoner[ "accountId"]: target_player = participant for participant in match["participants"]: if participant["participantId"] == target_player[ "participantId"]: target_champion_id = participant["championId"] target_stats = str( participant["stats"]["kills"]) + "/" + str( participant["stats"]["deaths"]) + "/" + str( participant["stats"]["assists"]) target_team = participant["teamId"] for team in match["teams"]: if team["teamId"] == target_team: match_outcome = team["win"] if match_outcome == "Fail": match_outcome = "Defeat :x:" else: match_outcome = "Victory :white_check_mark:" target_champion = LeagueHelper.get_champion_data()["keys"][str( target_champion_id)] embed.add_field( name="Last Game Played:", value="**" + match_outcome + "**\n" + target_champion + " " + target_stats + " http://matchhistory.euw.leagueoflegends.com/en/#match-details/" + region + "/" + str(match["gameId"]) + "/" + str(summoner["accountId"]) + "?tab=overview") except HTTPError as err: if err.response.status_code == 404: embed.add_field( name="Last Game Played", value="This summoner has not recently played a game.") if not self.league_helper.user_in_game(region, summoner["id"]): embed.add_field( name="Live Game", value="This summoner is not currently in a live game.") else: embed.add_field( name="Live Game", value="This summoner is in a live game, type ~live_game " + region + " " + summoner_name + " for more info.") event.msg.reply(embed=embed)
def generate_build(self, event, champion, version): # For ChampionGG API Documentation: http://api.champion.gg/docs/#api-Champions-GetChampion # This sends a GET request to the championGG API and retrieves the champions highest winrate build champion_id = champion["key"] embed = CacheHelper.getZileanEmbed(title="Champion Build", description=champion["name"] + " " + champion["title"]) api_url = "http://api.champion.gg/v2/champions/" + champion_id + "?champData=hashes&api_key=" + self.key response = urllib.request.urlopen(api_url) build_info = json.loads(response.read().decode("utf-8"))[ 0] # Decode the byte response to json object # The above also stores the json dict and not the array of the dict # Retrieve hashes for the highest winrate build hashes = build_info["hashes"] skill_order = hashes["skillorderhash"]["highestWinrate"]["hash"].strip( "skill-") start_items = hashes["firstitemshash"]["highestWinrate"]["hash"].strip( "first-") final_items = hashes["finalitemshashfixed"]["highestWinrate"][ "hash"].strip("items-") rune_hash = hashes["runehash"]["highestWinrate"]["hash"] # Convert hashes into viewable strings items = LeagueHelper.get_item_data() runes = LeagueHelper.get_rune_data() start_items, start_build_urls = self.parse_item_hash( start_items, items, True) final_items, final_build_urls = self.parse_item_hash( final_items, items, True) rune_message_1, rune_message_2, rune_path_urls = self.parse_rune_hash( rune_hash, runes) skill_order = skill_order.replace("-", ">") # Generate the final build image self.generate_build_image(final_build_urls, "finalbuild.png") self.generate_build_image(start_build_urls, "startbuild.png") self.generate_build_image(rune_path_urls[0:5], "runepath1.png") self.generate_build_image(rune_path_urls[5:8], "runepath2.png") # Append and send message embed and images image_url = "http://ddragon.leagueoflegends.com/cdn/" + version + "/img/champion/" embed.set_thumbnail(url=image_url + champion["image"]["full"]) embed.add_field(name="ProBuilds: " + champion["name"], value="https://www.probuilds.net/champions/details/" + champion["name"]) embed.add_field(name="In-Depth Builds:", value="https://www.mobafire.com/league-of-legends/" + champion["name"] + "-guide?sort=patch&order=ascending&author=all&page=1") embed.add_field(name="Skill Order", value=skill_order) event.msg.reply(embed=embed) event.msg.reply("**Recommended Starting Items:**\n" + start_items, attachments=[("startbuild.png", open("startbuild.png", "rb"))]) event.msg.reply("**Recommended Final Build:**\n" + final_items, attachments=[("finalbuild.png", open("finalbuild.png", "rb"))]) event.msg.reply("**Recommended Runes:**\n" + rune_message_1, attachments=[("runepath1.png", open("runepath1.png", "rb"))]) event.msg.reply(rune_message_2, attachments=[("runepath2.png", open("runepath2.png", "rb"))])
class GraphCommands(Plugin): def load(self, ctx): super(GraphCommands, self).load(ctx) self.league_helper = LeagueHelper() @Plugin.pre_command() def on_command_event(self, command, event, args, kwargs): CacheHelper.log_command(command, event) return event @Plugin.command('games_per_month', "[summoner_name:str] [region:str]", group="graph", aliases=["gpm"]) def on_gpm_graph(self, event, summoner_name=None, region=None): """Displays a graph of the league games played per month per year""" region = LeagueHelper.validate_region(region, event) if region: gpm_graph = GamesPerMonthGraph(self.league_helper.watcher, region) if summoner_name is not None: filepath = "gpm-" + summoner_name + ".png" else: filepath = "gpm-default.png" self._graph_renderer(event, gpm_graph, summoner_name, region, filepath, match_validation=True) @Plugin.command("champion_mastery", "[summoner_name:str] [region:str]", group="graph", aliases=["cm"]) def on_cm_graph(self, event, summoner_name=None, region=None): """Displays a graph of the summoners top 5 champions by mastery""" region = LeagueHelper.validate_region(region, event) if region: cm_graph = ChampionMasteryGraph(self.league_helper.watcher, region, LeagueHelper.get_champion_data()) if summoner_name is not None: filepath = "cm-" + summoner_name + ".png" else: filepath = "cm-default.png" self._graph_renderer(event, cm_graph, summoner_name, region, filepath) @Plugin.command("champion_wins", "[summoner_name:str] [region:str]", group="graph", aliases=["cw"]) def on_cw_graph(self, event, summoner_name=None, region=None): """Displays a graph of your wins per individual champion over the last 20 games played""" region = LeagueHelper.validate_region(region, event) if region: cw_graph = ChampionWinsGraph(self.league_helper.watcher, region, LeagueHelper.get_champion_data()) if summoner_name is not None: filepath = "cw-" + summoner_name + ".png" else: filepath = "cw-default.png" self._graph_renderer(event, cw_graph, summoner_name, region, filepath, match_validation=True) @Plugin.command("kill_participation", "[summoner_name:str] [region:str]", group="graph", aliases=["kp"]) def on_kp_graph(self, event, summoner_name=None, region=None): """Displays a graph of your kill participation percentage over the last 20 games played""" region = LeagueHelper.validate_region(region, event) if region: kp_graph = KillParticipationGraph(self.league_helper.watcher, region, LeagueHelper.get_champion_data()) if summoner_name is not None: filepath = "kp-" + summoner_name + ".png" else: filepath = "kp-default.png" self._graph_renderer(event, kp_graph, summoner_name, region, filepath, match_validation=True) ''' @Plugin.command("living_time_vs_gold", "<region:str> <summoner_name:str...>", group="graph", aliases=["ltg"]) def on_ltg_graph(self, event, region, summoner_name): """Displays a scatter graph of your longest living time against your total gold earned for 100 recent games""" region = LeagueHelper.validate_region(region) if self._validate_region(event, region): ltg_graph = LivingTimeGold(self.league_helper.watcher, region, LeagueHelper.get_champion_data()) filepath = "ltg-" + summoner_name + ".png" self._graph_renderer(event, ltg_graph, summoner_name, region, filepath, match_validation=True) ''' def _graph_renderer(self, event, graph, summoner_name, region, filepath, match_validation=False): if summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): summoner_tuple = LiveDataHelper.load_summoner_binds()[str( event.msg.author.id)] summoner_name = summoner_tuple[0] region = summoner_tuple[1] graph.set_region(region) if not self.league_helper.has_match_history( region, summoner_name) and match_validation: event.msg.reply( "The summoner `" + summoner_name + "` does not exist on the region `" + region + "` or does not have enough games in their match history. Try again with a different summoner!" ) return elif self.league_helper.user_exists(region, summoner_name, event): event.msg.reply("Loading " + summoner_name + "'s data... :hourglass_flowing_sand:") result = graph.render(summoner_name, filepath) event.msg.reply(attachments=[(filepath, open(filepath, "rb"))]) if result is not None: event.msg.reply(result) os.remove(filepath)
class GameInfoCommands(Plugin): def load(self, ctx): super(GameInfoCommands, self).load(ctx) self.league_helper = LeagueHelper() @Plugin.pre_command() def on_command_event(self, command, event, args, kwargs): CacheHelper.log_command(command, event) return event @Plugin.command("patch", "[version:str]") def on_patch(self, event, version=None): '''Displays the latest patch notes for League of Legends''' s = "." if not version: version = s.join(LeagueHelper.get_champion_data()["version"].split( ".", 2)[:2]) version_url = version.replace(".", "") patch_url = "http://na.leagueoflegends.com/en/news/game-updates/patch/patch-" + version_url + "-notes" version_url = "http://ddragon.leagueoflegends.com/api/versions.json" with urllib.request.urlopen(version_url) as url: raw_json = json.loads(url.read().decode()) versionExists = False for patch in raw_json: if patch.startswith(version): versionExists = True if not versionExists: event.msg.reply( "This is not a valid patch number. Try ~patch for the most recent patch notes!" ) return embed = CacheHelper.getZileanEmbed( title="League of Legends Patch Notes", description=version + " Patch Notes", footer=version + " Patch Notes") embed.add_field(name="Notes", value=patch_url) event.msg.reply(embed=embed) @Plugin.command("status", "[region:str]") def on_status(self, event, region=None): '''Displays the status of the league of legends servers. Use ~status (region) for a more detailed breakdown''' if region: self._display_region_status(event, region) return embed = CacheHelper.getZileanEmbed( title="League of Legends Server Status", description= "Use ~status [region] for a more detailed breakdown of server status! Displayed below is the game status", footer="League of Legends Server Status") for endpoint in LeagueHelper.API_ENDPOINTS: endpoint_status = self.league_helper.watcher.lol_status.shard_data( endpoint) embed.add_field(name=endpoint_status["name"] + " (" + endpoint_status["slug"].upper() + ")", value=self._emojify_status( endpoint_status["services"][0]["status"]), inline=True) event.msg.reply(embed=embed) def _emojify_status(self, status): if status == "online": return ":white_check_mark:" else: return ":no_entry_sign:" def _display_region_status(self, event, region): region = LeagueHelper.validate_region(region) if region is None: event.msg.reply( "Please enter a valid **region**: *EUW, NA, EUN, JP, LAN, LAS, OCE, TR, RU, KR* :warning:" ) return embed = CacheHelper.getZileanEmbed( title="Zilean Bot", footer="League of Legends Server Status for " + region, description="Type ~status to see every regions status!") endpoint_status = self.league_helper.watcher.lol_status.shard_data( region) embed.add_field(name=endpoint_status["name"] + " (" + endpoint_status["slug"].upper() + ")", value="Server Status") services = endpoint_status["services"] for service in endpoint_status["services"]: embed.add_field(name=service["name"], value=self._emojify_status(service["status"]), inline=True) if len(service["incidents"]) != 0: embed.add_field(name="Incidents", value=str(len(service["incidents"])), inline=True) incident_msg = "" for incident in service["incidents"]: if len(incident["updates"]) != 0: recent_update = incident["updates"][0] incident_msg += incident["created_at"][ 0:10] + " " + recent_update["severity"].upper( ) + ": " + recent_update["content"] + "\n" embed.add_field(name="Incident Description", value=incident_msg, inline=True) else: embed.add_field(name="Incidents", value="No incidents!", inline=True) embed.add_field(name="Incident Description", value="N/A", inline=True) event.msg.reply(embed=embed) @Plugin.command('live_game', '"[summoner_name:str] [region:str]"') def on_live_game(self, event, summoner_name=None, region=None): '''Displays the live game info if a summoner is in a game. Supports all game types and ranked modes''' # Prevent command quit on no region given if the discord user has bound a summoner to there account if region is None and summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists(region, summoner_name, event, event.msg.author.id) if summoner: spectate_info = self.league_helper.user_in_game( region, summoner["id"]) if spectate_info: game_info = GameInfo(self.league_helper) game_info.display_live_game(event.msg.channel, region, spectate_info) else: event.msg.reply("This summoner `" + summoner["name"] + " " + region + "` is not currently in a game!") @Plugin.command("match_history", "[summoner_name:str] [region:str] [game_number:int]") def on_recent_game(self, event, summoner_name=None, region=None, game_number=0): '''Displays a match in the summoners match history, by default displays the most recent game''' game_number = game_number - 1 if game_number < 0: game_number = 0 # If we want users to have a summoner bound to them we have to deal with the game number being passed as the summoner_name... if region is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) try: game_number = int(summoner_name) game_number = game_number - 1 if game_number < 0: game_number = 0 summoner_name = None except ValueError as err: pass except TypeError as err: pass # If we want users to choose a match history game and use the default region for the server # Then the game number is actually passed to the region variable # So we swap them or just leave it if the game number they has passed is not an int if LiveDataHelper.guild_has_region( LiveDataHelper.load_region_binds(), str( event.guild.id)) and region is not None: try: game_number = int(region) game_number = game_number - 1 if game_number < 0: game_number = 0 region = None except ValueError as err: pass except TypeError as err: pass region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists(region, summoner_name, event, event.msg.author.id) if not summoner: return # TODO: has_match_history returns false if history < 20, need to change this... if not self.league_helper.has_match_history(region, summoner["name"]): event.msg.reply( "This summoner has no valid match history at this time `" + region + "`") return matchlist = self.league_helper.watcher.match.matchlist_by_account( region, summoner["accountId"]) if game_number > len(matchlist["matches"]): event.msg.reply( "The game number entered has exceeded the number of games available `Max Games: " + str(len(matchlist["matches"])) + "`") return else: game_info = GameInfo(self.league_helper) match = self.league_helper.watcher.match.by_id( region, matchlist["matches"][game_number]["gameId"]) game_info.display_past_game(event.msg.channel, region, match, summoner["accountId"]) @Plugin.command("item", "<item_name:str...>") def on_item(self, event, item_name): '''Searches and displays the corresponding league of legends item''' items = LeagueHelper.get_item_data() game_info = GameInfo(self.league_helper) item_found = False for key, value in items["data"].items(): if item_name.lower() in value["name"].lower( ) and len(item_name) > 3: game_info.display_item(event.msg.channel, items["version"], items["data"][key]) item_found = True if not item_found: event.msg.reply("This item does not exist...") @Plugin.command("champion", "<champion_name:str...>") def on_champion(self, event, champion_name): '''Searches and displays the corresponding league of legends champion''' champions = LeagueHelper.get_champion_data() game_info = GameInfo(self.league_helper) champ_found = False for key, name in champions["keys"].items(): if champion_name.lower() == name.lower(): game_info.display_champ(event.msg.channel, champions["version"], champions["data"][name]) champ_found = True if not champ_found: event.msg.reply( "This champion does not exist! Try ~champion Akali as an example..." ) @Plugin.command("ability", "<champion_name:str>, [ability:str]") def on_ability(self, event, champion_name, ability="all"): ''' Displays information about a specific champions ability ''' champions = LeagueHelper.get_champion_data() game_info = GameInfo(self.league_helper) abilities = ["q", "w", "e", "r", "passive", "all"] champ_found = False if ability.lower() in ["ult", "ultimate"]: ability = "r" elif ability.lower() not in abilities: event.msg.reply( "This is not a valid ability, Try from one of these " + str(abilities)) return for key, name in champions["keys"].items(): if champion_name.lower() == name.lower(): champ_found = True if ability == "all": game_info.display_champ(event.msg.channel, champions["version"], champions["data"][name]) else: game_info.display_ability(event.msg.channel, champions["version"], champions["data"][name], ability) if not champ_found: event.msg.reply( "This champion does not exist! Try ~ability Akali Q as an example..." ) @Plugin.command("summoner", "[summoner_name:str] [region:str]") def on_summoner(self, event, summoner_name=None, region=None): '''Displays information about a League of Legends summoner''' # TODO: Tidy this up... # Prevent command quit on no region given if the discord user has bound a summoner to there account if region is None and summoner_name is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists(region, summoner_name, event, event.msg.author.id) if not summoner: return version = LeagueHelper.get_champion_data()["version"] embed = CacheHelper.getZileanEmbed( title="Summoner Profile: ", footer="Displaying summoner info for " + summoner["name"], description=summoner["name"] + " " + region) embed.set_thumbnail(url="http://ddragon.leagueoflegends.com/cdn/" + version + "/img/profileicon/" + str(summoner["profileIconId"]) + ".png") embed.add_field(name="Summoner Level", value=str(summoner["summonerLevel"])) ranked_positions = self.league_helper.watcher.league.positions_by_summoner( region, summoner["id"]) ranks_array = ["RANKED SOLO 5x5", "RANKED FLEX TT", "RANKED FLEX SR"] for rank in ranked_positions: rank_name = rank["queueType"].replace("_", " ") embed.add_field(name="Queue Type", value=rank_name, inline=True) ranks_array.remove(rank_name) winrate = round( (rank["wins"] / (rank["wins"] + rank["losses"])) * 100) rank_msg = rank["tier"] + " " + rank["rank"] + " (" + str( rank["leaguePoints"]) + "lp)" winrate_msg = " | " + str(winrate) + "%" winloss_msg = " | W:" + str(rank["wins"]) + " L:" + str( rank["losses"]) embed.add_field(name="Rank | Wins/Losses | Winrate", value=rank_msg + winloss_msg + winrate_msg, inline=True) for rank in ranks_array: embed.add_field(name="Queue Type", value=rank, inline=True) embed.add_field(name="Rank | Wins/Losses | Winrate", value="UNRANKED", inline=True) try: matchlist = self.league_helper.watcher.match.matchlist_by_account( region, summoner["accountId"]) match = self.league_helper.watcher.match.by_id( region, matchlist["matches"][0]["gameId"]) for participant in match["participantIdentities"]: if participant["player"]["currentAccountId"] == summoner[ "accountId"]: target_player = participant for participant in match["participants"]: if participant["participantId"] == target_player[ "participantId"]: target_champion_id = participant["championId"] target_stats = str( participant["stats"]["kills"]) + "/" + str( participant["stats"]["deaths"]) + "/" + str( participant["stats"]["assists"]) target_team = participant["teamId"] for team in match["teams"]: if team["teamId"] == target_team: match_outcome = team["win"] if match_outcome == "Fail": match_outcome = "Defeat :x:" else: match_outcome = "Victory :white_check_mark:" target_champion = LeagueHelper.get_champion_data()["keys"][str( target_champion_id)] embed.add_field( name="Last Game Played:", value="**" + match_outcome + "**\n" + target_champion + " " + target_stats + " http://matchhistory.euw.leagueoflegends.com/en/#match-details/" + region + "/" + str(match["gameId"]) + "/" + str(summoner["accountId"]) + "?tab=overview") except HTTPError as err: if err.response.status_code == 404: embed.add_field( name="Last Game Played", value="This summoner has not recently played a game.") if not self.league_helper.user_in_game(region, summoner["id"]): embed.add_field( name="Live Game", value="This summoner is not currently in a live game.") else: embed.add_field( name="Live Game", value="This summoner is in a live game, type ~live_game " + region + " " + summoner_name + " for more info.") event.msg.reply(embed=embed) @Plugin.command("build", "<champion_name:str>") def on_build(self, event, champion_name): '''Displays the highest winrate championGG build for the given champion''' champions = LeagueHelper.get_champion_data() champ_found = False for key, name in champions["keys"].items(): if champion_name.lower() == name.lower(): champion_builder = ChampionGGHelper() champion_builder.generate_build(event, champions["data"][name], champions["version"]) champ_found = True if not champ_found: event.msg.reply( "This champion does not exist! Try ~champion Akali as an example..." )
def on_recent_game(self, event, summoner_name=None, region=None, game_number=0): '''Displays a match in the summoners match history, by default displays the most recent game''' game_number = game_number - 1 if game_number < 0: game_number = 0 # If we want users to have a summoner bound to them we have to deal with the game number being passed as the summoner_name... if region is None and LiveDataHelper.user_is_bound( LiveDataHelper.load_summoner_binds(), str( event.msg.author.id)): region = LiveDataHelper.get_user_bound_region( str(event.msg.author.id)) try: game_number = int(summoner_name) game_number = game_number - 1 if game_number < 0: game_number = 0 summoner_name = None except ValueError as err: pass except TypeError as err: pass # If we want users to choose a match history game and use the default region for the server # Then the game number is actually passed to the region variable # So we swap them or just leave it if the game number they has passed is not an int if LiveDataHelper.guild_has_region( LiveDataHelper.load_region_binds(), str( event.guild.id)) and region is not None: try: game_number = int(region) game_number = game_number - 1 if game_number < 0: game_number = 0 region = None except ValueError as err: pass except TypeError as err: pass region = LeagueHelper.validate_region(region, event) if region is None: return summoner = self.league_helper.user_exists(region, summoner_name, event, event.msg.author.id) if not summoner: return # TODO: has_match_history returns false if history < 20, need to change this... if not self.league_helper.has_match_history(region, summoner["name"]): event.msg.reply( "This summoner has no valid match history at this time `" + region + "`") return matchlist = self.league_helper.watcher.match.matchlist_by_account( region, summoner["accountId"]) if game_number > len(matchlist["matches"]): event.msg.reply( "The game number entered has exceeded the number of games available `Max Games: " + str(len(matchlist["matches"])) + "`") return else: game_info = GameInfo(self.league_helper) match = self.league_helper.watcher.match.by_id( region, matchlist["matches"][game_number]["gameId"]) game_info.display_past_game(event.msg.channel, region, match, summoner["accountId"])
def load(self, ctx): super(GameInfoCommands, self).load(ctx) self.league_helper = LeagueHelper()