Repository navigation
Game statistics sources
Where each number on an account row comes from, what it sends over the network, and why one may be blank. For the GameStats.json file format, see Game statistics guide.
A game definition has one primary source and an optional list of fallbacks. On refresh the app tries them in order and keeps the first that returns at least one metric. The source that worked is remembered per account, so the next refresh starts there instead of retrying one that failed; if it fails, the rest of the chain is still tried.
If every source in the chain answers 404 or 410, the account's stats row is removed instead of left empty.
A source that names a collector is always tried first, whatever the account last used, because it reads a local file instead of making a request.
| Order | Source | Request |
|---|---|---|
| 1 |
steam-cs2-gcpd collector |
None. Reads CS2Ranks.json on disk |
| 2 | Leetify | https://api-public.cs-prod.leetify.com/v2/profiles/{SteamID64} |
| 3 | CSRep, through TcNo's API | https://api.tcno.co/sw/csrepStats?steamid={SteamID64} |
Leetify and CSRep supply Premier rating and competitive rank. Wingman comes only from Steam. The stats modal credits Leetify and CSRep; the Steam source is marked hidden and is not credited.
Source 1 only answers while CS2 Rank is on. With it off the chain starts at Leetify. See Settings.
| Game | Source |
|---|---|
| Apex Legends | https://api.tcno.co/sw/apexStats?player={EA username} |
| Overwatch |
https://playoverwatch.com/en-us/career/pc/{BattleTag}, read as HTML |
Neither has a fallback source.
Stats refresh in the background once they are older than the game's TTL: 3 hours by default, or 30 minutes for the account currently signed in while that game's process is running (cs2.exe, r5apex_dx12.exe, overwatch.exe). The running-process list is re-read every 5 minutes.
Results are cached in {UserData}/StatsCache/{game}.json. Offline mode stops every refresh, including the Steam checks below.
For an account signed in under Steam Guard/Auth, the app reads that account's own Game Personal Data page rather than a third-party API:
https://steamcommunity.com/profiles/{SteamID64}/gcpd/730?tab=matchmaking
The request carries that account's session cookie and pins Steam_Language=english, because the parser locates the cooldown table by its English header. One response yields the competitive matchmaking cooldown, the Premier rating and wins, the Wingman rank and wins, and the competitive skill group. Valve shows a cooldown to nobody but the account itself, so no public API has it.
A page the parser does not recognise, or Steam's sign-in page, writes nothing. Existing stored values are kept rather than cleared.
Prime is not on that page. With CS2 Prime Status on, an account with any Premier match on record is marked Prime without a second request, because Premier is Prime-gated. Every other account costs one more request:
https://store.steampowered.com/app/730/CounterStrike_2/
Fetched with the account's session, the store page marks the Prime Status Upgrade package as owned or not. CS2 Prime is a certain verdict. CS2 Non-Prime is a guess: accounts that reached rank 21 before 2019 were granted Prime without ever holding the package, and the store page shows them as not owning it. Accounts Steam holds no CS2 records for get neither tag.
Both are applied as tags, so the account list can be filtered by them. Turning the setting off removes both from every account.
It runs when the Steam Guard vault is unlocked, and every 6 hours while it stays unlocked. Under the default lease the vault relocks after five minutes, so the unlock is the trigger for most users; the 6-hour timer matters if you chose to remember the password for the session.
The check waits 2 seconds between accounts and will not re-check the same account inside 90 seconds. If Steam rate-limits the app, the sweep stops at that point rather than walking the rest of the list into the same wall, and the next unlock retries.
| File | Holds | Lifetime |
|---|---|---|
{UserData}/LoginCache/Steam/CS2Cooldowns.json |
Cooldown expiry, or a permanent flag | Until the expiry passes. The tile hides an expired one |
{UserData}/LoginCache/Steam/CS2Ranks.json |
Premier, Wingman, competitive rank, Prime verdict | 14 days, then ignored |
Both survive the vault relocking and survive removing the account from the vault. Reading them needs no credentials, so a rank drawn from Steam still renders on a locked vault; only the refresh stops.
A stored rank older than 14 days is ignored and the chain falls through to Leetify, then CSRep. The same happens when the stored entry has no Premier rating or no competitive rank, so an incomplete first-party answer never costs you the metrics a public API would have shown.
Ranks appear even on accounts with no CS2 stats row configured, as long as CS2 Rank is on. Where you have configured game stats, the configured row is what renders, and the same toggle gates that too: with CS2 Rank off, source 1 declines and the row falls through to Leetify and CSRep.
| Statistic | Source | Needs |
|---|---|---|
| CS2 competitive cooldown | Steam GCPD page | Steam Guard/Auth sign-in, vault unlocked at least once |
| CS2 Premier rating | Steam, else Leetify, else CSRep | Steam Guard for Steam's own figure. Fallbacks need only a SteamID64 |
| CS2 competitive rank | Steam, else Leetify, else CSRep | As above |
| CS2 Wingman rank | Steam GCPD page | Steam Guard/Auth |
CS2 Prime / CS2 Non-Prime tag |
Premier history, else the CS2 store page | Steam Guard/Auth, and CS2 Prime Status on |
| Apex ranked points and level | api.tcno.co | EA username entered on the account |
| Overwatch SR and level | playoverwatch.com | BattleTag entered on the account |
- The collector sends nothing. It reads
CS2Ranks.jsonfrom disk. - The GCPD and store requests go to Steam from your machine, signed in as that account, with that account's own session cookie. No third party is involved.
- Leetify receives your SteamID64 in the URL path, requested directly from your machine.
- The CSRep fallback sends your SteamID64 to
api.tcno.co. - Apex sends the EA username you entered to
api.tcno.co. Overwatch sends your BattleTag toplayoverwatch.com. - The Apex and Overwatch definitions each pull an image as well, from whatever host the answer points at rather than a host named here: Apex's rank badge from the
rankImgin the JSON, Overwatch's player portrait from thesrcon the page. Both are cached on disk and only re-fetched once the cached copy goes stale. - Turning CS2 Rank off takes Steam's own ranks out of the chain, so CS2 rows that were answered from disk start going to Leetify, and to CSRep if Leetify has nothing.
- Requests from the chain carry
User-Agent: TcNo-Acc-Switcherand nothing else, apart from a cookie header where a definition declares one. The image fetches use their own:TcNo-Acc-Switcher/1.0for the rank badge,TcNo Account Switcherfor the portrait.
Steam session tokens never pass through GameStats.json. That file is user-editable and ends up in debug dumps, which is why the Steam source is a collector with an empty Url rather than a URL with credentials in it.
Steam -> Settings -> Steam Guard/Auth -> Show states:
| Toggle | Default | Effect |
|---|---|---|
| CS2 Cooldown | On | Shows the cooldown on the account tile |
| CS2 Rank | On | Uses Steam's own ranks as the first CS2 source |
| CS2 Prime Status | Off | Applies the Prime tags. Costs one extra request per account with no Premier history |
The three read the same page, so any one of them being on is enough for the check to run. Turning all three off stops it.
CS2 Cooldown only gates the display. It does not stop the read: while any of the three is on, the cooldown is still fetched, still written to CS2Cooldowns.json, and the CS2 Cooldown tag is still applied. Turning all three off is what stops the read.
CS2 Rank off means Steam's own ranks are not used at all: not on accounts with no CS2 stats row, and not as source 1 for a configured one. A configured row then falls through to Leetify, and to CSRep if Leetify has nothing, so an account that was answered from disk starts sending its SteamID64 to a third party.
Per-account statistics are configured from the stats icon on an account row, including which metrics to show. Disabling a game there drops that account's cached row.
- The vault has not been unlocked. No unlock, no check. Nothing is read at startup.
- The account's saved Steam session has expired. The check skips it and does not renew it, because renewing writes to the vault and would invalidate an open Steam Guard window. Open the account once under right-click -> Steam Guard; that renews the session from the stored refresh token without asking for a password.
- The account is not in the Steam Guard vault. There is no first-party data for it, so CS2 falls through to Leetify and CSRep, and cooldown, Wingman and Prime stay blank.
- Steam answered with something unreadable, such as a sign-in page. Nothing is written and the previous values stand.
- The stored rank is over 14 days old. It is ignored, and the chain moves to the third-party sources.
- Steam rate-limited the app. The check stopped part way. Lock and unlock the vault to retry.
- The account has never played that mode. A zero rank is hidden rather than drawn.
- Offline mode is on. No source in any chain is contacted.
One thing comes back rather than staying missing: turning CS2 Cooldown off clears the CS2 Cooldown tag once, but the sweep still runs while CS2 Rank or CS2 Prime Status is on, and it re-applies the tag to any account on cooldown. Turn all three off to keep it gone.
| Item | Path |
|---|---|
| Definitions | {UserData}/GameStats.json |
| Custom definitions | {UserData}/GameStats.custom.json |
| Stats cache | {UserData}/StatsCache/{game}.json |
| CS2 cooldowns | {UserData}/LoginCache/Steam/CS2Cooldowns.json |
| CS2 ranks and Prime | {UserData}/LoginCache/Steam/CS2Ranks.json |
All trademarks and materials are the property of their respective owners and their licensors. This project is not affiliated with any companies referenced. This is not "Official" software or related to any companies mentioned. All it does is let you move your files around on your computer the same way you can. The use of names, icons and trademarks does not indicate endorsement of the trademark holder by this project or its creators, nor vice versa. They are only used to visually indicate which programs this project interacts with easily to the end-user.
By enabling optional features that scrape the web for publicly available information (such as limited game/profile statistics and other data), you understand and accept full responsibility for doing so on your own volition. If you appreciate accurate information, support the services providing it directly. The information collected is incredibly limited and is no replacement or competitor for sites scraped.
I am not responsible for the contents of external links. For the rest of the disclaimer, refer to the License (GNU General Public License v3.0) file: https://github.com/TCNOco/TcNo-Acc-Switcher/blob/master/LICENSE - See sections like 15, 16 and 17, as well as GitHub's 'simplification' at the top of the above website.
Information
Build and contribute
- Building from source
- Building on Linux
- Help code a platform
- Templated platform guide
- Game statistics guide
Platforms
Automation