Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Date added

A Millennium plugin that shows when a game was added to your library, as a card in the stats row of the library game page — alongside Cloud status, Achievements and Size on disk.

Installing

Copy this folder into your Millennium plugins/ directory and restart Steam, then enable it in Millennium's settings.

Only these are needed at runtime:

date-added/
├── plugin.json
└── .millennium/Dist/index.js

Building

npm install
npm run build

The bundle is written to .millennium/Dist/index.js and must be committed — Millennium installs plugins straight from the repository and does not build anything itself.

How it works

The date comes from rt_purchased_time on Steam's app overview, so it is read locally with no network access.

Three implementation notes:

  • Class names are looked up at runtime. Steam's CSS classes are content hashes that change between builds, so the card's styling is resolved through findClassModule(m => m.GameStat) rather than hardcoded.
  • The card is re-checked on a timer rather than hooked to navigation. The library lives in a separate popup window whose stats section React re-renders freely; a one-shot navigation hook would inject the card and then silently lose it. A one-second poll re-injects only when the card is missing or the game changed, so idle cost is a couple of DOM lookups.
  • The label reuses one of Steam's own strings (#AppProperties_Dlc_DateAdded), so it is translated wherever the client is, with no translation table to maintain. Steam returns a React node when it knows a token and echoes the raw token back when it does not, so the fallback to English tests for that rather than for null.

Not implemented: purchase vs key activation

Showing whether a game was bought on Steam or added with a product key was the intended second card. It was investigated thoroughly and dropped. Recording the findings so nobody repeats the search.

It is not available in the client. The payment method lives on the licence, and Steam never exposes licences to its JavaScript layer. Checked the app overview fields, all of SteamClient.Apps and SteamClient.User, and every payment_method reference in Steam's own bundles — the only hits are protobuf definitions for the key-activation flow and for user reviews.

The web account pages do have it. store.steampowered.com/account/licenses/ lists every licence with an acquisition method (Magasin Steam, Revendeur, Cadeau/Invitation, Gratuit). It is reachable from a webkit context, where a same-origin authenticated fetch works. It paginates ~100 rows at a time through ?continuationToken=<token>&offset=<n>, the token coming from the next-page link — an offset alone is ignored.

What killed it is the join. Licence rows carry no appid, no packageid and no link — only a product name — so apps can only be matched by title. Measured against a real 795-app library and its 784 licences:

Exact, unambiguous matches 377 (47%)
Ambiguous matches 0
No match 418 (53%)

The misses are structural, not fixable by better parsing: dedicated servers and SDKs have no licence of their own, bundle packages are never named after the games inside them, and app titles are localised while licence names are not (Agatha Christie – Mort sur le Nil never matches its English package).

Strict equality at least never lies — 0 ambiguous matches — but a card that is absent on half the library, in exchange for scraping eight paginated pages and maintaining it against Steam's HTML, was not judged worth it.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages