Giter Site home page Giter Site logo

knutzuidema / golio Goto Github PK

View Code? Open in Web Editor NEW
70.0 5.0 28.0 315 KB

League of Legends, Legends of Runeterra and Valorant API client library for Go

License: MIT License

Go 100.00%
riot-api api-client league-of-legends datadragon-api golang go lol legends-of-runeterra lor valorant

golio's Introduction

Documentation CI Go Report Card codecov

Golio

Golio is a wrapper for the Riot API and the Data Dragon service. It is written purely in Go and provides idiomatic access to all API endpoints.

Example

package main

import (
	"fmt"

	"github.com/KnutZuidema/golio"
	"github.com/KnutZuidema/golio/api"
	"github.com/KnutZuidema/golio/riot/lol"
	"github.com/sirupsen/logrus"
)

func main() {
	client := golio.NewClient("API KEY",
		golio.WithRegion(api.RegionEuropeWest),
		golio.WithLogger(logrus.New().WithField("foo", "bar")))
	summoner, _ := client.Riot.LoL.Summoner.GetByName("SK Jenax")
	fmt.Printf("%s is a level %d summoner\n", summoner.Name, summoner.SummonerLevel)
	champion, _ := client.DataDragon.GetChampion("Ashe")
	mastery, err := client.Riot.LoL.ChampionMastery.Get(summoner.ID, champion.Key)
	if err != nil {
		fmt.Printf("%s has not played any games on %s\n", summoner.Name, champion.Name)
	} else {
		fmt.Printf("%s has mastery level %d with %d points on %s\n", summoner.Name, mastery.ChampionLevel,
			mastery.ChampionPoints, champion.Name)
	}
	challengers, _ := client.Riot.LoL.League.GetChallenger(lol.QueueRankedSolo)
	rank1 := challengers.GetRank(0)
	fmt.Printf("%s is the highest ranked player with %d league points\n", rank1.SummonerName, rank1.LeaguePoints)
}

golio's People

Contributors

algorithme avatar ayuei avatar davidbayo10 avatar duskrunner avatar hanscauwenbergh avatar happsie avatar harmonherring avatar ironpark avatar knutzuidema avatar nggialac avatar nico-mayer avatar pixelrazor avatar yigithanbalci avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

golio's Issues

Expand documentation

Provide documentation describing the general use of each package
Provide documentation examples for all exported methods

If you call GetChampions() after calling GetChampion(championName), you only see a limited number of results

If you call GetChampion("Ashe") and then you call GetChampions(), you will only receive a list containing Ashe.

I'm not sure this is expected and I wonder if the cache used for GetChampion shouldn't be different.

IMHO, I would first check in GetChampions Cache if Ashe is available, then in GetChampion Cache and when I get the result I would only store it in GetChampion Cache.

If you want I can fix it for you ?

separate riot api endpoints by category

The riot api client is very large
To alleviate this and increase maintainability the different endpoint methods should be separated by category so the usage can look like this:

client.Riot.Summoner.GetByID("id")

Matches V5

With upcoming deprecation to Matches v4, we should change the MatchesClient to use the V5 endpoint and tag a new release once production API keys are accepted on these endpoints (estimated to be mid july)

The addition of this endpoint also introduces 'routing values' ->

The AMERICAS routing value serves NA, BR, LAN, LAS, and OCE. The ASIA routing value serves KR and JP. The EUROPE routing value serves EUNE, EUW, TR, and RU.

The Client will need to be able to make requests to the appropriate routing value based off of region. ex:
na1 -> americas

At the time of writing, the spectator eendpoint isn't getting a v5, and those match IDS should be convertible by using the followwing format:
ToUpper(spectatorRegion)_matchID
ex: NA1_123456789

Is this library thread safe?

Just trying to figure out if I can use this the way I'd like. I'd like to create a global var client for each region and use each client whenever I need, in separate goroutines. Will that work or will it screw with the caching?

Are there any particular directions you're looking to take this library other than what's mentioned in the issues? Would love to help out wherever I can :)

