Added
- Legacy Games codes from Prime are redeemed for you – set
LG_EMAIL/LG_PASSWORDandsrc/stores/legacygames.py, on by default, signs in to your Legacy Games account and redeems Prime's codes in the same run, as they expire within days. Without them it only says how many codes wait. The newsletter stays unticked. - The browser's time zone matches your IP address – instead of UTC,
src/core/browser_timezone.pygives Chrome the zone your IP address is in, asking ipapi.co (or ipwho.is), which sees your IP, on the first run and then monthly (BROWSER_TIMEZONE_REFRESHsets run, week or month).TZorBROWSER_TIMEZONEpicks one yourself,offkeeps UTC.
Changed
- DLC without its base game is reported once, not every run (#78) – Steam now keeps these DLC in the database like Epic (
track_missing_base()insrc/core/claimer.py), and both list them once, then again every three weeks while they stay free.NOTIFY_MISSING_BASE=falsestill hides them for good. - Epic's checkout is clicked like a hand –
src/stores/epic.pyclicked the buttons in Epic's checkout frame by script, which a page can tell from a person. They are now real mouse clicks along a curve, a button off screen is reached with the mouse wheel, and every click is checked and made again if the page did not react. - Library updates can no longer break the image on their own –
requirements.txtcaps APScheduler, nodriver, httpx and SQLAlchemy below their next breaking version, so a rebuild cannot pull APScheduler 4, which drops the scheduler the bot uses. Dependabot still proposes each update. - The tests run on GitHub too –
.github/workflows/dependency-check.ymlnow runspython -m pytest tests/ -qand starts on every change tomain.py,src/ortests/, not only on dependency updates, so a pull request that breaks them shows a red check.
Removed
- The unused desktop stealth script –
_STEALTH_JSandinject_base_stealthinsrc/core/claimer.pyhad not run since 1.4, when they were switched off for causing captchas. They are gone, and so is the AliExpress URL blocking call that failed every run (set_blocked_urls). The bot does nothing differently.
Fixed
- AliExpress no longer raises the alarm when the next run can still collect – an empty coin page, a capped reward or a missing button used to ask you to collect by hand at once.
src/stores/aliexpress.pynow leaves it to the next run when that run still has hours of AliExpress's day left. - Itch.io no longer asks you to sign in when its page did not load (#59) –
_itch_session_ready()insrc/stores/gamerpower.pytook any page without a logout link, even an error page, as signed out and asked you to sign in over VNC. It now loads itch.io again; if it still shows nothing, it marks the giveawayfailed:itch-unreachableand tries next run. - Prime stops when the sign-in fails (#77) –
_ensure_logged_in()insrc/stores/prime.pynow says whether it worked. When nobody finishes the sign-in over VNC, the run ends with one message and a "Needed you" line in the summary instead of a "failed" line for every game; a session lost mid-run leaves the rest for the next run. - A dry run no longer adds or redeems anything – with
DRYRUN=true,_ensure_base_game()insrc/stores/steam.pystill clicked "Add to Library" for a DLC's free base game, and_redeem_gog_code()insrc/stores/gog.pyredeemed Prime codes left from an earlier run. Both now stop before the click and list it asavailable (dry run). - Steam checks your library before it reports a claim –
_claim_game()and_ensure_base_game()insrc/stores/steam.pyreported "claimed" right after the click. They now reload the store page and report it only when Steam shows the game in your library, otherwisefailed:unconfirmedwith a screenshot. - Epic never orders a game that costs money – a product page that sells the game ("Buy Now", a price) went through Epic's old checkout like a giveaway, which could charge a saved card.
_claim_game()insrc/stores/epic.pynow skips such a page, and_handle_purchase_iframe()orders only when the checkout total reads zero. - A two-factor key pasted with spaces works –
_fresh_totp()insrc/core/claimer.pyrefused a key copied in groups of four (JBSW Y3DP …) and the store stopped with an error. Spaces are now dropped, for every*_OTP_KEY. RESET_DB_GAMESkeeps codes still to redeem – it runs at every start and also erased Prime codes waiting for GOG, Microsoft or Legacy Games and Steam keys waiting for activation.reset_recent_games()inmain.pynow leaves those rows alone, and the README says to switch it off after one start.- Steam stops when the sign-in fails –
_ensure_logged_in()insrc/stores/steam.pynow says whether it worked, like Prime's. When nobody finishes the sign-in over VNC, the run ends with one message and a "Needed you" line instead of a failure for every game, and waiting Steam keys stay queued. - AliExpress's phone runs the Chrome the browser runs – the saved phone (
fgc_fingerprint.json) said Chrome 148 while the image runs Chrome 155, which a page can tell apart._load_or_make_fingerprint()insrc/stores/aliexpress.pynow moves it to the real version in the user agent, client hints and script alike; the phone stays the same. - The account in the summary no longer breaks its formatting – the masked address (
p***@gmail.com) put three asterisks into the notification, which Discord and Telegram read as bold, so the line turned bold and a stray**showed by the game.main.pynow passes it throughmarkdown_safe(), like game titles.
Security
- Game codes no longer appear whole in the log –
src/stores/prime.py,src/stores/gog.pyand a debug line inmain.pylogged each Prime code in full, and logs end up in bug reports. The log now shows the first five characters, like Steam keys; the whole code stays in your notification and indata/prime-gaming.json. - A missing VNC password is said out loud – without
VNC_PASSWORDanyone who reaches the noVNC port can use the browser and every store it is signed in to.start-vnc.shnow warns at every start, and the README explains it.