rito 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b88f9486b198ec08703fb9124aaea6d20d8c7313488d61d06541d289b7caf8b
4
- data.tar.gz: a5acab9fe9d2cd25ca2e1a64e674d3ffc61e7ce3ae46896e4947a8dc93c267a3
3
+ metadata.gz: 9088da4cb186a04b00b160ac7ee8ddaf8c26bb7f48e10f4db80c20bb5d2dff7b
4
+ data.tar.gz: 7323a3cf554a3f60c8f85ee05635e74101cd767d3befe47ca5e467f6bfc61cc3
5
5
  SHA512:
6
- metadata.gz: 381057a97d7fd77f04f13cfcaa8e394d472dd1dbe4bafb7aef1ad8c696a681587c4ced5db2e93a1d1d120ca76ca7e603d7be701954e91b650f04a7d83d7d28c9
7
- data.tar.gz: 783a2bdf9c817180d9caa160ec9429af4cf34a3df15b69382c5c653dc49cb5a1c909b87ef58277233c8990cfdfc588259892f8b776bc24ea11e22e64fe0ff55c
6
+ metadata.gz: 8fa6f315096ecbf7cdb8ac2dc72b31e39c37bcaffa4f2d1a81e4b62f44737fc5611a89d253191d19835b4048c57feb608fd91ea1cdf61d02b84e3fe81e3f6998
7
+ data.tar.gz: 40775c60207a3e639c5590680285ad4ccd6271c257588c6d29bee31c998baa19efd45468bab04063e0eee52c94426aaf127c77a407f5f9159583d8b249f40fe4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0 (2026-09-05)
4
+
5
+ Aligned the endpoint surface with the current Riot API reference
6
+ (cross-checked against riotapi-schema). **Breaking:** phantom endpoints
7
+ Riot has removed were dropped, and outdated paths were corrected.
8
+
9
+ - **Removed (no longer in the API docs)**: summoner-v4 `by_name` /
10
+ `by_account_id` / `by_summoner_id`; TFT summoner `by_account_id` /
11
+ `by_summoner_id`; spectator-v5 and spectator-tft-v5 `featured_games`;
12
+ league-v4 `league(leagueId)` and `entries_by_summoner_id`; TFT league
13
+ `entries_by_summoner_id`; clash `players_by_summoner_id`; LoR
14
+ `decks.deck(deck_id)`; tournament-stub `update_code`.
15
+ - **Renamed/fixed paths**: spectator active games (`by-summoner-id` →
16
+ `by-summoner/{puuid}`, TFT: `by-puuid/{puuid}`), TFT league routing is
17
+ platform (`na1`), not regional; tournament-v5/stub code paths
18
+ (`codes/by-code/{code}` → `codes/{code}`); challenges leaderboard param
19
+ `top`/`page` → `limit`.
20
+ - **Added**: `lol-rso-match-v1` (`client.rso_matches` — RSO bearer token;
21
+ `ids`, `by_id`, `timeline_by_id`), `val-console-ranked-v1`
22
+ (`client.val.console_ranked` with required `platform_type:`),
23
+ match-v5 `replays`, tournament-v5 `games_by_code`, clash
24
+ `tournament(tournamentId)`, league-v4 `entries_by_puuid`, TFT league
25
+ `entries_by_puuid` / `entries(tier, division)`, challenges
26
+ `challenge_config` / `challenge_percentiles`, summoner-v4 `me` (RSO),
27
+ LoR `decks.create_deck` (POST).
28
+ - **Queues reference**: `Rito::Queues` — frozen snapshot of the League
29
+ client's game select data (408 queue ids) with name, description,
30
+ category (`:pvp` / `:bots` / `:custom`), mode, limited-time and bot
31
+ flags; `MatchInfo#queue` resolves a match's `queueId`.
32
+ - **Routing**: VALORANT platform `na1` → `na`; VALORANT platforms accept
33
+ `esports` (content/match only) and console accepts `br`/`latam`
34
+ (console match); dropped dead `ph2`/`th2`; added `pbe1` (challenges,
35
+ status) and `esports`/`esportseu` regionals (tft-match-v1).
36
+
37
+ ## 0.2.0 (2026-09-05)
38
+
39
+ - **Riot Sign On (RSO)**: new `Rito::RSO` module implementing the OAuth2
40
+ authorization code flow against `auth.riotgames.com`:
41
+ `authorization_url` (with generated CSRF state), `exchange_code`,
42
+ `refresh`, `userinfo`, and `verify_id_token` (RS256 signature +
43
+ iss/aud/exp validation via `/jwks.json`, with key-rotation-aware
44
+ refetch). Token requests support `client_secret` basic, a static
45
+ `client_assertion` (the RSO "100 year token"), or minted private-key
46
+ JWT client assertions from an RSA `private_key`. Zero new runtime
47
+ dependencies (stdlib `openssl`).
48
+
3
49
  ## 0.1.3 (2026-09-05)
