示例#1
0
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..."
            )
示例#2
0
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)