add statPerk0~2 field from ParticipantStats model

statPerk0,statPerk1,statPerk2

statPerk0,statPerk1,statPerk2 dose not define "ParticipantStatsDto" from api document getMatch API

However, the response results include statPerk0, statPerk1, and statPerk2, which are necessary to record the total rune information for each player.

API response example (participants part)

    {
            "participantId": 3,
            "teamId": 100,
            "championId": 240,
            "spell1Id": 12,
            "spell2Id": 4,
            "stats": {
                "participantId": 3,
                "win": false,
                "item0": 3077,
                "item1": 2033,
                "item2": 3044,
                "item3": 1055,
                "item4": 3047,
                "item5": 3067,
                "item6": 3340,
                "kills": 0,
                "deaths": 7,
                "assists": 6,
                "largestKillingSpree": 0,
                "largestMultiKill": 0,
                "killingSprees": 0,
                "longestTimeSpentLiving": 279,
                "doubleKills": 0,
                "tripleKills": 0,
                "quadraKills": 0,
                "pentaKills": 0,
                "unrealKills": 0,
                "totalDamageDealt": 38746,
                "magicDamageDealt": 67,
                "physicalDamageDealt": 38667,
                "trueDamageDealt": 12,
                "largestCriticalStrike": 0,
                "totalDamageDealtToChampions": 7427,
                "magicDamageDealtToChampions": 67,
                "physicalDamageDealtToChampions": 7348,
                "trueDamageDealtToChampions": 12,
                "totalHeal": 840,
                "totalUnitsHealed": 1,
                "damageSelfMitigated": 15012,
                "damageDealtToObjectives": 3697,
                "damageDealtToTurrets": 2531,
                "visionScore": 6,
                "timeCCingOthers": 4,
                "totalDamageTaken": 20944,
                "magicalDamageTaken": 7715,
                "physicalDamageTaken": 12744,
                "trueDamageTaken": 484,
                "goldEarned": 6018,
                "goldSpent": 5925,
                "turretKills": 0,
                "inhibitorKills": 0,
                "totalMinionsKilled": 87,
                "neutralMinionsKilled": 4,
                "neutralMinionsKilledTeamJungle": 1,
                "neutralMinionsKilledEnemyJungle": 0,
                "totalTimeCrowdControlDealt": 33,
                "champLevel": 10,
                "visionWardsBoughtInGame": 0,
                "sightWardsBoughtInGame": 0,
                "wardsPlaced": 2,
                "wardsKilled": 2,
                "firstBloodKill": false,
                "firstBloodAssist": false,
                "firstTowerKill": false,
                "firstTowerAssist": false,
                "firstInhibitorKill": false,
                "firstInhibitorAssist": false,
                "combatPlayerScore": 0,
                "objectivePlayerScore": 0,
                "totalPlayerScore": 0,
                "totalScoreRank": 0,
                "playerScore0": 0,
                "playerScore1": 0,
                "playerScore2": 0,
                "playerScore3": 0,
                "playerScore4": 0,
                "playerScore5": 0,
                "playerScore6": 0,
                "playerScore7": 0,
                "playerScore8": 0,
                "playerScore9": 0,
                "perk0": 8010,
                "perk0Var1": 339,
                "perk0Var2": 0,
                "perk0Var3": 0,
                "perk1": 9111,
                "perk1Var1": 562,
                "perk1Var2": 120,
                "perk1Var3": 0,
                "perk2": 9104,
                "perk2Var1": 0,
                "perk2Var2": 0,
                "perk2Var3": 0,
                "perk3": 8299,
                "perk3Var1": 318,
                "perk3Var2": 0,
                "perk3Var3": 0,
                "perk4": 8446,
                "perk4Var1": 589,
                "perk4Var2": 0,
                "perk4Var3": 0,
                "perk5": 8473,
                "perk5Var1": 951,
                "perk5Var2": 0,
                "perk5Var3": 0,
                "perkPrimaryStyle": 8000,
                "perkSubStyle": 8400,
                "statPerk0": 5005,
                "statPerk1": 5008,
                "statPerk2": 5002
            },

Proposed changes

// ParticipantStats contains stats of a participant in a game
type ParticipantStats struct {
	// ...............
	// Primary rune path
	PerkPrimaryStyle int `json:"perkPrimaryStyle"`
	// Secondary rune path
	PerkSubStyle int `json:"perkSubStyle"`
	// Primary path keystone rune.
	Perk0     int `json:"perk0"`
	Perk0Var1 int `json:"perk0Var1"`
	Perk0Var2 int `json:"perk0Var2"`
	Perk0Var3 int `json:"perk0Var3"`
	// Primary path rune.
	Perk1     int `json:"perk1"`
	Perk1Var1 int `json:"perk1Var1"`
	Perk1Var2 int `json:"perk1Var2"`
	Perk1Var3 int `json:"perk1Var3"`
	// Primary path rune.
	Perk2     int `json:"perk2"`
	Perk2Var1 int `json:"perk2Var1"`
	Perk2Var2 int `json:"perk2Var2"`
	Perk2Var3 int `json:"perk2Var3"`
	// Primary path rune.
	Perk3     int `json:"perk3"`
	Perk3Var1 int `json:"perk3Var1"`
	Perk3Var2 int `json:"perk3Var2"`
	Perk3Var3 int `json:"perk3Var3"`
	// Secondary path rune.
	Perk4     int `json:"perk4"`
	Perk4Var1 int `json:"perk4Var1"`
	Perk4Var2 int `json:"perk4Var2"`
	Perk4Var3 int `json:"perk4Var3"`
	// Secondary path rune.
	Perk5     int `json:"perk5"`
	Perk5Var1 int `json:"perk5Var1"`
	Perk5Var2 int `json:"perk5Var2"`
	Perk5Var3 int `json:"perk5Var3"`
        // ========================================= Hear !! ++
	StatPerk0 int `json:"statPerk0"`
	StatPerk1 int `json:"statPerk1"`
	StatPerk2 int `json:"statPerk2"`
        // =========================================
}

Since English is not my native language, there may be awkward or misleading expressions.

client.DataDragon.GetChampion() fails for Champions with spaces or apostrophes

Currently client.DataDragon.GetChampion() fails for specific champions, or at least for me, I went ahead and tested it with a slightly changed version of your example code:

package main

import (
	"fmt"

	"github.com/KnutZuidema/golio"
	"github.com/KnutZuidema/golio/api"
	"github.com/KnutZuidema/golio/riot/lol"
	"github.com/sirupsen/logrus"
)

func main() {
	client := golio.NewClient("",
		golio.WithRegion(api.RegionEuropeWest),
		golio.WithLogger(logrus.New().WithField("foo", "bar")))
	summoner, _ := client.Riot.Summoner.GetByName("Herndl")
	fmt.Printf("%s is a level %d summoner\n", summoner.Name, summoner.SummonerLevel)
	champion, _ := client.DataDragon.GetChampion("Kai'Sa") // Doesn't work with Kai'Sa, Kaisa, KaiSa, or kaisa
	mastery, err := client.Riot.ChampionMastery.Get(summoner.ID, champion.Key)
	if err != nil {
		fmt.Printf("%s has not played any games on %s\n", summoner.Name, champion.ChampionData.Name)
	} else {
		fmt.Printf("%s has mastery level %d with %d points on %s\n", summoner.Name, mastery.ChampionLevel,
			mastery.ChampionPoints, champion.Name)
	}
	challengers, _ := client.Riot.League.GetChallenger(lol.QueueRankedSolo)
	rank1 := challengers.GetRank(0)
	fmt.Printf("%s is the highest ranked player with %d league points\n", rank1.SummonerName, rank1.LeaguePoints)
}

Output for Kai'Sa:

Herndl is a level 455 summoner
Herndl has not played any games on 
Destined 2 Win is the highest ranked player with 1311 league points

Output for Ashe:

Herndl is a level 455 summoner
Herndl has mastery level 5 with 43637 points on Ashe
Destined 2 Win is the highest ranked player with 1311 league points

More options to "MatchClient"

More options to "MatchClient"

/lol/match/v4/matchlists/by-account/{encryptedAccountId}

  • champion
  • queue
  • season
  • beginTime
  • endTime
  • beginIndex
  • endIndex

It has a total of 7 optional parameters. Since the season is DEPRECATED, in the remaining 6 cases, the current golio library supports only beginIndex and endIndex. The rest of the parameters are also useful depending on the situation, so I think it is better to support the rest. However, if all the parameters are supported, the following method is proposed as the function argument will be greatly enlarged..

Option Struct

import (
  "github.com/KnutZuidema/golio/api"
  "github.com/KnutZuidema/golio/riot/lol"
)

func main(){
  ...
  client.Riot.LoL.Match.List(accountId, lol.MatchListOption{
    BeginIndex:1,
    EndTime: ...,
    ...
  })
}

Option Function

import (
  "github.com/KnutZuidema/golio/api"
  "github.com/KnutZuidema/golio/riot/lol"
  "time"
)

func main(){
  ...
  client.Riot.LoL.Match.List(accountId,
     lol.Index(0,100),
     lol.BeginTime(time.Now().Add(-time.Second*100)
  ))
}

Builder

import (
  "github.com/KnutZuidema/golio/api"
  "github.com/KnutZuidema/golio/riot/lol"
  "time"
)

func main(){
  ...
  client.Riot.LoL.Match.Request().
    List().
    Index(0,100).
    BeginTime(time.Now().Add(-time.Second*100).
    Do()
}

Found an error in the example

challengers, _ := client.Riot.League.GetChallenger(api.QueueRankedSolo)
QueueRankedSolo not declared by package api

The real path is:
github.com/KnutZuidema/golio/riot/lol

Support for RiotID

Hey, first of all, great work on building this library. I'm wondering if there are plans to update the project to support the new Riot ID system with the Summonername#tag syntax in the future. Keep up the excellent work.

Best regards,
Nico

Support for Request Contexts

It doesn't look like any of these requests support caller-defined contexts. @KnutZuidema would you support it if I opened a PR that adds ...WithContext functions for all existing API requests?

For example, I'd add GetByAccountIDWithContext(ctx context.Context, ...), GetByPUUIDWithContext(ctx context.Context, ...) etc etc for summoner routes.

I'm thinking I'd bubble that context down to a duplicate Client.DoRequestWithContext(ctx context.Context, ...) that adds a context to the request with request.WithContext

New endpoint prefixes

Since some time now the League of Legends API uses the /lol prefix instead of /riot

datadragon.ChampionData.ID returns name of the Champion instead of the actual ID.

I am currently working on a small scale Discord Bot with some League of Legends functionality and stumbled opon a problem with the DataDragon.GetChampionByID() function. To my knowledge every champ should have an numerical ID, for example Vayne has the ID 67, as returned by the ChampionMastery data, but using the ByID function returns nothing when passing in 67.

A sample:

func main() {
	client := golio.NewClient("KEY",
		golio.WithRegion(api.RegionEuropeWest))
	summoner, _ := client.Riot.Summoner.GetByName("Herndl")
	masteryList, _ := client.Riot.LoL.ChampionMastery.List(summoner.ID)
	fmt.Printf("ID: %v\n", masteryList[0].ChampionID)
	champion, _ := client.DataDragon.GetChampion("Vayne")
	fmt.Printf("ID without ByID: %s\n", champion.ID)
	IdToString := fmt.Sprintf("%v", masteryList[0].ChampionID) // convert int to string
	championByID, err := client.DataDragon.GetChampionByID(IdToString)
	fmt.Printf("%T\n", IdToString)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("ID with ByID: %s", championByID.ID)
}

Output of the sample:

ID: 67
ID without ByID: Vayne
string
not found
ID with ByID:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.