4
50
 
5
51
  - CI: publish via `rubygems/release-gem` so releases carry a Sigstore
data/README.md CHANGED
@@ -44,6 +44,103 @@ Rito.rate_limiter # rate limit strategy (default: AdaptiveLimiter)
44
44
  client = Rito::Client.new(api_key: "RGAPI-...", region: :kr)
45
45
  ```
46
46
 
47
+ ## Queues
48
+
49
+ `Rito::Queues` is a frozen, built-in reference for League queue ids as
50
+ they appear in match data (match-v5 `queueId`, the `queue` filter on
51
+ match lists). Snapshot of the League client's game select data (408 ids).
52
+
53
+ ```ruby
54
+ Rito::Queues.find(420).name # => "Ranked Solo/Duo"
55
+ Rito::Queues[450].mode # => :aram
56
+ Rito::Queues.find(2450).limited_time # => true (rotating game mode)
57
+ Rito::Queues.select { |q| q.category == :bots }.map(&:name).first(3)
58
+
59
+ match = client.matches.by_id("NA1_123")
60
+ match.info.queue.name # => "Ranked Flex" (convenience on MatchInfo)
61
+ ```
62
+
63
+ Each queue is a frozen `Data` object: `id`, `name`, `short_name`,
64
+ `description`, `detailed_description`, `category` (`:pvp`, `:bots`,
65
+ `:custom`), `mode` (`:summoners_rift`, `:aram`, `:tft`, `:jade`,
66
+ `:other`), `limited_time`, `bot_honoring_allowed`. The module includes
67
+ `Enumerable`. Unknown ids return `nil` (Riot adds queues without notice).
68
+
69
+ ## Riot Sign On (RSO)
70
+
71
+ `Rito::RSO` implements the OAuth2 authorization code flow against
72
+ `https://auth.riotgames.com`. Register a client with Riot first; the
73
+ redirect URI must be on its allowlist.
74
+
75
+ ```ruby
76
+ rso = Rito::RSO::Client.new(
77
+ client_id: ENV.fetch("RIOT_RSO_CLIENT_ID"),
78
+ client_secret: ENV.fetch("RIOT_RSO_CLIENT_SECRET"), # or client_assertion: / private_key:
79
+ redirect_uri: "https://app.example.com/oauth2-callback"
80
+ )
81
+
82
+ # 1. Send the player to Riot; persist request.state to compare on callback
83
+ login = rso.authorization_url(login_hint: "na1|daguava")
84
+ login.url # => "https://auth.riotgames.com/authorize?..."
85
+ login.state
86
+
87
+ # 2. Exchange the ?code= query param from the callback for tokens
88
+ tokens = rso.exchange_code(params[:code])
89
+ tokens.access_token # Bearer token for RSO resources (encrypted, opaque)
90
+ tokens.id_token # signed JWT identity token
91
+ tokens.refresh_token # signed JWT, self-contained
92
+ tokens.expires_in # 600
93
+
94
+ # 3. Identify the player
95
+ me = rso.userinfo(tokens.access_token)
96
+ me.sub # player sub claim
97
+ me.cpid # "NA1" when the cpid scope was requested
98
+
99
+ # 4. Rotate when the access token expires
100
+ tokens = rso.refresh(tokens.refresh_token)
101
+ ```
102
+
103
+ Newer RSO clients authenticate with private-key JWT instead of a secret
104
+ (the gem mints a fresh signed assertion per token request):
105
+
106
+ ```ruby
107
+ rso = Rito::RSO::Client.new(
108
+ client_id: ENV.fetch("RIOT_RSO_CLIENT_ID"),
109
+ private_key: OpenSSL::PKey::RSA.new(ENV.fetch("RIOT_RSO_PRIVATE_KEY")),
110
+ redirect_uri: "https://app.example.com/oauth2-callback"
111
+ )
112
+ ```
113
+
114
+ or pass the pre-signed client assertion (the "100 year token") via
115
+ `client_assertion:` and treat it like a password.
116
+
117
+ ### Verifying the ID token
118
+
119
+ ```ruby
120
+ claims = rso.verify_id_token(tokens.id_token)
121
+ claims["sub"] # => signature (RS256 via /jwks.json) + iss/aud/exp validated
122
+ ```
123
+
124
+ `verify_id_token` caches the JWKS document and refetches it once when a
125
+ `kid` is unknown (Riot rotates keypairs without disabling old ones).
126
+ Any failure raises `Rito::RSO::InvalidToken`. Token and userinfo failures
127
+ raise `Rito::RSO::OAuthError` with `.error_code` / `.error_description`.
128
+
129
+ ### RSO configuration
130
+
131
+ ```ruby
132
+ Rito::RSO.client_id # default: ENV["RIOT_RSO_CLIENT_ID"]
133
+ Rito::RSO.client_secret # default: ENV["RIOT_RSO_CLIENT_SECRET"]
134
+ Rito::RSO.client_assertion # default: ENV["RIOT_RSO_CLIENT_ASSERTION"]
135
+ Rito::RSO.private_key
136
+ Rito::RSO.redirect_uri # default: ENV["RIOT_RSO_REDIRECT_URI"]
137
+ Rito::RSO.scope # default: "openid" (add cpid / offline_access)
138
+ ```
139
+
140
+ Per-instance kwargs override the module config. Token requests are never
141
+ retried (authorization codes and refresh tokens are one-time), so handle
142
+ failures explicitly.
143
+
47
144
  ## Routing values
48
145
 
49
146
  Endpoints declare whether they are platform-routed (`na1`, `kr`, ...) or
@@ -124,9 +221,10 @@ entry.raw # => full payload hash
124
221
 
125
222
  | Accessor | API |
126
223
  | --- | --- |
127
- | `client.account` | account-v1 |
128
- | `client.summoner` | summoner-v4 |
129
- | `client.matches` | match-v5 (matches, matchlist, timeline) |
224
+ | `client.account` | account-v1 (accounts, active shards, region, `me` for RSO) |
225
+ | `client.summoner` | summoner-v4 (`by_puuid`, `me` for RSO) |
226
+ | `client.matches` | match-v5 (matches, matchlist, timeline, replays) |
227
+ | `client.rso_matches` | lol-rso-match-v1 (RSO bearer token; player resolved from the token) |
130
228
  | `client.champion_masteries` | champion-mastery-v4 |
131
229
  | `client.champions` | champion-v3 (rotations) |
132
230
  | `client.leagues` / `client.league_exp` | league-v4 / league-exp-v4 |
@@ -136,12 +234,16 @@ entry.raw # => full payload hash
136
234
  | `client.challenges` | lol-challenges-v1 |
137
235
  | `client.tournaments` / `client.tournament_stub` | tournament-v5 / stub-v5 |
138
236
  | `client.tft.summoner` / `.leagues` / `.matches` / `.status` / `.spectator` | tft-summoner-v1, tft-league-v1, tft-match-v1, tft-status-v1, spectator-tft-v5 |
