Compare commits

..
98 Commits
Author SHA1 Message Date
lobo e11fae8e31 feat(follow): add player search with rate limit (#57)
Build, Test & Push Core Service / quality-check (push) Successful in 2m19s
Build, Test & Push Core Service / docker (push) Successful in 1m34s
Find public profiles by name: GET /api/follows/players?q=.
Queries under 2 characters find nothing; more than 30 searches
per minute get 429. LIKE escaping is shared with the library search.
2026-10-21 14:54:48 +02:00
lobo c42526bc16 feat(library): sort by name, last played and time to beat (#56)
Sort by name ignores upper and lower case.
Games never played, or without a time to beat, come last.
2026-10-21 11:09:44 +02:00
lobo 4fbf572f32 perf(datasource): reuse query plans on core connections (#49)
Build, Test & Push Core Service / quality-check (push) Successful in 2m11s
Build, Test & Push Core Service / docker (push) Successful in 1m29s
Planning was 94% of Dashboard DB time, and prod never reused a plan.
Force generic plans and prepare on first use. Burst: 443 -> 229 ms.
2026-10-20 11:41:31 +02:00
lobo 6f2d7b4885 fix(library): book psn play on its last played day (#53)
Build, Test & Push Core Service / quality-check (push) Successful in 2m35s
Build, Test & Push Core Service / docker (push) Successful in 1m29s
A newly linked PSN title booked its whole history on the sync day.
Now only new play counts, on its last played day. A day is capped
at 24 h. V49 deletes the wrong old day rows.
2026-10-20 09:06:53 +02:00
lobo d3c9c7558c feat(follow): add feed link data and game endpoints (#52, #51)
Build, Test & Push Core Service / quality-check (push) Successful in 2m34s
Build, Test & Push Core Service / docker (push) Successful in 1m52s
Feed notes get profileName and appid; follows get lastActivityAt.
New GET /api/library/games/{appid}/preview: catalog data, any game.
New GET /api/public/profiles/library/games/{appid}: one profile game.
2026-10-14 16:23:11 +02:00
lobo ec66bd5ead chore: remove unused dev compose and prometheus dependency
Build, Test & Push Core Service / quality-check (push) Successful in 3m9s
Build, Test & Push Core Service / docker (push) Successful in 2m4s
Prometheus is not in use. Only /actuator/health is exposed.
2026-10-14 15:22:20 +02:00
lobo 54946ef0eb docs(readme): sync features, endpoints and config with code
Build, Test & Push Core Service / quality-check (push) Successful in 2m38s
Build, Test & Push Core Service / docker (push) Successful in 2m3s
The readme had drifted from the code. Update sync rules, thread pools,
API tables, env vars and the CI setup.
2026-10-14 14:51:40 +02:00
lobo dba4fedfa1 test(wiremock): add 30-game library and 6 achievement sets
Build, Test & Push Core Service / quality-check (push) Successful in 2m32s
Build, Test & Push Core Service / docker (push) Successful in 1m32s
Local WireMock library grows from 8 to 30 games.
Six games get schema, achievement and percentage stubs.
LocalMocksParseTest checks each stub appid is an owned game.
2026-10-13 12:03:56 +02:00
lobo cdfbb4a863 fix(follow): keep sync status rows for the sync digest
A hand-only digest used to move the cursor past all status rows.
It now stops at the last by_user change, so the sync digest still
gets its status detail lines.
2026-10-13 11:15:10 +02:00
lobo c6bfea1976 feat(inbox): add details for digest notes
Digest notes now keep the lines behind their counts in
inbox_note_detail (V48). GET /api/inbox/{id}/details shows them
while the reader still follows the subject and it is public.
2026-10-13 09:17:41 +02:00
lobo 03469f9eb5 perf(library): add dashboard-games and stored game detail
Build, Test & Push Core Service / quality-check (push) Successful in 2m26s
Build, Test & Push Core Service / docker (push) Successful in 1m32s
Add GET /api/library/dashboard-games for the top and playing tiles
in one call. It has no count query.
GET /api/library/games/{appid}?refresh=false answers from stored
data and sets achievementsStale. It does not wait for Steam.
entryPlatforms reads the view once in a materialized CTE:
planning ~33 ms -> 15 ms.
Test CORS Access-Control-Max-Age 3600 on preflight.

Refs #47
2026-10-12 09:25:49 +02:00
lobo b1aaec0615 fix(speedrun): pause queue on 429/420 instead of dropping it
speedrun.com returns 429 or 420 when we ask too fast. These were
counted as errors: 3 in a row dropped both queues. Now the thread
pauses and retries the same game. Rate: 1 request per 2 s. Refs #48
2026-10-12 08:25:43 +02:00
lobo 9efed0ab1d feat(speedrun): match speedrun.com games only when sure
Build, Test & Push Core Service / quality-check (push) Successful in 2m32s
Build, Test & Push Core Service / docker (push) Successful in 1m29s
Loose name matches gave wrong links. Now a link needs one sure hit:
same name and within 1 year of IGDB, or one hit when no year is known.
V47 marks old matches (not corrected ones) for one re-check. Refs #8
2026-10-11 17:23:32 +02:00
lobo bb195a1f79 test(library): compare trend move times as Instants
Sort the parsed Instant values, not the raw strings. String order
is wrong when fraction lengths differ. Refs #45.
2026-10-11 16:46:03 +02:00
lobo 0f56f5bb0f feat(library): add ALL_UNLOCKED sync change for last achievement
Build, Test & Push Core Service / quality-check (push) Successful in 2m30s
Build, Test & Push Core Service / docker (push) Successful in 1m35s
A sync that unlocks the last achievement of a game not COMPLETED
adds an ALL_UNLOCKED change. The overview hides it once the game is
COMPLETED, hidden or removed. Refs #21
2026-10-11 16:22:49 +02:00
lobo 1de8acef2e fix(library): merge manual game into its Steam row on sync
Steam sync added a second row for a game the user added by hand (#9).
The manual row moves to the Steam appid and keeps its data, such as
status, notes, sets and PSN links. Manual rows on other platforms stay
and join the Steam game's set.
2026-10-11 14:55:09 +02:00
lobo 59d6b3394d fix(rewards): check last achievement unlock for manual COMPLETED
Refs #44. Check the last achievement unlock, not the first status change.
Old 100% games no longer pass. New reason COMPLETION_TOO_OLD.
Add earlySince to the games and wallet GET responses.
2026-10-11 13:51:34 +02:00
lobo 1a9a4e912c fix(rewards): let manual finish open COMPLETED for Steam edition
A paid FINISHED_MANUAL on a set edition blocked COMPLETED for the
Steam game forever. It now opens COMPLETED, but only when the Steam
game's first finish is on or after app.rewards.early-since. Refs #35
2026-10-11 13:07:26 +02:00
lobo 6215bb0dec fix(library): count trend never played by set total
Nightly snapshot and live trend point use the set total, as stats do.
Newest point now equals stats "never started". Old rows keep old value.
Refs #43
2026-10-11 12:11:47 +02:00
lobo 8f884040d8 fix(stats): count each set once by its set playtime
Played, never started, under one hour and oldest unplayed used the
counted edition's own minutes, so a set played only on PS5 showed as
never started. They and their drill-down lists now use the set total
(user_game_entry_playtime). Refs #38. Nightly snapshot (#43) unchanged.
2026-10-11 11:52:45 +02:00
lobo 0550f3fe9c feat(configuration): add request timing log
Build, Test & Push Core Service / quality-check (push) Successful in 2m28s
Build, Test & Push Core Service / docker (push) Successful in 1m34s
One INFO line per API request: method, handler pattern, status, ms.
No ids or query strings in the line. Refs #40.
2026-10-11 11:05:18 +02:00
lobo e18b799501 perf(library): bind owned-games subqueries to user
Subqueries in OWNED_WHERE had no userId filter, so Postgres hashed
rows of all users. Skip the source filter when all sources are set.
Refs #40.
2026-10-11 11:05:18 +02:00
lobo 4d49b0f023 feat(library): soft delete removed games and add restore
Build, Test & Push Core Service / quality-check (push) Successful in 1m46s
Build, Test & Push Core Service / docker (push) Successful in 1m26s
Removed games could not come back (#39). Remove now sets removed_at
and restore clears it. V46 brings back PSN games removed before.
2026-10-11 09:52:11 +02:00
lobo 696e06e7fe fix(test): delete user_game_playtime_day rows in seed
Build, Test & Push Core Service / quality-check (push) Successful in 1m45s
Build, Test & Push Core Service / docker (push) Successful in 1m38s
RewardControllerTest leaves user_game_playtime_day rows for user 1,
affecting paceWeeks calculation. Delete them in seed() to ensure
clean test isolation.
2026-10-09 19:32:35 +02:00
lobo b24fd91e88 feat(rewards): pay early finish points and top-up on proof
Build, Test & Push Core Service / quality-check (push) Failing after 1m49s
Build, Test & Push Core Service / docker (push) Skipped
A linked PlayStation title no longer blocks. Its playtime never
proves a finish. An unproven Steam finish pays 10 early points,
the rest comes with proof. Back pay only from app.rewards.early-since.
2026-10-09 16:00:06 +02:00
lobo 7c4b475321 feat(rewards): add game points endpoint with reason codes
Frontend shows why a game earned no points after a status save.
Settle runs first. Rules and amounts are not changed.
2026-10-09 15:25:04 +02:00
lobo 4ed8a341af feat(library): use set total playtime in sort and stats
Sort, total playtime, most played, genres, moods and the public
profile use the set total of an entry, as the library card does.
New view user_game_entry_playtime (V45) is the one SQL rule.
2026-10-09 14:35:07 +02:00
lobo 1ff1e061c7 feat(library): show play per platform on game detail
Store PSN play per title. A PS title on a Steam row keeps its minutes.
Steam rtime_last_played now fills last played.
Dropped? questions read the newest PSN last played too.
2026-10-09 13:55:57 +02:00
lobo 413381d404 feat(library): show one entry per game in every list
Gitea #34 slice 2 of 3. Lists and stats count a set once.
V43 views map an entry to its editions and platforms.
Remove the hideDuplicates param; GameDto gets platforms[].
2026-10-09 11:31:11 +02:00
lobo 82d3b59165 feat(library): group same game across platforms into sets
One entry per game across platforms (Gitea #34, slice 1 of 3).
Same IGDB game is linked; a user can split one key off its set.
V42 keeps status, rating and notes per set; rewards pay once per set.
2026-10-09 10:57:23 +02:00
lobo 8e4c382563 feat(library): add source filter to owned games
A row matches when its own source, or the source of a listed
linked edition, is selected. The hidden view ignores the filter.
2026-10-09 10:03:05 +02:00
lobo 6cd92f3e83 feat(library): add question queue for open game decisions
Add open questions per game: Start it?, Finished?, Dropped?, Rate it?.
A "No" is saved in user_game_question (V41) and snoozes the question.
Account cleanup clears the new table too. Refs Gitea #32.
2026-10-09 09:31:48 +02:00
lobo 0ddb345a41 feat(psn): sync PlayStation trophies as achievements
Build, Test & Push Core Service / quality-check (push) Successful in 1m30s
Build, Test & Push Core Service / docker (push) Successful in 1m49s
Sets map by exact title id, else by name and platform.
Trophy gains count as achievements; platinum or all earned is perfect.
Max 30 PSN calls per run; trophy lists load only when changed.
Hidden trophies stay hidden (name and detail) until earned.
2026-10-08 09:18:15 +02:00
lobo f5ca7237a9 feat(psn): sync PlayStation titles in the library sync
Exact IGDB matches are added; unsure titles wait in a review import.
Playtime and last played come from PSN: summed per game, not editable.
PSN games give no Pile Points. Users with only a PSN link sync too
(V39 drops steam_id NOT NULL). Linking starts a sync, or schedules one
for the end of the cooldown. Inbox notes 2 days before the PSN link
ends and when it has ended.
2026-10-08 08:15:37 +02:00
lobo 7ac887ed5a feat(psn): link PlayStation account and import played games
Build, Test & Push Core Service / quality-check (push) Successful in 1m22s
Build, Test & Push Core Service / docker (push) Successful in 1m27s
The NPSSO is used once to get a refresh token; only that token is
stored, sealed with AES-GCM (SecretBox, key APP_PSN_TOKEN_KEY; no key
= feature off). One-time import of played PS4/PS5 titles through the
import pipeline as source PSN. Unlink keeps the games. One PSN call
per user at a time. IGDB search now sends UTF-8, so non-ASCII names
like "Yōtei" match again.
2026-10-07 13:30:48 +02:00
lobo e87f40bba0 feat(picker): add FRIENDS row from followed users
Backlog games a followed user finished or played >= 5 h. One game per
friend; strongest signal first (finished, then playtime). Requires an
active follow of a public profile that shows SUMMARY or STATUS. Skips
DROPPED games, blocked and deleted users, hidden and removed games.
2026-10-07 09:42:10 +02:00
lobo 117ff61730 feat(picker): add series and studio rows from IGDB credits
Build, Test & Push Core Service / quality-check (push) Successful in 1m22s
Build, Test & Push Core Service / docker (push) Successful in 1m36s
New V37 tables game_credit and game_credit_check store IGDB
collections and developer/publisher companies per game.
A scheduled job backfills existing games (250 per 30 s);
sync, import, manual add, merge and detail page refresh them.
SERIES row: next part of a collection the user played.
STUDIO row: backlog games from developers of top played games.
2026-10-06 20:22:53 +02:00
lobo 8dd398321c feat(picker): return rows of up to 3 games per source
Picker returns categories in fixed order: NEXT_UP, SIMILAR, LONGEST,
RANDOM, each with up to 3 games. Empty rows are left out.
Param `count` is removed; new optional `category` loads one row (reroll).
Budget and exclude apply to all rows; mood only to RANDOM.
SIMILAR takes the 3 most played games, one similar game each.
Remove PickMix.
2026-10-06 19:41:24 +02:00
lobo 867dc4c4d1 feat(follow): add user follows with activity inbox digest
Build, Test & Push Core Service / quality-check (push) Successful in 1m26s
Build, Test & Push Core Service / docker (push) Successful in 1m31s
2026-10-06 16:22:22 +02:00
lobo 2dba863c54 feat(stats): add owners endpoint to list users who own a game
Build, Test & Push Core Service / quality-check (push) Successful in 1m21s
Build, Test & Push Core Service / docker (push) Successful in 1m33s
2026-10-06 13:19:58 +02:00
lobo 7747bc7b8b feat(library): add hand-ordered backlog with next-up picker source
Build, Test & Push Core Service / quality-check (push) Successful in 1m25s
Build, Test & Push Core Service / docker (push) Successful in 1m29s
2026-10-06 09:06:51 +02:00
lobo 7b538b7f30 feat(library): exclude unreleased games from picker and pile
Build, Test & Push Core Service / quality-check (push) Successful in 1m22s
Build, Test & Push Core Service / docker (push) Successful in 1m34s
2026-10-05 20:33:25 +02:00
lobo 33b230ee91 feat(picker): mix similar, longest waiting and random picks
Build, Test & Push Core Service / quality-check (push) Successful in 2m37s
Build, Test & Push Core Service / docker (push) Successful in 1m45s
Picker slots rotate three sources: backlog games that share moods with
one of the top 5 played games, oldest first seen, and random. Each game
carries a reason (source, anchor game, first seen). Empty slots fall
back to random. Issue #28.
2026-10-05 16:13:19 +02:00
lobo 10b7dc2272 feat(account): reject tokens of blocked users and old roles
Build, Test & Push Core Service / quality-check (push) Successful in 1m23s
Build, Test & Push Core Service / docker (push) Successful in 1m30s
V32 stores the last role change per user, sent by Auth. A token
issued before that change, or of a blocked user, gets 401 within
about 30 s instead of working until it expires.
2026-10-04 20:09:22 +02:00
lobo 35b1db45e6 feat(sync): start Steam sync on visit when data is older than 20 h
A visit starts a background sync when the last successful sync is
older than 20 h; one try per hour, one sync at a time. Migration V31
adds last_success_at and login_sync_tried_at. The nightly sync skips
only users with a successful sync today after 23:00. games-count
returns syncStarted.
2026-10-04 19:05:23 +02:00
lobo a8e208321f feat(sync): record what each Steam sync changed
Build, Test & Push Core Service / quality-check (push) Successful in 1m17s
Build, Test & Push Core Service / docker (push) Successful in 1m28s
Allows dashboard to show what the last sync changed. Migration V30
creates sync_change and sync_result tables. Sync records additions,
removals, playtime, achievements, and status changes per game.
2026-10-04 11:36:09 +02:00
lobo 065048415c feat(library): add drill-down lists for stat numbers
Build, Test & Push Core Service / quality-check (push) Successful in 1m17s
Build, Test & Push Core Service / docker (push) Successful in 1m27s
The number and list share the same SQL query, so they cannot drift.
StatKey enum maps each statistic to its query, validation rules, and visibility.
StatGamesService reads games per key with 40-game pages; repositories share the
same set logic as the stat counts. Three endpoints open games: own library stats,
public profile stats (with ticket checks), and public landing-page stats (cached
10 min). Rewards track and bonus rows support drill-down too.
2026-10-03 18:51:59 +02:00
lobo 74cc8297ce feat(rewards): add 14 new shop items with twin backgrounds
Build, Test & Push Core Service / quality-check (push) Successful in 1m14s
Build, Test & Push Core Service / docker (push) Successful in 1m23s
Each page background gets a matching banner background. Tests verify
pairing, price constraints, and code length limits
2026-10-03 17:31:19 +02:00
lobo 8eab98df74 feat(rewards): unlock items by progress and skins
Build, Test & Push Core Service / quality-check (push) Successful in 1m11s
Build, Test & Push Core Service / docker (push) Successful in 1m27s
Five progress tracks: games finished, completed, weekly finish
streaks, pile-down months and play-more months. Settle books UNLOCK
rows once, also retroactively, when a track reaches an item's target.
12 unlock-only items (incl. the Steam skin) and 3 skins to buy. The
wallet returns progress; buying an unlock item answers NOT_FOR_SALE.
2026-10-02 15:40:46 +02:00
lobo bb8341dfef feat(library): undo auditor merges for 30 days, redirect old keys
Build, Test & Push Core Service / quality-check (push) Successful in 1m14s
Build, Test & Push Core Service / docker (push) Successful in 1m36s
V29 adds game_merge_undo and game_merge_undo_user: every new merge saves
a copy of what it changed. POST /api/library/merges/{mergeId}/undo
(auditors, newest merge first) puts it back; users keep later status
and rating, nothing is paid twice. A nightly job drops copies after 30
days. Old keys follow game_alias to the kept game. Manual games can now
be hidden and shown like Steam games.
2026-10-02 13:39:02 +02:00
lobo 44af19d32e feat(library): auditor catalog search and time to beat correction
GET /api/library/catalog finds any game a user has, by name, for
auditors; GET /api/library/catalog/{appid} loads it for the correction
dialog. New correction field TIME_TO_BEAT (normal + completionist,
1..60000 min, completionist >= normal) that survives the IGDB refresh.
Every correction and reset writes GAME_CORRECT / GAME_CORRECTION_RESET
to admin_audit.
2026-10-02 11:21:15 +02:00
lobo a2ea1e45d3 feat(audit): add audit log endpoint and display names from Auth
Build, Test & Push Core Service / quality-check (push) Successful in 1m14s
Build, Test & Push Core Service / docker (push) Successful in 1m20s
GET /api/library/audit-log for auditors and admins, paged, filter by
action. The account state push stores displayName in account_name so
the log shows names. Contract test updated.
2026-10-02 09:10:56 +02:00
lobo 221b5594c5 feat(library): count linked editions once in pile and stats
All game counts read the counted_user_game view, which keeps only the
most advanced edition of a linked set (older edition wins a tie). Add
the hideDuplicates filter to the library query.
2026-10-02 09:10:56 +02:00
lobo e806670d26 feat(library): add IGDB editions, game links and auditor queue
Tables game_edition (IGDB "same game" id per library key), game_link
(global sets set by auditors), game_link_pair (queue of IGDB and
requested pairs), game_link_request and account_name. Fetch IGDB
editions, link and unlink with audit rows, serve the paged auditor queue
with request counts. WireMock recordings for the editions query.
2026-10-02 09:10:56 +02:00
lobo a12ed20705 feat(rewards): add completed, background and banner effect items
Build, Test & Push Core Service / quality-check (push) Successful in 1m4s
Build, Test & Push Core Service / docker (push) Successful in 1m31s
2026-10-01 15:09:25 +02:00
lobo 349fa40272 feat(rewards): shop, equipped looks and public looks
Build, Test & Push Core Service / quality-check (push) Successful in 1m5s
Build, Test & Push Core Service / docker (push) Successful in 1m35s
Add endpoints to buy items, equip looks by slot and unequip. The shop has
8 whitelisted looks: avatar borders, badges, accents and banner frames.
Ownership is a BUY ledger row; PLATFORM_ADMIN owns every catalog item
without buying. The public profile endpoint shares only the equipped looks
filtered by ownership.
2026-10-01 13:17:04 +02:00
lobo 837dad8a6f feat(rewards): ledger, earning rules and nightly settle
New module rewards tracks Pile Points in an append-only ledger. A settle
derives rows from the status log, playtime days and achievements, once per
user, kind and game. The balance is the sum of all rows. Settle runs on
every wallet read and nightly at 02:30. The unique key (user_id, kind, ref)
makes every run idempotent. V26 also pays a one-time starter grant for
finishes from before the status log.
2026-10-01 13:15:04 +02:00
lobo 732970697d feat(stats): add PLATFORMS stat group and landing page statistics
Add PLATFORMS stat group to user stats: games and playtime per platform.
Add platforms, genres, and finished-per-year statistics to public stats
for the landing page.
2026-10-01 11:10:59 +02:00
lobo 216c1af62f feat(import): source values for exports and bookmarklet
Build, Test & Push Core Service / quality-check (push) Successful in 1m9s
Build, Test & Push Core Service / docker (push) Successful in 1m33s
2026-09-30 15:59:05 +02:00
lobo e347b7aac8 chore(security)!: refuse tokens without aud 2026-09-30 15:00:47 +02:00
lobo 23bf5c41b4 chore(library)!: drop the full-replace PUT of a backlog entry
The Frontend sends PATCH since item 27 batch 2.
2026-09-30 15:00:47 +02:00
lobo 34d64e7215 refactor: item 29 cleanup
C14 C16 C17 C18 C20 A11 A15 X10 X12 X15: dead Steam count code, GameNames, steamIdText, one query per game for the finished estimate, no API versioning config, open-in-view off, CORS from APP_FRONTEND_URL, non-root image, prune only up to the highest known id.
2026-09-30 15:00:47 +02:00
lobo 504c935b27 feat(account): Steam ID and blocked state from Auth (V25)
A blocked user gets no sync and leaves the landing stats. A new or removed Steam ID stops the nightly sync of the old one. No token check in Core: the token lives until it expires.
2026-09-30 15:00:47 +02:00
lobo 3512159b41 test: background work inline, shared mock bases, lock-wait instead of sleep
Build, Test & Push Core Service / quality-check (push) Successful in 1m8s
Build, Test & Push Core Service / docker (push) Successful in 1m31s
2026-09-30 12:08:57 +02:00
lobo 7fe2823519 refactor(library): detail page refreshes, then assembles 2026-09-30 12:08:57 +02:00
lobo 2c97e2ae96 refactor(library): two bounded background pools
Every @Async names a pool: with the scheduler there are two TaskExecutor beans, and a bare @Async ran on an unbounded executor. Page views queue only stale games; the long runs after a sync get their own pool.
2026-09-30 12:08:57 +02:00
lobo 9a09d535fc refactor(library): listed_user_game view and one shared schema (V24) 2026-09-30 09:37:16 +02:00
lobo b499e79c41 refactor(library): one IGDB split and merge for time to beat and moods 2026-09-30 09:37:16 +02:00
lobo c1472c7d59 refactor(library): own IgdbGame record, one owned rule, layer rules
Stored import candidates keep their JSON shape, so READY imports from before still read.
2026-09-30 09:37:16 +02:00
lobo 1abc03d2c1 refactor(library): auditor fields only through applyCorrection 2026-09-30 09:37:16 +02:00
lobo 79d7bf17f2 feat(library): PATCH backlog saves only the sent fields 2026-09-30 07:36:08 +02:00
lobo 73cfcb58e2 refactor(api): one error body, token audiences, contract fixture
Build, Test & Push Core Service / quality-check (push) Successful in 1m7s
Build, Test & Push Core Service / docker (push) Successful in 1m23s
2026-09-29 14:48:28 +02:00
lobo 2360beeb81 fix(sync): short sync transactions, real Steam retries, no N+1 2026-09-29 13:27:31 +02:00
lobo 2a5fcc1c00 feat(import): import many games with background matching, review and undo 2026-09-29 10:20:54 +02:00
lobo 3bd1eda0ec docs(profile): note that the ticket claims come from the tile layout
Build, Test & Push Core Service / quality-check (push) Successful in 1m6s
Build, Test & Push Core Service / docker (push) Successful in 1m27s
2026-09-28 15:05:11 +02:00
lobo 07d287cd43 feat(profile): leave out hidden public profile sections 2026-09-28 14:20:14 +02:00
lobo 5c0c0c6a78 feat(dev): add the local profile with recorded third-party answers
Profile "local" points Steam, Twitch/IGDB and speedrun.com to a WireMock
container from compose.yaml (recordings in local/wiremock) and checks
logins against the local Auth.

The IGDB lookups now keep only the ids they asked for: an answer with
another game made tags and release years drop the whole batch.
2026-09-28 13:07:40 +02:00
lobo 5a089b2082 feat(library): let auditors merge duplicate games
Build, Test & Push Core Service / quality-check (push) Successful in 1m3s
Build, Test & Push Core Service / docker (push) Successful in 1m26s
An auditor merges a game added by hand into its Steam game or another
game added by hand (V21). Every user's row moves; a user with both rows
keeps one, with the status, rating and notes set by hand. game_alias
sends later adds to the kept key, and admin_audit logs who merged what.
The game search shows games already in ToBePlayed first.
2026-09-28 11:25:45 +02:00
lobo 3c2f40036d feat(library): let auditors correct game data
Build, Test & Push Core Service / quality-check (push) Successful in 1m0s
Build, Test & Push Core Service / docker (push) Successful in 1m25s
An AUDITOR corrects name, header image, speedrun link, moods, endless and genres of a game for every user (V20 game_correction, PUT/DELETE /api/library/games/{appid}/corrections/{field}). The value is also written into the cached row, so reads stay unchanged; the Steam sync, the image repair, the IGDB add and the mood and speedrun upserts skip corrected fields. SteamGame gets @DynamicUpdate so a sync no longer writes back columns it did not change.
2026-09-28 09:31:39 +02:00
lobo 2596df609e feat(security): check role markers on services and read the role claim
Every service method a controller calls carries @RequiresRole, @Public or @Internal; a Spring Security method interceptor checks it while a request is served. Core now grants the active role from the token and every lower one. ArchUnit fails the build for an unmarked method, two markers, a controller calling an @Async method, or a service reaching a method that needs more. The background refreshes moved from LibraryController into the services, because an @Async method is never checked.
2026-09-28 08:50:10 +02:00
lobo 351cda411d feat(account): hide deleted accounts and clean up their rows
Build, Test & Push Core Service / quality-check (push) Successful in 1m2s
Build, Test & Push Core Service / docker (push) Successful in 1m20s
Auth marks a deleted user in deleted_user (no sync, not in landing stats or pile snapshots) and later purges the rows through /internal/accounts with a service token. Prune removes rows of user ids Auth does not know. Dry run by default.
2026-09-27 11:46:22 +02:00
lobo 88aae0101f feat(version): answer the build commit and time
Build, Test & Push Core Service / quality-check (push) Successful in 57s
Build, Test & Push Core Service / docker (push) Successful in 1m20s
GET /api/version is public. CI passes GIT_SHA and BUILD_TIME as Docker build args; a local build answers dev.
2026-09-27 10:27:01 +02:00
lobo 01552ecd89 fix(sync): keep old playtime off the day a game shows up
A game the sync saw for the first time put its whole playtime on that
day (40 h "longest gaming day" after skip_unvetted_apps=0). Growth now
counts at most Steam's last two weeks, and one game gets at most 24 h
per day. V18 drops the bad rows and caps old ones.
2026-09-27 10:00:53 +02:00
lobo 0fa2a37f47 feat(library): add stats page data and pile trend
Build, Test & Push Core Service / quality-check (push) Successful in 1m0s
Build, Test & Push Core Service / docker (push) Successful in 1m18s
Log every status change with a trigger, so no code path can miss it.
Store IGDB genres with the moods. Write a pile snapshot per user each
night. The sync moves an untouched pile game with new playtime to
PLAYING in one guarded update, so a status the user picks wins.
Old finished games get their year from the ending achievement.
GET /api/library/stats serves the groups; the public profile shows
only the groups in the profile ticket.
2026-09-27 07:16:05 +02:00
lobo b959542e23 feat(library): finish games from the ending achievement or suggest it
Build, Test & Push Core Service / quality-check (push) Successful in 58s
Build, Test & Push Core Service / docker (push) Successful in 1m23s
2026-09-26 19:00:57 +02:00
lobo c2d17d0bc7 feat(library): hide games from lists and stats
Build, Test & Push Core Service / quality-check (push) Successful in 58s
Build, Test & Push Core Service / docker (push) Successful in 1m25s
2026-09-26 12:27:58 +02:00
lobo 246e255058 feat(images): repair reported covers and achievement icons at night
Build, Test & Push Core Service / quality-check (push) Successful in 56s
Build, Test & Push Core Service / docker (push) Successful in 1m24s
2026-09-26 12:07:07 +02:00
lobo a389bdd0c7 fix(sync): stop the nightly sync when the Steam ID is gone
Build, Test & Push Core Service / quality-check (push) Successful in 49s
Build, Test & Push Core Service / docker (push) Successful in 1m20s
After an unlink in Auth, or when a verified link took the ID away, the
nightly job kept syncing the old Steam ID for up to 14 days. A
games-count request without a steamId claim now clears user_seen_at.
steam_id stays, so a later link with another ID still soft-deletes the
old games.
2026-09-26 11:20:04 +02:00
lobo 393cdddf06 feat(library): add a speedrun mood from speedrun.com
Build, Test & Push Core Service / quality-check (push) Successful in 1m4s
Build, Test & Push Core Service / docker (push) Successful in 1m23s
The picker takes mood=SPEEDRUN for backlog games with a speedrun.com
game that has at least one verified run. The game detail returns the
link as speedrunUrl.

speedrun.com has no Steam or IGDB link, so games are matched by name
and, when IGDB knows it, by release year (one year off at most). One
queue serves all users at 1 request per second. Results are kept 30
days in game_speedrun.
2026-09-26 10:24:22 +02:00
lobo 3224257325 fix(steam): sync owned apps Steam calls unvetted
Build, Test & Push Core Service / quality-check (push) Successful in 1m3s
Build, Test & Push Core Service / docker (push) Successful in 1m32s
GetOwnedGames leaves out "unvetted" apps unless skip_unvetted_apps=0
is set. So a released game owned through a developer license was
missing from the library.

Such an app can come without a name. The sync now keeps the stored
name, or uses "App <appid>" for a new game, so the NOT NULL name
column does not fail the whole sync.
2026-09-26 10:04:23 +02:00
lobo b350de1c79 docs(readme): add the architecture overview
Build, Test & Push Core Service / quality-check (push) Successful in 53s
Build, Test & Push Core Service / docker (push) Successful in 1m20s
2026-09-26 07:37:44 +02:00
lobo 7663e09a8c feat(library): filter the picker by mood
Moods come from IGDB genres, themes and game modes and are stored per game in game_mood (V9), refreshed like the time to beat. Picking a mood also refreshes the moods of the backlog in the background, so users without a Steam sync get them too.
2026-09-26 07:36:10 +02:00
lobo 5e7455db05 feat(library): weight the backlog suggestion by priority
Build, Test & Push Core Service / quality-check (push) Successful in 51s
Build, Test & Push Core Service / docker (push) Successful in 1m19s
A HIGH game is 4 times as likely as a LOW or unset one, a
MEDIUM game twice. Not HIGH first like the picker: the
dashboard shuffles by excluding only the current game, so a
strict order would swap between two games. The picker now
starts a stale Steam sync like the library does.
2026-09-26 07:05:57 +02:00
lobo 1cac7de836 feat(igdb): rank game search by popularity and help with typos
Build, Test & Push Core Service / quality-check (push) Successful in 49s
Build, Test & Push Core Service / docker (push) Successful in 1m36s
IGDB lists every e-Reader card as a game, and its own order
puts obscure entries first. Core now drops e-Reader-only
games, asks for 50 hits and sorts exact name first, then by
rating count. When a search finds fewer than 3 games, Core
searches again without doubled letters and with single
words, and adds those hits by Levenshtein distance after
IGDB's own hits.

Also fixes a flaky test that read the time to beat before
the background refresh wrote it.
2026-09-26 06:29:57 +02:00
lobo e1d837bc78 fix(igdb): search only games a user can own and play
Build, Test & Push Core Service / quality-check (push) Failing after 49s
Build, Test & Push Core Service / docker (push) Skipped
The search listed DLC and e-Reader levels, and the limit of
10 pushed the main games out. Keep main games, standalone
expansions, seasons, remakes, remasters, expanded games and
ports, and show 20 hits.
2026-09-25 15:24:05 +02:00
lobo 4d50863cb8 feat(library): add games by name from IGDB
Build, Test & Push Core Service / quality-check (push) Successful in 51s
Build, Test & Push Core Service / docker (push) Successful in 1m24s
Games the user owns outside Steam get the key minus their
IGDB id, or the Steam appid when IGDB knows the game on
Steam. The sync never removes a MANUAL row and takes it
over once the user owns the game on Steam. Users without
a Steam ID can use the library.
2026-09-25 14:37:21 +02:00
lobo 33e0a59664 docs(roadmap): add games by name from IGDB for other platforms 2026-09-25 13:45:13 +02:00
lobo 5d608b72e6 feat(security): accept the auth cookie and guard against CSRF
Core reads the login token from the tbp_access cookie or a Bearer
header, whichever verifies, and parses it once per request. Unsafe
requests need an X-TBP-Client or Authorization header, CORS allows
only the exact frontend origin, and a missing or expired token
answers 401 instead of 403.
2026-09-25 13:45:08 +02:00
680 changed files with 54006 additions and 1136 deletions

No files matched your search

+4
View File
@@ -52,6 +52,7 @@ jobs:
BRANCH="$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]')"
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
echo "sha=${GITHUB_SHA::12}" >> "$GITHUB_OUTPUT"
echo "build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
@@ -69,6 +70,9 @@ jobs:
with:
context: .
push: true
build-args: |
GIT_SHA=${{ github.sha }}
BUILD_TIME=${{ steps.prep.outputs.build_time }}
tags: |
git.andreas-dahm.eu/lobo_corp/tbp-core-service:${{ steps.prep.outputs.branch }}
git.andreas-dahm.eu/lobo_corp/tbp-core-service:${{ steps.prep.outputs.branch }}-${{ steps.prep.outputs.sha }}
+9
View File
@@ -25,11 +25,20 @@ FROM eclipse-temurin:25-jre-alpine
WORKDIR /app
# Passed by the CI workflow; shown by GET /api/version
ARG GIT_SHA=dev
ARG BUILD_TIME=
ENV APP_BUILD_COMMIT=$GIT_SHA APP_BUILD_TIME=$BUILD_TIME
# Expose the port your Spring Boot app runs on
EXPOSE 8090
# Copy the compiled jar file from the builder stage
COPY --from=builder /app/target/*.jar app.jar
# No root in the container
RUN addgroup -S app && adduser -S app -G app
USER app
# Run the application
ENTRYPOINT ["java", "-jar", "app.jar"]
+9
View File
@@ -8,3 +8,12 @@ services:
- POSTGRES_DB=tbp_core
- POSTGRES_USER=tbp_user
- POSTGRES_PASSWORD=local_secret_password
# Recorded answers of Steam, Twitch/IGDB and speedrun.com (local/wiremock). Starts only with the local profile.
wiremock:
image: wiremock/wiremock:3.9.1
container_name: tbp_core_mocks_local
profiles: ["local"]
ports:
- "8089:8080"
volumes:
- ./local/wiremock:/home/wiremock
-22
View File
@@ -1,22 +0,0 @@
# docker-compose.dev.yml
services:
# ─────────────────────────────────────────────
# LOCAL DATABASE FOR DEVELOPMENT
# ─────────────────────────────────────────────
tbp-db-local:
image: postgres:17-alpine
container_name: tbp_db_local
restart: unless-stopped
ports:
# Map the container port 5432 to your local machine port 5432
- "5432:5432"
environment:
- POSTGRES_DB=tbp_core
- POSTGRES_USER=tbp_user
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
# Use a local volume to persist data across container restarts
- tbp_local_db_data:/var/lib/postgresql/data
volumes:
tbp_local_db_data:
+29
View File
@@ -0,0 +1,29 @@
[
{
"id": 72
},
{
"id": 113112
},
{
"id": 17000
},
{
"id": 7046
},
{
"id": 26226
},
{
"id": 14593
},
{
"id": 233
},
{
"id": 133236
},
{
"id": 119388
}
]
@@ -0,0 +1,34 @@
[
{
"game": 72,
"uid": "620"
},
{
"game": 113112,
"uid": "1145360"
},
{
"game": 17000,
"uid": "413150"
},
{
"game": 7046,
"uid": "427520"
},
{
"game": 26226,
"uid": "504230"
},
{
"game": 14593,
"uid": "367520"
},
{
"game": 233,
"uid": "220"
},
{
"game": 133236,
"uid": "892970"
}
]
@@ -0,0 +1,27 @@
[
{
"id": 113112,
"name": "Hades",
"first_release_date": 1600387200,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PC (Microsoft Windows)",
"abbreviation": "PC"
},
{
"name": "Nintendo Switch",
"abbreviation": "Switch"
}
],
"total_rating_count": 1500,
"external_games": [
{
"external_game_source": 1,
"uid": "1145360"
}
]
}
]
@@ -0,0 +1,17 @@
[
{
"id": 119388,
"name": "The Legend of Zelda: Tears of the Kingdom",
"first_release_date": 1683849600,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "Nintendo Switch",
"abbreviation": "Switch"
}
],
"total_rating_count": 900
}
]
@@ -0,0 +1,17 @@
[
{
"id": 14593,
"name": "Hollow Knight",
"first_release_date": 1487980800,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PlayStation 5",
"abbreviation": "PS5"
}
],
"total_rating_count": 1100
}
]
@@ -0,0 +1,27 @@
[
{
"id": 26226,
"name": "Celeste",
"first_release_date": 1516838400,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PC (Microsoft Windows)",
"abbreviation": "PC"
},
{
"name": "Nintendo Switch",
"abbreviation": "Switch"
}
],
"total_rating_count": 1300,
"external_games": [
{
"external_game_source": 1,
"uid": "504230"
}
]
}
]
@@ -0,0 +1,17 @@
[
{
"id": 900003,
"name": "Mega Man Legacy Collection",
"first_release_date": 1451520000,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PlayStation 4",
"abbreviation": "PS4"
}
],
"total_rating_count": 300
}
]
@@ -0,0 +1,21 @@
[
{
"id": 900002,
"name": "Ghost of Tsushima",
"first_release_date": 1595548800,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PlayStation 4",
"abbreviation": "PS4"
},
{
"name": "PlayStation 5",
"abbreviation": "PS5"
}
],
"total_rating_count": 2000
}
]
@@ -0,0 +1,17 @@
[
{
"id": 900001,
"name": "Ghost of Yōtei",
"first_release_date": 1760054400,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PlayStation 5",
"abbreviation": "PS5"
}
],
"total_rating_count": 800
}
]
@@ -0,0 +1,82 @@
[
{
"id": 119388,
"name": "The Legend of Zelda: Tears of the Kingdom",
"first_release_date": 1683849600,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "Nintendo Switch",
"abbreviation": "Switch"
}
],
"total_rating_count": 900
},
{
"id": 113112,
"name": "Hades",
"first_release_date": 1600387200,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PC (Microsoft Windows)",
"abbreviation": "PC"
},
{
"name": "Nintendo Switch",
"abbreviation": "Switch"
}
],
"total_rating_count": 1500,
"external_games": [
{
"external_game_source": 1,
"uid": "1145360"
}
]
},
{
"id": 26226,
"name": "Celeste",
"first_release_date": 1516838400,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PC (Microsoft Windows)",
"abbreviation": "PC"
},
{
"name": "Nintendo Switch",
"abbreviation": "Switch"
}
],
"total_rating_count": 1300,
"external_games": [
{
"external_game_source": 1,
"uid": "504230"
}
]
},
{
"id": 14593,
"name": "Hollow Knight",
"first_release_date": 1487980800,
"cover": {
"image_id": "co1r7f"
},
"platforms": [
{
"name": "PlayStation 5",
"abbreviation": "PS5"
}
],
"total_rating_count": 1100
}
]
@@ -0,0 +1,38 @@
[
{
"id": 72,
"first_release_date": 1303171200
},
{
"id": 113112,
"first_release_date": 1600387200
},
{
"id": 17000,
"first_release_date": 1456444800
},
{
"id": 7046,
"first_release_date": 1600387200
},
{
"id": 26226,
"first_release_date": 1516838400
},
{
"id": 14593,
"first_release_date": 1487980800
},
{
"id": 233,
"first_release_date": 1100736000
},
{
"id": 133236,
"first_release_date": 1612828800
},
{
"id": 119388,
"first_release_date": 1683849600
}
]
+257
View File
@@ -0,0 +1,257 @@
[
{
"id": 72,
"genres": [
{
"name": "Puzzle"
},
{
"name": "Platform"
},
{
"name": "Shooter"
}
],
"themes": [
{
"name": "Science fiction"
},
{
"name": "Comedy"
}
],
"game_modes": [
{
"name": "Single player"
},
{
"name": "Co-operative"
}
]
},
{
"id": 113112,
"genres": [
{
"name": "Role-playing (RPG)"
},
{
"name": "Hack and slash/Beat 'em up"
},
{
"name": "Indie"
}
],
"themes": [
{
"name": "Action"
},
{
"name": "Fantasy"
}
],
"game_modes": [
{
"name": "Single player"
}
]
},
{
"id": 17000,
"genres": [
{
"name": "Role-playing (RPG)"
},
{
"name": "Simulator"
},
{
"name": "Indie"
}
],
"themes": [
{
"name": "Sandbox"
}
],
"game_modes": [
{
"name": "Single player"
},
{
"name": "Multiplayer"
},
{
"name": "Co-operative"
}
]
},
{
"id": 7046,
"genres": [
{
"name": "Simulator"
},
{
"name": "Strategy"
},
{
"name": "Indie"
}
],
"themes": [
{
"name": "Science fiction"
},
{
"name": "Sandbox"
},
{
"name": "Survival"
}
],
"game_modes": [
{
"name": "Single player"
},
{
"name": "Multiplayer"
}
]
},
{
"id": 26226,
"genres": [
{
"name": "Platform"
},
{
"name": "Indie"
}
],
"themes": [
{
"name": "Action"
}
],
"game_modes": [
{
"name": "Single player"
}
]
},
{
"id": 14593,
"genres": [
{
"name": "Platform"
},
{
"name": "Adventure"
},
{
"name": "Indie"
}
],
"themes": [
{
"name": "Action"
},
{
"name": "Fantasy"
}
],
"game_modes": [
{
"name": "Single player"
}
]
},
{
"id": 233,
"genres": [
{
"name": "Shooter"
}
],
"themes": [
{
"name": "Action"
},
{
"name": "Science fiction"
}
],
"game_modes": [
{
"name": "Single player"
}
]
},
{
"id": 133236,
"genres": [
{
"name": "Adventure"
},
{
"name": "Indie"
},
{
"name": "Simulator"
}
],
"themes": [
{
"name": "Action"
},
{
"name": "Fantasy"
},
{
"name": "Sandbox"
},
{
"name": "Survival"
}
],
"game_modes": [
{
"name": "Single player"
},
{
"name": "Multiplayer"
},
{
"name": "Co-operative"
}
]
},
{
"id": 119388,
"genres": [
{
"name": "Adventure"
},
{
"name": "Role-playing (RPG)"
}
],
"themes": [
{
"name": "Action"
},
{
"name": "Fantasy"
},
{
"name": "Open world"
}
],
"game_modes": [
{
"name": "Single player"
}
]
}
]
@@ -0,0 +1,58 @@
[
{
"game_id": 72,
"hastily": 21600,
"normally": 32400,
"completely": 79200,
"count": 100
},
{
"game_id": 113112,
"hastily": 72000,
"normally": 90000,
"completely": 342000,
"count": 100
},
{
"game_id": 17000,
"hastily": 144000,
"normally": 190800,
"completely": 576000,
"count": 100
},
{
"game_id": 7046,
"hastily": 108000,
"normally": 216000,
"completely": 900000,
"count": 100
},
{
"game_id": 26226,
"hastily": 28800,
"normally": 43200,
"completely": 144000,
"count": 100
},
{
"game_id": 14593,
"hastily": 97200,
"normally": 147600,
"completely": 226800,
"count": 100
},
{
"game_id": 233,
"hastily": 43200,
"normally": 50400,
"completely": 68400,
"count": 100
},
{
"game_id": 119388,
"hastily": 180000,
"normally": 216000,
"completely": 684000,
"count": 100
}
]
+81
View File
@@ -0,0 +1,81 @@
{
"titles": [
{
"titleId": "PPSA26344_00",
"name": "Ghost of Yōtei",
"category": "ps5_native_game",
"service": "none(purchased)",
"playCount": 31,
"playDuration": "PT65H9M15S",
"imageUrl": "https://image.api.playstation.com/local/ghost-of-yotei.png",
"firstPlayedDateTime": "2025-10-03T18:20:11.000Z",
"lastPlayedDateTime": "2026-10-01T20:41:07.000Z",
"concept": {
"id": 10003923,
"titleIds": ["PPSA26344_00"]
}
},
{
"titleId": "CUSA02521_00",
"name": "Mega Man Legacy Collection™",
"category": "ps4_game",
"service": "none(purchased)",
"playCount": 9,
"playDuration": "PT8H30M28S",
"imageUrl": "https://image.api.playstation.com/local/mega-man-legacy.png",
"firstPlayedDateTime": "2017-01-14T09:02:51.000Z",
"lastPlayedDateTime": "2024-03-02T16:10:30.000Z",
"concept": {
"id": 202697,
"titleIds": ["CUSA02521_00", "CUSA02522_00"]
}
},
{
"titleId": "PPSA03208_00",
"name": "Ghost of Tsushima DIRECTOR'S CUT (PS5)",
"category": "ps5_native_game",
"service": "none(purchased)",
"playCount": 22,
"playDuration": "PT64H3S",
"imageUrl": "https://image.api.playstation.com/local/ghost-of-tsushima.png",
"firstPlayedDateTime": "2021-08-20T19:44:02.000Z",
"lastPlayedDateTime": "2023-12-11T21:15:48.000Z",
"concept": {
"id": 235227,
"titleIds": ["PPSA03208_00", "CUSA17722_00", "CUSA17723_00"]
}
},
{
"titleId": "CUSA17722_00",
"name": "Ghost of Tsushima",
"category": "ps4_game",
"service": "none(purchased)",
"playCount": 3,
"playDuration": "PT1H30M",
"imageUrl": "https://image.api.playstation.com/local/ghost-of-tsushima.png",
"firstPlayedDateTime": "2020-07-17T10:00:00.000Z",
"lastPlayedDateTime": "2020-07-19T12:00:00.000Z",
"concept": {
"id": 235227,
"titleIds": ["PPSA03208_00", "CUSA17722_00", "CUSA17723_00"]
}
},
{
"titleId": "PPSA00000_00",
"name": "Monster Hunter Wilds",
"category": "ps5_native_game",
"service": "none(purchased)",
"playCount": 5,
"playDuration": "PT12H",
"imageUrl": "https://image.api.playstation.com/local/monster-hunter-wilds.png",
"firstPlayedDateTime": "2025-03-01T10:00:00.000Z",
"lastPlayedDateTime": "2025-03-09T22:00:00.000Z",
"concept": {
"id": 10000001,
"titleIds": ["PPSA00000_00"]
}
}
],
"totalItemCount": 5,
"nextOffset": null
}
+9
View File
@@ -0,0 +1,9 @@
{
"access_token": "local-access",
"token_type": "bearer",
"expires_in": 3599,
"scope": "psn:mobile.v2.core psn:clientapp",
"id_token": "local-id",
"refresh_token": "local-refresh",
"refresh_token_expires_in": 863999
}
@@ -0,0 +1,60 @@
{
"trophySetVersion": "01.00",
"hasTrophyGroups": true,
"trophies": [
{
"trophyId": 0,
"trophyHidden": false,
"trophyType": "platinum",
"trophyName": "Legend of Yōtei",
"trophyDetail": "Earn all other trophies.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t0.png",
"trophyGroupId": "default"
},
{
"trophyId": 1,
"trophyHidden": false,
"trophyType": "gold",
"trophyName": "Wolf of Ezo",
"trophyDetail": "Finish the story.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t1.png",
"trophyGroupId": "default"
},
{
"trophyId": 2,
"trophyHidden": false,
"trophyType": "silver",
"trophyName": "Lone Blade",
"trophyDetail": "Win a duel.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t2.png",
"trophyGroupId": "default"
},
{
"trophyId": 3,
"trophyHidden": false,
"trophyType": "bronze",
"trophyName": "First Steps",
"trophyDetail": "Leave the village.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t3.png",
"trophyGroupId": "default"
},
{
"trophyId": 4,
"trophyHidden": true,
"trophyType": "bronze",
"trophyName": "Secret Name",
"trophyDetail": "Secret detail text.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t4.png",
"trophyGroupId": "default"
},
{
"trophyId": 5,
"trophyHidden": false,
"trophyType": "bronze",
"trophyName": "Island Trial",
"trophyDetail": "Finish the DLC trial.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t5.png",
"trophyGroupId": "001"
}
]
}
@@ -0,0 +1,33 @@
{
"trophySetVersion": "01.00",
"hasTrophyGroups": false,
"trophies": [
{
"trophyId": 0,
"trophyHidden": false,
"trophyType": "bronze",
"trophyName": "Blue Bomber",
"trophyDetail": "Start the game.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t0.png",
"trophyGroupId": "default"
},
{
"trophyId": 1,
"trophyHidden": false,
"trophyType": "bronze",
"trophyName": "Rock On",
"trophyDetail": "Beat Mega Man 1.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t1.png",
"trophyGroupId": "default"
},
{
"trophyId": 2,
"trophyHidden": false,
"trophyType": "silver",
"trophyName": "Robot Master",
"trophyDetail": "Beat Mega Man 2.",
"trophyIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/t2.png",
"trophyGroupId": "default"
}
]
}
@@ -0,0 +1,58 @@
{
"trophySetVersion": "01.00",
"hasTrophyGroups": true,
"trophies": [
{
"trophyId": 0,
"trophyHidden": false,
"trophyType": "platinum",
"earned": true,
"trophyRare": 3,
"trophyEarnedRate": "2.1",
"earnedDateTime": "2026-09-20T18:00:00Z"
},
{
"trophyId": 1,
"trophyHidden": false,
"trophyType": "gold",
"earned": true,
"trophyRare": 3,
"trophyEarnedRate": "30.5",
"earnedDateTime": "2026-09-21T18:00:00Z"
},
{
"trophyId": 2,
"trophyHidden": false,
"trophyType": "silver",
"earned": true,
"trophyRare": 3,
"trophyEarnedRate": "55.0",
"earnedDateTime": "2026-09-22T18:00:00Z"
},
{
"trophyId": 3,
"trophyHidden": false,
"trophyType": "bronze",
"earned": true,
"trophyRare": 3,
"trophyEarnedRate": "90.2",
"earnedDateTime": "2026-09-23T18:00:00Z"
},
{
"trophyId": 4,
"trophyHidden": true,
"trophyType": "bronze",
"earned": false,
"trophyRare": 3,
"trophyEarnedRate": "1.3"
},
{
"trophyId": 5,
"trophyHidden": false,
"trophyType": "bronze",
"earned": false,
"trophyRare": 3,
"trophyEarnedRate": "12.0"
}
]
}
@@ -0,0 +1,31 @@
{
"trophySetVersion": "01.00",
"hasTrophyGroups": false,
"trophies": [
{
"trophyId": 0,
"trophyHidden": false,
"trophyType": "bronze",
"earned": false,
"trophyRare": 3,
"trophyEarnedRate": "40.0"
},
{
"trophyId": 1,
"trophyHidden": false,
"trophyType": "bronze",
"earned": true,
"earnedDateTime": "2024-03-02T16:10:30Z",
"trophyRare": 3,
"trophyEarnedRate": "25.5"
},
{
"trophyId": 2,
"trophyHidden": false,
"trophyType": "silver",
"earned": false,
"trophyRare": 2,
"trophyEarnedRate": "10.0"
}
]
}
@@ -0,0 +1,33 @@
{
"titles": [
{
"npTitleId": "PPSA26344_00",
"trophyTitles": [
{
"npServiceName": "trophy2",
"npCommunicationId": "NPWR90001_00",
"trophySetVersion": "01.00",
"trophyTitleName": "Ghost of Yōtei",
"trophyTitleIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/ghost-set.png",
"trophyTitlePlatform": "PS5",
"hasTrophyGroups": true,
"definedTrophies": {
"bronze": 3,
"silver": 1,
"gold": 1,
"platinum": 1
},
"progress": 66,
"earnedTrophies": {
"bronze": 1,
"silver": 1,
"gold": 1,
"platinum": 1
},
"hiddenFlag": false,
"lastUpdatedDateTime": "2026-10-01T20:41:07Z"
}
]
}
]
}
@@ -0,0 +1,102 @@
{
"totalItemCount": 4,
"nextOffset": null,
"trophyTitles": [
{
"npServiceName": "trophy2",
"npCommunicationId": "NPWR90001_00",
"trophySetVersion": "01.00",
"trophyTitleName": "Ghost of Yōtei",
"trophyTitleIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/ghost-set.png",
"trophyTitlePlatform": "PS5",
"hasTrophyGroups": true,
"definedTrophies": {
"bronze": 3,
"silver": 1,
"gold": 1,
"platinum": 1
},
"progress": 66,
"earnedTrophies": {
"bronze": 1,
"silver": 1,
"gold": 1,
"platinum": 1
},
"hiddenFlag": false,
"lastUpdatedDateTime": "2026-10-01T20:41:07Z"
},
{
"npServiceName": "trophy",
"npCommunicationId": "NPWR90002_00",
"trophySetVersion": "01.00",
"trophyTitleName": "Mega Man Legacy Collection",
"trophyTitleIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/megaman-set.png",
"trophyTitlePlatform": "PS4",
"hasTrophyGroups": false,
"definedTrophies": {
"bronze": 2,
"silver": 1,
"gold": 0,
"platinum": 0
},
"progress": 33,
"earnedTrophies": {
"bronze": 1,
"silver": 0,
"gold": 0,
"platinum": 0
},
"hiddenFlag": false,
"lastUpdatedDateTime": "2024-03-02T16:10:30Z"
},
{
"npServiceName": "trophy",
"npCommunicationId": "NPWR90003_00",
"trophySetVersion": "01.00",
"trophyTitleName": "Old PS3 Game",
"trophyTitleIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/ps3-set.png",
"trophyTitlePlatform": "PS3",
"hasTrophyGroups": false,
"definedTrophies": {
"bronze": 5,
"silver": 0,
"gold": 0,
"platinum": 0
},
"progress": 20,
"earnedTrophies": {
"bronze": 1,
"silver": 0,
"gold": 0,
"platinum": 0
},
"hiddenFlag": false,
"lastUpdatedDateTime": "2012-05-01T10:00:00Z"
},
{
"npServiceName": "trophy",
"npCommunicationId": "NPWR90004_00",
"trophySetVersion": "01.00",
"trophyTitleName": "Hidden By The User",
"trophyTitleIconUrl": "https://psnobj.prod.dl.playstation.net/psnobj/local/hidden-set.png",
"trophyTitlePlatform": "PS4",
"hasTrophyGroups": false,
"definedTrophies": {
"bronze": 1,
"silver": 0,
"gold": 0,
"platinum": 0
},
"progress": 0,
"earnedTrophies": {
"bronze": 0,
"silver": 0,
"gold": 0,
"platinum": 0
},
"hiddenFlag": true,
"lastUpdatedDateTime": "2020-01-01T10:00:00Z"
}
]
}
@@ -0,0 +1,17 @@
{
"data": [
{
"id": "o1y9j9v6",
"names": {
"international": "Celeste"
},
"released": 2018,
"weblink": "https://www.speedrun.com/celeste",
"links": [
{
"rel": "self"
}
]
}
]
}
@@ -0,0 +1,7 @@
{
"data": [
{
"id": "y8dwozoj"
}
]
}
@@ -0,0 +1,30 @@
{
"achievementpercentages": {
"achievements": [
{
"name": "ACH_B1",
"percent": 81.0
},
{
"name": "ACH_B2",
"percent": 57.3
},
{
"name": "ACH_B3",
"percent": 39.8
},
{
"name": "ACH_B4",
"percent": 26.5
},
{
"name": "ACH_B5",
"percent": 23.6
},
{
"name": "ACH_B6",
"percent": 18.2
}
]
}
}
@@ -0,0 +1,38 @@
{
"achievementpercentages": {
"achievements": [
{
"name": "ACH_A1",
"percent": 88.2
},
{
"name": "ACH_A2",
"percent": 52.7
},
{
"name": "ACH_A3",
"percent": 74.1
},
{
"name": "ACH_A4",
"percent": 31.4
},
{
"name": "ACH_A5",
"percent": 44.9
},
{
"name": "ACH_A6",
"percent": 36.0
},
{
"name": "ACH_A7",
"percent": 28.3
},
{
"name": "ACH_A8",
"percent": 4.6
}
]
}
}
@@ -0,0 +1,30 @@
{
"achievementpercentages": {
"achievements": [
{
"name": "ACH_F1",
"percent": 91.2
},
{
"name": "ACH_F2",
"percent": 64.8
},
{
"name": "ACH_F3",
"percent": 48.5
},
{
"name": "ACH_F4",
"percent": 37.1
},
{
"name": "ACH_F5",
"percent": 22.4
},
{
"name": "ACH_F6",
"percent": 11.0
}
]
}
}
@@ -0,0 +1,30 @@
{
"achievementpercentages": {
"achievements": [
{
"name": "ACH_E1",
"percent": 83.4
},
{
"name": "ACH_E2",
"percent": 62.0
},
{
"name": "ACH_E3",
"percent": 44.3
},
{
"name": "ACH_E4",
"percent": 31.9
},
{
"name": "ACH_E5",
"percent": 27.5
},
{
"name": "ACH_E6",
"percent": 9.7
}
]
}
}
@@ -0,0 +1,22 @@
{
"achievementpercentages": {
"achievements": [
{
"name": "FIRST_STEPS",
"percent": 88.0
},
{
"name": "CRYSTAL_HEART",
"percent": 35.2
},
{
"name": "SUMMIT",
"percent": 30.6
},
{
"name": "FAREWELL",
"percent": 5.9
}
]
}
}
@@ -0,0 +1,22 @@
{
"achievementpercentages": {
"achievements": [
{
"name": "ACH_WAKE_UP",
"percent": 92.1
},
{
"name": "ACH_SURVIVE_CONTAINMENT",
"percent": 70.4
},
{
"name": "ACH_CO_OP",
"percent": 22.5
},
{
"name": "ACH_END_SP",
"percent": 48.3
}
]
}
}
@@ -0,0 +1,30 @@
{
"achievementpercentages": {
"achievements": [
{
"name": "ACH_C1",
"percent": 78.5
},
{
"name": "ACH_C2",
"percent": 47.2
},
{
"name": "ACH_C3",
"percent": 33.6
},
{
"name": "ACH_C4",
"percent": 35.4
},
{
"name": "ACH_C5",
"percent": 41.0
},
{
"name": "ACH_C6",
"percent": 12.9
}
]
}
}
@@ -0,0 +1,30 @@
{
"achievementpercentages": {
"achievements": [
{
"name": "ACH_D1",
"percent": 70.3
},
{
"name": "ACH_D2",
"percent": 25.8
},
{
"name": "ACH_D3",
"percent": 30.2
},
{
"name": "ACH_D4",
"percent": 15.6
},
{
"name": "ACH_D5",
"percent": 12.1
},
{
"name": "ACH_D6",
"percent": 8.4
}
]
}
}
@@ -0,0 +1,269 @@
{
"response": {
"game_count": 30,
"games": [
{
"appid": 620,
"name": "Portal 2",
"playtime_forever": 1450,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1787300000
},
{
"appid": 1145360,
"name": "Hades",
"playtime_forever": 3200,
"playtime_2weeks": 240,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790500000
},
{
"appid": 413150,
"name": "Stardew Valley",
"playtime_forever": 5400,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1788900000
},
{
"appid": 427520,
"name": "Factorio",
"playtime_forever": 12000,
"playtime_2weeks": 600,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790900000
},
{
"appid": 504230,
"name": "Celeste",
"playtime_forever": 800,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1789200000
},
{
"appid": 367520,
"name": "Hollow Knight",
"playtime_forever": 0,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true
},
{
"appid": 220,
"name": "Half-Life 2",
"playtime_forever": 780,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1786900000
},
{
"appid": 892970,
"name": "Valheim",
"playtime_forever": 90,
"playtime_2weeks": 90,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790700000
},
{
"appid": 1245620,
"name": "ELDEN RING",
"playtime_forever": 6100,
"playtime_2weeks": 900,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790000000
},
{
"appid": 1091500,
"name": "Cyberpunk 2077",
"playtime_forever": 4300,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1787900000
},
{
"appid": 292030,
"name": "The Witcher 3: Wild Hunt",
"playtime_forever": 5200,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1789800000
},
{
"appid": 1086940,
"name": "Baldur's Gate 3",
"playtime_forever": 2800,
"playtime_2weeks": 300,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790150000
},
{
"appid": 730,
"name": "Counter-Strike 2",
"playtime_forever": 1900,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1788600000
},
{
"appid": 570,
"name": "Dota 2",
"playtime_forever": 0,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true
},
{
"appid": 1174180,
"name": "Red Dead Redemption 2",
"playtime_forever": 0,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true
},
{
"appid": 105600,
"name": "Terraria",
"playtime_forever": 2600,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1789300000
},
{
"appid": 294100,
"name": "RimWorld",
"playtime_forever": 3900,
"playtime_2weeks": 120,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790300000
},
{
"appid": 632470,
"name": "Disco Elysium - The Final Cut",
"playtime_forever": 1500,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1788100000
},
{
"appid": 548430,
"name": "Deep Rock Galactic",
"playtime_forever": 700,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790000000
},
{
"appid": 646570,
"name": "Slay the Spire",
"playtime_forever": 2200,
"playtime_2weeks": 60,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790450000
},
{
"appid": 2379780,
"name": "Balatro",
"playtime_forever": 1100,
"playtime_2weeks": 420,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790600000
},
{
"appid": 1794680,
"name": "Vampire Survivors",
"playtime_forever": 450,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790700000
},
{
"appid": 268910,
"name": "Cuphead",
"playtime_forever": 900,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1787600000
},
{
"appid": 814380,
"name": "Sekiro: Shadows Die Twice",
"playtime_forever": 0,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true
},
{
"appid": 374320,
"name": "DARK SOULS III",
"playtime_forever": 0,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true
},
{
"appid": 1057090,
"name": "Ori and the Will of the Wisps",
"playtime_forever": 0,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true
},
{
"appid": 275850,
"name": "No Man's Sky",
"playtime_forever": 120,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1790200000
},
{
"appid": 526870,
"name": "Satisfactory",
"playtime_forever": 0,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true
},
{
"appid": 1332010,
"name": "Stray",
"playtime_forever": 330,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true,
"rtime_last_played": 1789000000
},
{
"appid": 108600,
"name": "Project Zomboid",
"playtime_forever": 0,
"playtime_2weeks": null,
"img_icon_url": "",
"has_community_visible_stats": true
}
]
}
}
@@ -0,0 +1,39 @@
{
"playerstats": {
"steamID": "76561198000000001",
"gameName": "Cyberpunk 2077",
"success": true,
"achievements": [
{
"apiname": "ACH_B1",
"achieved": 1,
"unlocktime": 1786000000
},
{
"apiname": "ACH_B2",
"achieved": 1,
"unlocktime": 1786259200
},
{
"apiname": "ACH_B3",
"achieved": 1,
"unlocktime": 1786518400
},
{
"apiname": "ACH_B4",
"achieved": 1,
"unlocktime": 1786777600
},
{
"apiname": "ACH_B5",
"achieved": 1,
"unlocktime": 1787036800
},
{
"apiname": "ACH_B6",
"achieved": 0,
"unlocktime": 0
}
]
}
}
@@ -0,0 +1,49 @@
{
"playerstats": {
"steamID": "76561198000000001",
"gameName": "ELDEN RING",
"success": true,
"achievements": [
{
"apiname": "ACH_A1",
"achieved": 1,
"unlocktime": 1786000000
},
{
"apiname": "ACH_A2",
"achieved": 1,
"unlocktime": 1786259200
},
{
"apiname": "ACH_A3",
"achieved": 1,
"unlocktime": 1786518400
},
{
"apiname": "ACH_A4",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "ACH_A5",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "ACH_A6",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "ACH_A7",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "ACH_A8",
"achieved": 0,
"unlocktime": 0
}
]
}
}
@@ -0,0 +1,39 @@
{
"playerstats": {
"steamID": "76561198000000001",
"gameName": "Stray",
"success": true,
"achievements": [
{
"apiname": "ACH_F1",
"achieved": 1,
"unlocktime": 1786000000
},
{
"apiname": "ACH_F2",
"achieved": 1,
"unlocktime": 1786259200
},
{
"apiname": "ACH_F3",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "ACH_F4",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "ACH_F5",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "ACH_F6",
"achieved": 0,
"unlocktime": 0
}
]
}
}
@@ -0,0 +1,39 @@
{
"playerstats": {
"steamID": "76561198000000001",
"gameName": "Cuphead",
"success": true,
"achievements": [
{
"apiname": "ACH_E1",
"achieved": 1,
"unlocktime": 1786000000
},
{
"apiname": "ACH_E2",
"achieved": 1,
"unlocktime": 1786259200
},
{
"apiname": "ACH_E3",
"achieved": 1,
"unlocktime": 1786518400
},
{
"apiname": "ACH_E4",
"achieved": 1,
"unlocktime": 1786777600
},
{
"apiname": "ACH_E5",
"achieved": 1,
"unlocktime": 1787036800
},
{
"apiname": "ACH_E6",
"achieved": 0,
"unlocktime": 0
}
]
}
}
@@ -0,0 +1,29 @@
{
"playerstats": {
"steamID": "76561198000000001",
"gameName": "Celeste",
"success": true,
"achievements": [
{
"apiname": "FIRST_STEPS",
"achieved": 1,
"unlocktime": 1700000000
},
{
"apiname": "CRYSTAL_HEART",
"achieved": 1,
"unlocktime": 1700003600
},
{
"apiname": "SUMMIT",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "FAREWELL",
"achieved": 0,
"unlocktime": 0
}
]
}
}
@@ -0,0 +1,29 @@
{
"playerstats": {
"steamID": "76561198000000001",
"gameName": "Portal 2",
"success": true,
"achievements": [
{
"apiname": "ACH_WAKE_UP",
"achieved": 1,
"unlocktime": 1700000000
},
{
"apiname": "ACH_SURVIVE_CONTAINMENT",
"achieved": 1,
"unlocktime": 1700003600
},
{
"apiname": "ACH_CO_OP",
"achieved": 0,
"unlocktime": 0
},
{
"apiname": "ACH_END_SP",
"achieved": 1,
"unlocktime": 1700010800
}
]
}
}
@@ -0,0 +1,39 @@
{
"playerstats": {
"steamID": "76561198000000001",
"gameName": "Disco Elysium - The Final Cut",
"success": true,
"achievements": [
{
"apiname": "ACH_C1",
"achieved": 1,
"unlocktime": 1786000000
},
{
"apiname": "ACH_C2",
"achieved": 1,
"unlocktime": 1786259200
},
{
"apiname": "ACH_C3",
"achieved": 1,
"unlocktime": 1786518400
},
{
"apiname": "ACH_C4",
"achieved": 1,
"unlocktime": 1786777600
},
{
"apiname": "ACH_C5",
"achieved": 1,
"unlocktime": 1787036800
},
{
"apiname": "ACH_C6",
"achieved": 0,
"unlocktime": 0
}
]
}
}
@@ -0,0 +1,39 @@
{
"playerstats": {
"steamID": "76561198000000001",
"gameName": "Slay the Spire",
"success": true,
"achievements": [
{
"apiname": "ACH_D1",
"achieved": 1,
"unlocktime": 1786000000
},
{
"apiname": "ACH_D2",
"achieved": 1,
"unlocktime": 1786259200
},
{
"apiname": "ACH_D3",
"achieved": 1,
"unlocktime": 1786518400
},
{
"apiname": "ACH_D4",
"achieved": 1,
"unlocktime": 1786777600
},
{
"apiname": "ACH_D5",
"achieved": 1,
"unlocktime": 1787036800
},
{
"apiname": "ACH_D6",
"achieved": 1,
"unlocktime": 1787296000
}
]
}
}
@@ -0,0 +1,12 @@
{
"response": {
"players": [
{
"steamid": "76561198000000001",
"personaname": "Dev",
"profileurl": "https://steamcommunity.com/profiles/76561198000000001/",
"avatarfull": "https://avatars.steamstatic.com/fef49e7fa7e1997310d705b2a6158ff8dc1cdfeb_full.jpg"
}
]
}
}
@@ -0,0 +1,58 @@
{
"game": {
"gameName": "Cyberpunk 2077",
"gameVersion": "1",
"availableGameStats": {
"achievements": [
{
"name": "ACH_B1",
"displayName": "Street Kid",
"description": "Get through the opening job.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg"
},
{
"name": "ACH_B2",
"displayName": "Chrome Fan",
"description": "Install five implants.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg"
},
{
"name": "ACH_B3",
"displayName": "Fast Driver",
"description": "Win a street race.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg"
},
{
"name": "ACH_B4",
"displayName": "Netrunner",
"description": "Hack ten enemies in one fight.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg"
},
{
"name": "ACH_B5",
"displayName": "Final Run",
"description": "Complete the main story.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg"
},
{
"name": "ACH_B6",
"displayName": "Rich Merc",
"description": "Hold a big pile of eddies.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1091500/capsule_184x69.jpg"
}
]
}
}
}
@@ -0,0 +1,74 @@
{
"game": {
"gameName": "ELDEN RING",
"gameVersion": "1",
"availableGameStats": {
"achievements": [
{
"name": "ACH_A1",
"displayName": "Rune Bearer",
"description": "Pick up your first rune from the grace.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg"
},
{
"name": "ACH_A2",
"displayName": "Margit Down",
"description": "Defeat the warden of the gate.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg"
},
{
"name": "ACH_A3",
"displayName": "Roundtable Guest",
"description": "Visit the hold between worlds.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg"
},
{
"name": "ACH_A4",
"displayName": "Smith Friend",
"description": "Upgrade a weapon to a high level.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg"
},
{
"name": "ACH_A5",
"displayName": "Mounted Hunter",
"description": "Slay a foe from horseback.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg"
},
{
"name": "ACH_A6",
"displayName": "Great Rune",
"description": "Restore a great rune.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg"
},
{
"name": "ACH_A7",
"displayName": "Deep Delver",
"description": "Explore a deep underground city.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg"
},
{
"name": "ACH_A8",
"displayName": "Lord of Lands",
"description": "Gather every legendary talisman.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1245620/capsule_184x69.jpg"
}
]
}
}
}
@@ -0,0 +1,58 @@
{
"game": {
"gameName": "Stray",
"gameVersion": "1",
"availableGameStats": {
"achievements": [
{
"name": "ACH_F1",
"displayName": "Cat Nap",
"description": "Sleep in a sunny spot.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg"
},
{
"name": "ACH_F2",
"displayName": "Rooftop Walker",
"description": "Cross the roofs of the old slum.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg"
},
{
"name": "ACH_F3",
"displayName": "Robot Friend",
"description": "Make a friend of a small robot.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg"
},
{
"name": "ACH_F4",
"displayName": "Meow Choir",
"description": "Meow in front of ten robots.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg"
},
{
"name": "ACH_F5",
"displayName": "Fish Lover",
"description": "Find a cold bowl of fish.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg"
},
{
"name": "ACH_F6",
"displayName": "Secret Paw",
"description": "Open every hidden door.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/1332010/capsule_184x69.jpg"
}
]
}
}
}
@@ -0,0 +1,58 @@
{
"game": {
"gameName": "Cuphead",
"gameVersion": "1",
"availableGameStats": {
"achievements": [
{
"name": "ACH_E1",
"displayName": "Contract Signed",
"description": "Take the deal at the casino.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg"
},
{
"name": "ACH_E2",
"displayName": "Run and Gun",
"description": "Pass a platform stage.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg"
},
{
"name": "ACH_E3",
"displayName": "Boss Rush",
"description": "Defeat five bosses.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg"
},
{
"name": "ACH_E4",
"displayName": "Devil Beaten",
"description": "Complete the main story.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg"
},
{
"name": "ACH_E5",
"displayName": "Coin Collector",
"description": "Find every coin of a world.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg"
},
{
"name": "ACH_E6",
"displayName": "Perfect Parry",
"description": "Parry twelve pink shots in a row.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/268910/capsule_184x69.jpg"
}
]
}
}
}
@@ -0,0 +1,42 @@
{
"game": {
"gameName": "Celeste",
"gameVersion": "1",
"availableGameStats": {
"achievements": [
{
"name": "FIRST_STEPS",
"displayName": "First Steps",
"description": "Complete the Prologue.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/504230/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/504230/capsule_184x69.jpg"
},
{
"name": "CRYSTAL_HEART",
"displayName": "Heart of the Mountain",
"description": "Collect a Crystal Heart.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/504230/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/504230/capsule_184x69.jpg"
},
{
"name": "SUMMIT",
"displayName": "Summit",
"description": "Reach the summit and finish the story.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/504230/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/504230/capsule_184x69.jpg"
},
{
"name": "FAREWELL",
"displayName": "Farewell",
"description": "Complete Chapter 9.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/504230/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/504230/capsule_184x69.jpg"
}
]
}
}
}
@@ -0,0 +1,42 @@
{
"game": {
"gameName": "Portal 2",
"gameVersion": "1",
"availableGameStats": {
"achievements": [
{
"name": "ACH_WAKE_UP",
"displayName": "Wake Up Call",
"description": "Survive the manual override of the relaxation center.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/620/capsule_184x69.jpg"
},
{
"name": "ACH_SURVIVE_CONTAINMENT",
"displayName": "Pit Boss",
"description": "Show that pit who is boss.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/620/capsule_184x69.jpg"
},
{
"name": "ACH_CO_OP",
"displayName": "Team Building",
"description": "Complete all test chambers in the Team Building co-op course.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/620/capsule_184x69.jpg"
},
{
"name": "ACH_END_SP",
"displayName": "Lunacy",
"description": "Complete the single player campaign.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/620/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/620/capsule_184x69.jpg"
}
]
}
}
}
@@ -0,0 +1,58 @@
{
"game": {
"gameName": "Disco Elysium - The Final Cut",
"gameVersion": "1",
"availableGameStats": {
"achievements": [
{
"name": "ACH_C1",
"displayName": "Fresh Case",
"description": "Wake up in the hostel room.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg"
},
{
"name": "ACH_C2",
"displayName": "Good Listener",
"description": "Talk to every skill voice.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg"
},
{
"name": "ACH_C3",
"displayName": "Thought Cabinet",
"description": "Fill all slots of the cabinet.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg"
},
{
"name": "ACH_C4",
"displayName": "Case Closed",
"description": "Finish the main story.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg"
},
{
"name": "ACH_C5",
"displayName": "Best Friend",
"description": "Win the trust of your partner.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg"
},
{
"name": "ACH_C6",
"displayName": "Sweet Tunes",
"description": "Hear every song on the radio.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/632470/capsule_184x69.jpg"
}
]
}
}
}
@@ -0,0 +1,58 @@
{
"game": {
"gameName": "Slay the Spire",
"gameVersion": "1",
"availableGameStats": {
"achievements": [
{
"name": "ACH_D1",
"displayName": "Spire Climber",
"description": "Reach the top of the first act.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg"
},
{
"name": "ACH_D2",
"displayName": "Card Hoarder",
"description": "Own forty cards in one run.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg"
},
{
"name": "ACH_D3",
"displayName": "Relic Fan",
"description": "Hold ten relics in one run.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg"
},
{
"name": "ACH_D4",
"displayName": "Silent Hunter",
"description": "Win a run as the second hero.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg"
},
{
"name": "ACH_D5",
"displayName": "Cold Heart",
"description": "Win a run as the third hero.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg"
},
{
"name": "ACH_D6",
"displayName": "Pure Deck",
"description": "Win a run with a tiny deck.",
"hidden": 0,
"icon": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg",
"icongray": "https://cdn.cloudflare.steamstatic.com/steam/apps/646570/capsule_184x69.jpg"
}
]
}
}
}
@@ -0,0 +1,34 @@
{
"response": {
"store_items": [
{
"appid": 1030300,
"success": 1,
"name": "Hollow Knight: Silksong",
"best_purchase_option": {
"formatted_final_price": "19,50€",
"formatted_original_price": "19,50€",
"discount_pct": 0
},
"assets": {
"asset_url_format": "steam/apps/1030300/${FILENAME}",
"header": "header.jpg"
}
},
{
"appid": 1145350,
"success": 1,
"name": "Hades II",
"best_purchase_option": {
"formatted_final_price": "22,49€",
"formatted_original_price": "29,99€",
"discount_pct": 25
},
"assets": {
"asset_url_format": "steam/apps/1145350/${FILENAME}",
"header": "header.jpg"
}
}
]
}
}
@@ -0,0 +1,14 @@
{
"response": {
"items": [
{
"appid": 1030300,
"date_added": 1735689600
},
{
"appid": 1145350,
"date_added": 1735776000
}
]
}
}
+5
View File
@@ -0,0 +1,5 @@
{
"access_token": "local",
"expires_in": 5000000,
"token_type": "bearer"
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "fields version_parent"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-editions.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/external_games"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-external-games.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "where id = 113112;"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-113112.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "where id = 119388;"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-119388.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "where id = 14593;"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-14593.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "where id = 26226;"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-26226.json"
}
}
@@ -0,0 +1,19 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "search \"Mega Man Legacy"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-search-psn-mega-man-legacy.json"
},
"priority": 4
}
@@ -0,0 +1,19 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "search \"Ghost of Tsushima"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-search-psn-tsushima.json"
},
"priority": 4
}
@@ -0,0 +1,19 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "search \"Ghost of Yōtei"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-search-psn-yotei.json"
},
"priority": 4
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "search \""
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-search.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "fields first_release_date;"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-game-years.json"
}
}
@@ -0,0 +1,14 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": []
},
"priority": 10
}
+18
View File
@@ -0,0 +1,18 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/games",
"bodyPatterns": [
{
"contains": "genres.name"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-tags.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "POST",
"urlPath": "/igdb/game_time_to_beats"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "igdb-time-to-beats.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/auth/authorize"
},
"response": {
"status": 302,
"headers": {
"Location": "com.scee.psxandroid.scecompcall://redirect/?error=invalid_grant"
}
},
"priority": 10
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/auth/authorize",
"headers": {
"Cookie": {
"contains": "npsso=local-npsso"
}
}
},
"response": {
"status": 302,
"headers": {
"Location": "com.scee.psxandroid.scecompcall://redirect/?code=local-code&cid=local"
}
},
"priority": 5
}
+13
View File
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/gamelist/v2/users/me/titles"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "psn-gamelist.json"
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"request": {
"method": "POST",
"urlPath": "/psn/auth/token"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "psn-token.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/trophy/v1/npCommunicationIds/NPWR90001_00/trophyGroups/all/trophies"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "psn-trophies-NPWR90001_00.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/trophy/v1/npCommunicationIds/NPWR90002_00/trophyGroups/all/trophies"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "psn-trophies-NPWR90002_00.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/trophy/v1/users/me/npCommunicationIds/NPWR90001_00/trophyGroups/all/trophies"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "psn-trophies-earned-NPWR90001_00.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/trophy/v1/users/me/npCommunicationIds/NPWR90002_00/trophyGroups/all/trophies"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "psn-trophies-earned-NPWR90002_00.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/trophy/v1/users/me/titles/trophyTitles"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "psn-trophy-title-sets.json"
}
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/psn/trophy/v1/users/me/trophyTitles"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "psn-trophy-titles.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/speedrun/games",
"queryParameters": {
"name": {
"equalTo": "Celeste"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "speedrun-games-celeste.json"
}
}
@@ -0,0 +1,16 @@
{
"request": {
"method": "GET",
"urlPath": "/speedrun/games"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"data": []
}
},
"priority": 10
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/speedrun/runs",
"queryParameters": {
"game": {
"equalTo": "o1y9j9v6"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "speedrun-runs-celeste.json"
}
}
@@ -0,0 +1,16 @@
{
"request": {
"method": "GET",
"urlPath": "/speedrun/runs"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"data": []
}
},
"priority": 10
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/",
"queryParameters": {
"gameid": {
"equalTo": "1091500"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-global-percentages-1091500.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/",
"queryParameters": {
"gameid": {
"equalTo": "1245620"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-global-percentages-1245620.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/",
"queryParameters": {
"gameid": {
"equalTo": "1332010"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-global-percentages-1332010.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/",
"queryParameters": {
"gameid": {
"equalTo": "268910"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-global-percentages-268910.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/",
"queryParameters": {
"gameid": {
"equalTo": "504230"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-global-percentages-504230.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/",
"queryParameters": {
"gameid": {
"equalTo": "620"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-global-percentages-620.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/",
"queryParameters": {
"gameid": {
"equalTo": "632470"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-global-percentages-632470.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/",
"queryParameters": {
"gameid": {
"equalTo": "646570"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-global-percentages-646570.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"achievementpercentages": {
"achievements": []
}
}
},
"priority": 10
}
@@ -0,0 +1,13 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/IPlayerService/GetOwnedGames/v1/"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-owned-games.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetPlayerAchievements/v1/",
"queryParameters": {
"appid": {
"equalTo": "1091500"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-player-achievements-1091500.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetPlayerAchievements/v1/",
"queryParameters": {
"appid": {
"equalTo": "1245620"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-player-achievements-1245620.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetPlayerAchievements/v1/",
"queryParameters": {
"appid": {
"equalTo": "1332010"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-player-achievements-1332010.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetPlayerAchievements/v1/",
"queryParameters": {
"appid": {
"equalTo": "268910"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-player-achievements-268910.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetPlayerAchievements/v1/",
"queryParameters": {
"appid": {
"equalTo": "504230"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-player-achievements-504230.json"
}
}
@@ -0,0 +1,18 @@
{
"request": {
"method": "GET",
"urlPath": "/steam/ISteamUserStats/GetPlayerAchievements/v1/",
"queryParameters": {
"appid": {
"equalTo": "620"
}
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "steam-player-achievements-620.json"
}
}
Loaded 100 of 680 files, more files were not shown because too many files have changed in this diff. Show more