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..." )
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)