139
- | `client.val.content` / `.matches` / `.console_matches` / `.ranked` / `.status` | val-content-v1, val-match-v1, val-console-match-v1, val-ranked-v1, val-status-v1 |
237
+ | `client.val.content` / `.matches` / `.console_matches` / `.ranked` / `.console_ranked` / `.status` | val-content-v1, val-match-v1, val-console-match-v1, val-ranked-v1, val-console-ranked-v1, val-status-v1 |
140
238
  | `client.lor.matches` / `.ranked` / `.status` / `.decks` / `.inventory` | lor-match-v1, lor-ranked-v1, lor-status-v1, lor-deck-v1 / lor-inventory-v1 (RSO) |
141
239
  | `client.riftbound` | riftbound-content-v1 |
142
240
 
143
- Note: VALORANT uses its own platform routing values (`na1, eu, ap, kr, latam, br`;
144
- console: `na, eu, ap`) — the client validates against the right set per product.
241
+ Note: VALORANT uses its own platform routing values (`na, eu, ap, kr,
242
+ latam, br`; console: `na, eu, ap, br, latam`) — the client validates
243
+ against the right set per product. `esports` is a valid platform for
244
+ VALORANT content/match and a valid regional for tft-match-v1 (with
245
+ `esportseu`). The tournament endpoints only exist on the `americas`
246
+ platform — pass `region: :na1` or `:americas`.
145
247
 
146
248
  ## Testing your own app
147
249
 
data/lib/rito/client.rb CHANGED
@@ -32,6 +32,10 @@ module Rito
32
32
  Endpoints::Lol::MatchV5.new(self)
33
33
  end
34
34
 
35
+ def rso_matches
36
+ Endpoints::Lol::RsoMatchV1.new(self)
37
+ end
38
+
35
39
  def champion_masteries
36
40
  Endpoints::Lol::ChampionMasteryV4.new(self)
37
41
  end
@@ -10,14 +10,21 @@ module Rito
10
10
  get('/lol/challenges/v1/challenges/config', region)
11
11
  end
12
12
 
13
+ def challenge_config(challenge_id, region: nil)
14
+ get("/lol/challenges/v1/challenges/#{escape(challenge_id)}/config", region)
15
+ end
16
+
13
17
  def percentiles(region: nil)
14
18
  get('/lol/challenges/v1/challenges/percentiles', region)
15
19
  end
16
20
 
17
- def leaderboard(challenge_id, level, top: nil, page: nil, region: nil)
21
+ def challenge_percentiles(challenge_id, region: nil)
22
+ get("/lol/challenges/v1/challenges/#{escape(challenge_id)}/percentiles", region)
23
+ end
24
+
25
+ def leaderboard(challenge_id, level, limit: nil, region: nil)
18
26
  params = {}
19
- params['top'] = top if top
20
- params['page'] = page if page
27
+ params['limit'] = limit if limit
21
28
  get("/lol/challenges/v1/challenges/#{escape(challenge_id)}/leaderboards/by-level/#{escape(level)}", region,
22
29
  params: params)
23
30
  end
@@ -6,8 +6,8 @@ module Rito
6
6
  class ClashV1 < Base
7
7
  ROUTING = :platform
8
8
 
9
- def players_by_summoner_id(summoner_id, region: nil)
10
- get("/lol/clash/v1/players/by-summoner/#{escape(summoner_id)}", region)
9
+ def players_by_puuid(puuid, region: nil)
10
+ get("/lol/clash/v1/players/by-puuid/#{escape(puuid)}", region)
11
11
  end
12
12
 
13
13
  def team(team_id, region: nil)
@@ -18,6 +18,10 @@ module Rito
18
18
  get('/lol/clash/v1/tournaments', region)
19
19
  end
20
20
 
21
+ def tournament(tournament_id, region: nil)
22
+ get("/lol/clash/v1/tournaments/#{escape(tournament_id)}", region)
23
+ end
24
+
21
25
  def tournament_by_team(team_id, region: nil)
22
26
  get("/lol/clash/v1/tournaments/by-team/#{escape(team_id)}", region)
23
27
  end
@@ -24,8 +24,8 @@ module Rito
24
24
  )
25
25
  end
26
26
 
27
- def entries_by_summoner_id(summoner_id, region: nil)
28
- get("/lol/league/v4/entries/by-summoner/#{escape(summoner_id)}", region)
27
+ def entries_by_puuid(puuid, region: nil)
28
+ get("/lol/league/v4/entries/by-puuid/#{escape(puuid)}", region)
29
29
  .map { |hash| Models::LeagueEntry.from_api(hash) }
30
30
  end
31
31
 
@@ -35,12 +35,6 @@ module Rito
35
35
  get("/lol/league/v4/entries/#{escape(tier)}/#{escape(division)}", region, params: params)
36
36
  .map { |hash| Models::LeagueEntry.from_api(hash) }
37
37
  end
38
-
39
- def league(league_id, region: nil)
40
- Models::LeagueList.from_api(
41
- get("/lol/league/v4/leagues/#{escape(league_id)}", region)
42
- )
43
- end
44
38
  end
45
39
 
46
40
  class LeagueExpV4 < Base
@@ -28,6 +28,12 @@ module Rito
28
28
  def timeline_by_id(match_id, region: nil)
29
29
  get("/lol/match/v5/matches/#{escape(match_id)}/timeline", region)
30
30
  end
31
+
32
+ def replays(puuid, region: nil)
33
+ Models::Replay.from_api(
34
+ get("/lol/match/v5/matches/by-puuid/#{escape(puuid)}/replays", region)
35
+ )
36
+ end
31
37
  end
32
38
  end
33
39
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rito
4
+ module Endpoints
5
+ module Lol
6
+ # Requires the client to be configured with a bearer_token (RSO) instead
7
+ # of an API key. The player is identified by the token itself; payload
8
+ # shapes are the same as match-v5.
9
+ class RsoMatchV1 < Base
10
+ ROUTING = :regional
11
+
12
+ def ids(region: nil, start: nil, count: nil, queue: nil,
13
+ type: nil, start_time: nil, end_time: nil)
14
+ params = {}
15
+ params['start'] = start if start
16
+ params['count'] = count if count
17
+ params['queue'] = queue if queue
18
+ params['type'] = type if type
19
+ params['startTime'] = start_time if start_time
20
+ params['endTime'] = end_time if end_time
21
+
22
+ get('/lol/rso-match/v1/matches/ids', region, params: params)
23
+ end
24
+
25
+ def by_id(match_id, region: nil)
26
+ Models::Match.from_api(
27
+ get("/lol/rso-match/v1/matches/#{escape(match_id)}", region)
28
+ )
29
+ end
30
+
31
+ def timeline_by_id(match_id, region: nil)
32
+ get("/lol/rso-match/v1/matches/#{escape(match_id)}/timeline", region)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -7,15 +7,11 @@ module Rito
7
7
  ROUTING = :platform
8
8
 
9
9
  # Returns nil when the summoner is not in an active game (HTTP 404).
10
- def active_game(summoner_id, region: nil)
11
- get("/lol/spectator/v5/active-games/by-summoner-id/#{escape(summoner_id)}", region)
10
+ def active_game(puuid, region: nil)
11
+ get("/lol/spectator/v5/active-games/by-summoner/#{escape(puuid)}", region)
12
12
  rescue NotFound
13
13
  nil
14
14
  end
15
-
16
- def featured_games(region: nil)
17
- get('/lol/spectator/v5/featured-games', region)
18
- end
19
15
  end
20
16
  end
21
17
  end
@@ -12,22 +12,9 @@ module Rito
12
12
  )
13
13
  end
14
14
 
15
- def by_name(name, region: nil)
16
- Models::Summoner.from_api(
17
- get("/lol/summoner/v4/summoners/by-name/#{escape(name)}", region)
18
- )
19
- end
20
-
21
- def by_account_id(account_id, region: nil)
22
- Models::Summoner.from_api(
23
- get("/lol/summoner/v4/summoners/by-account/#{escape(account_id)}", region)
24
- )
25
- end
26
-
27
- def by_summoner_id(summoner_id, region: nil)
28
- Models::Summoner.from_api(
29
- get("/lol/summoner/v4/summoners/#{escape(summoner_id)}", region)
30
- )
15
+ # Requires the client to be configured with a bearer_token (RSO).
16
+ def me(region: nil)
17
+ Models::Summoner.from_api(get('/lol/summoner/v4/summoners/me', region))
31
18
  end
32
19
  end
33
20
  end
@@ -8,7 +8,7 @@ module Rito
8
8
  PREFIX = '/lol/tournament/v5'
9
9
 
10
10
  def code(tournament_code, region: nil)
11
- get("#{PREFIX}/codes/by-code/#{escape(tournament_code)}", region)
11
+ get("#{PREFIX}/codes/#{escape(tournament_code)}", region)
12
12
  end
13
13
 
14
14
  def create_codes(tournament_id:, count: nil, body: {}, region: nil)
@@ -18,7 +18,11 @@ module Rito
18
18
  end
19
19
 
20
20
  def update_code(tournament_code, body: {}, region: nil)
21
- put("#{PREFIX}/codes/by-code/#{escape(tournament_code)}", region, body: body)
21
+ put("#{PREFIX}/codes/#{escape(tournament_code)}", region, body: body)
22
+ end
23
+
24
+ def games_by_code(tournament_code, region: nil)
25
+ get("#{PREFIX}/games/by-code/#{escape(tournament_code)}", region)
22
26
  end
23
27
 
24
28
  def lobby_events(tournament_code, region: nil)
@@ -39,7 +43,7 @@ module Rito
39
43
  PREFIX = '/lol/tournament-stub/v5'
40
44
 
41
45
  def code(tournament_code, region: nil)
42
- get("#{PREFIX}/codes/by-code/#{escape(tournament_code)}", region)
46
+ get("#{PREFIX}/codes/#{escape(tournament_code)}", region)
43
47
  end
44
48
 
45
49
  def create_codes(tournament_id:, count: nil, body: {}, region: nil)
@@ -48,10 +52,6 @@ module Rito
48
52
  post("#{PREFIX}/codes", region, params: params, body: body)
49
53
  end
50
54
 
51
- def update_code(tournament_code, body: {}, region: nil)
52
- put("#{PREFIX}/codes/by-code/#{escape(tournament_code)}", region, body: body)
53
- end
54
-
55
55
  def lobby_events(tournament_code, region: nil)
56
56
  get("#{PREFIX}/lobby-events/by-code/#{escape(tournament_code)}", region)
57
57
  end
@@ -39,8 +39,9 @@ module Rito
39
39
  get('/lor/deck/v1/decks/me', region)
40
40
  end
41
41
 
42
- def deck(deck_id, region: nil)
43
- get("/lor/deck/v1/decks/me/#{escape(deck_id)}", region)
42
+ # Requires the client to be configured with a bearer_token (RSO).
43
+ def create_deck(body:, region: nil)
44
+ post('/lor/deck/v1/decks/me', region, body: body)
44
45
  end
45
46
  end
46
47
 
@@ -11,14 +11,6 @@ module Rito
11
11
  Models::Summoner.from_api(get("#{PREFIX}/by-puuid/#{escape(puuid)}", region))
12
12
  end
13
13
 
14
- def by_account_id(account_id, region: nil)
15
- Models::Summoner.from_api(get("#{PREFIX}/by-account/#{escape(account_id)}", region))
16
- end
17
-
18
- def by_summoner_id(summoner_id, region: nil)
19
- Models::Summoner.from_api(get("#{PREFIX}/#{escape(summoner_id)}", region))
20
- end
21
-
22
14
  # Requires the client to be configured with a bearer_token (RSO).
23
15
  def me(region: nil)
24
16
  Models::Summoner.from_api(get("#{PREFIX}/me", region))
@@ -26,14 +18,17 @@ module Rito
26
18
  end
27
19
 
28
20
  class LeagueV1 < Base
29
- ROUTING = :regional
21
+ ROUTING = :platform
22
+
23
+ def entries_by_puuid(puuid, region: nil)
24
+ get("/tft/league/v1/by-puuid/#{escape(puuid)}", region)
25
+ end
30
26
 
31
- def entries_by_summoner_id(summoner_id, queue: nil, tier: nil, division: nil, region: nil)
27
+ def entries(tier, division, queue: nil, page: nil, region: nil)
32
28
  params = {}
33
29
  params['queue'] = queue if queue
34
- params['tier'] = tier if tier
35
- params['division'] = division if division
36
- get("/tft/league/v1/entries/by-summoner/#{escape(summoner_id)}", region, params: params)
30
+ params['page'] = page if page
31
+ get("/tft/league/v1/entries/#{escape(tier)}/#{escape(division)}", region, params: params)
37
32
  end
38
33
 
39
34
  def challenger(region: nil)
@@ -80,15 +75,11 @@ module Rito
80
75
  ROUTING = :platform
81
76
 
82
77
  # Returns nil when the summoner is not in an active game (HTTP 404).
83
- def active_game(summoner_id, region: nil)
84
- get("/tft/spectator/v5/active-games/by-summoner-id/#{escape(summoner_id)}", region)
78
+ def active_game(puuid, region: nil)
79
+ get("/lol/spectator/tft/v5/active-games/by-puuid/#{escape(puuid)}", region)
85
80
  rescue NotFound
86
81
  nil
87
82
  end
88
-
89
- def featured_games(region: nil)
90
- get('/tft/spectator/v5/featured-games', region)
91
- end
92
83
  end
93
84
  end
94
85
  end
@@ -52,6 +52,17 @@ module Rito
52
52
  end
53
53
  end
54
54
 
55
+ class ConsoleRankedV1 < Base
56
+ ROUTING = :valorant_console_platform
57
+
58
+ def leaderboard(act_id, platform_type:, size: nil, start_index: nil, region: nil)
59
+ params = { 'platformType' => platform_type }
60
+ params['size'] = size if size
61
+ params['startIndex'] = start_index if start_index
62
+ get("/val/console/ranked/v1/leaderboards/by-act/#{escape(act_id)}", region, params: params)
63
+ end
64
+ end
65
+
55
66
  class StatusV1 < Base
56
67
  ROUTING = :valorant_platform
57
68
 
@@ -80,6 +91,10 @@ module Rito
80
91
  Endpoints::Valorant::ConsoleMatchV1.new(@client)
81
92
  end
82
93
 
94
+ def console_ranked
95
+ Endpoints::Valorant::ConsoleRankedV1.new(@client)
96
+ end
97
+
83
98
  def ranked
84
99
  Endpoints::Valorant::RankedV1.new(@client)
85
100
  end
@@ -31,6 +31,10 @@ module Rito
31
31
  MatchInfo = Data.define(:game_creation, :game_duration, :game_end_timestamp,
32
32
  :game_id, :game_mode, :game_start_timestamp, :game_type,
33
33
  :game_version, :map_id, :participants, :queue_id, :raw) do
34
+ def queue
35
+ Rito::Queues.find(queue_id)
36
+ end
37
+
34
38
  def self.from_api(hash)
35
39
  return nil if hash.nil?
36
40
 
@@ -67,5 +71,15 @@ module Rito
67
71
  )
68
72
  end
69
73
  end
74
+
75
+ Replay = Data.define(:total, :match_file_urls, :raw) do
76
+ def self.from_api(hash)
77
+ new(
78
+ total: hash['total'],
79
+ match_file_urls: hash['matchFileURLs'],
80
+ raw: hash.freeze
81
+ )
82
+ end
83
+ end
70
84
  end
71
85
  end