Giter Site home page Giter Site logo

vogler / free-games-claimer Goto Github PK

View Code? Open in Web Editor NEW
2.1K 23.0 126.0 656 KB

Automatically claims free games on the Epic Games Store, Amazon Prime Gaming and GOG.

License: GNU Affero General Public License v3.0

JavaScript 93.08% Dockerfile 4.00% Shell 2.91%
epic-games playwright puppeteer automation free-games freebies claimer epic-games-store prime-gaming amazon-games

free-games-claimer's Introduction

logo-free-games-claimer

Code Smells

free-games-claimer

Claims free games periodically on

Pull requests welcome :)

Telegram Screenshot

Works on Windows/macOS/Linux.

Raspberry Pi (3, 4, Zero 2): requires 64-bit OS like Raspberry Pi OS or Ubuntu (Raspbian won't work since it's 32-bit).

How to run

Easy option: install Docker (or podman) and run this command in a terminal:

docker run --rm -it -p 6080:6080 -v fgc:/fgc/data --pull=always ghcr.io/vogler/free-games-claimer

This currently gives you a captcha challenge for epic-games. Until issue #183 is fixed, it is recommended to just run node epic-games without docker (see below).

This will run node epic-games; node prime-gaming; node gog - if you only want to claim games for one of the stores, you can override the default command by appending e.g. node epic-games at the end of the docker run command, or if you want several bash -c "node epic-games.js; node gog.js". Data (including json files with claimed games, codes to redeem, screenshots) is stored in the Docker volume fgc.

I want to run without Docker or develop locally.
  1. Install Node.js
  2. Clone/download this repository and cd into it in a terminal
  3. Run npm install
  4. Run pip install apprise (or use pipx if you have problems) to install apprise if you want notifications
  5. To get updates: git pull; npm install
  6. Run node epic-games, node prime-gaming, node gog...

During npm install Playwright will download its Firefox to a cache in home (doc). If you are missing some dependencies for the browser on your system, you can use sudo npx playwright install firefox --with-deps.

If you don't want to use Docker for quasi-headless mode, you could run inside a virtual machine, on a server, or you wake your PC at night to avoid being interrupted.

Usage

All scripts start an automated Firefox instance, either with the browser GUI shown or hidden (headless mode). By default, you won't see any browser open on your host system.

  • When running inside Docker, the browser will be shown only inside the container. You can open http://localhost:6080 to interact with the browser running inside the container via noVNC (or use other VNC clients on port 5900).
  • When running the scripts outside of Docker, the browser will be hidden by default; you can use SHOW=1 ... to show the UI (see options below).

When running the first time, you have to login for each store you want to claim games on. You can login indirectly via the terminal or directly in the browser. The scripts will wait until you are successfully logged in.

There will be prompts in the terminal asking you to enter email, password, and afterwards some OTP (one time password / security code) if you have 2FA/MFA (two-/multi-factor authentication) enabled. If you want to login yourself via the browser, you can press escape in the terminal to skip the prompts.

After login, the script will continue claiming the current games. If it still waits after you are already logged in, you can restart it (and open an issue). If you run the scripts regularly, you should not have to login again.

Configuration / Options

Options are set via environment variables which allow for flexible configuration.

TODO: On the first run, the script will guide you through configuration and save all settings to data/config.env. You can edit this file directly or run node fgc config to run the configuration assistant again.

Available options/variables and their default values:

Option Default Description
SHOW 1 Show browser if 1. Default for Docker, not shown when running outside.
WIDTH 1280 Width of the opened browser (and of screen for VNC in Docker).
HEIGHT 1280 Height of the opened browser (and of screen for VNC in Docker).
VNC_PASSWORD VNC password for Docker. No password used by default!
NOTIFY Notification services to use (Pushover, Slack, Telegram...), see below. Apprise
NOTIFY_TITLE Optional title for notifications, e.g. for Pushover.
BROWSER_DIR data/browser Directory for browser profile, e.g. for multiple accounts.
TIMEOUT 60 Timeout for any page action. Should be fine even on slow machines.
LOGIN_TIMEOUT 180 Timeout for login in seconds. Will wait twice (prompt + manual login).
EMAIL Default email for any login.
PASSWORD Default password for any login.
EG_EMAIL Epic Games email for login. Overrides EMAIL.
EG_PASSWORD Epic Games password for login. Overrides PASSWORD.
EG_OTPKEY Epic Games MFA OTP key.
EG_PARENTALPIN Epic Games Parental Controls PIN.
PG_EMAIL Prime Gaming email for login. Overrides EMAIL.
PG_PASSWORD Prime Gaming password for login. Overrides PASSWORD.
PG_OTPKEY Prime Gaming MFA OTP key.
PG_REDEEM 0 Prime Gaming: try to redeem keys on external stores (experimental).
PG_CLAIMDLC 0 Prime Gaming: try to claim DLCs (experimental).
GOG_EMAIL GOG email for login. Overrides EMAIL.
GOG_PASSWORD GOG password for login. Overrides PASSWORD.
GOG_NEWSLETTER 0 Do not unsubscribe from newsletter after claiming a game if 1.

See src/config.js for all options.

How to set options

You can add options directly in the command or put them in a file to load.

Docker

You can pass variables using -e VAR=VAL, for example docker run -e [email protected] -e NOTIFY='tgram://bottoken/ChatID' ... or using --env-file fgc.env where fgc.env is a file on your host system (see docs). You can also docker cp your configuration file to /fgc/data/config.env in the fgc volume to store it with the rest of the data instead of on the host (example). If you are using docker compose (or Portainer etc.), you can put options in the environment: section.

Without Docker

On Linux/macOS you can prefix the variables you want to set, for example [email protected] SHOW=1 node epic-games will show the browser and skip asking you for your login email. You can also put options in data/config.env which will be loaded by dotenv.

Notifications

The scripts will try to send notifications for successfully claimed games and any errors like needing to log in or encountered captchas (should not happen).

apprise is used for notifications and offers many services including Pushover, Slack, Telegram, SMS, Email, desktop and custom notifications. You just need to set NOTIFY to the notification services you want to use, e.g. NOTIFY='mailto://myemail:[email protected]' 'pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b' - refer to their list of services and examples.

Automatic login, two-factor authentication

If you set the options for email, password and OTP key, there will be no prompts and logins should happen automatically. This is optional since all stores should stay logged in since cookies are refreshed. To get the OTP key, it is easiest to follow the store's guide for adding an authenticator app. You should also scan the shown QR code with your favorite app to have an alternative method for 2FA.

  • Epic Games: visit password & security, enable 'third-party authenticator app', copy the 'Manual Entry Key' and use it to set EG_OTPKEY.
  • Prime Gaming: visit Amazon 'Your Account › Login & security', 2-step verification › Manage › Add new app › Can't scan the barcode, copy the bold key and use it to set PG_OTPKEY
  • GOG: only offers OTP via email

Beware that storing passwords and OTP keys as clear text may be a security risk. Use a unique/generated password! TODO: maybe at least offer to base64 encode for storage.

Epic Games Store

Run node epic-games (locally or in Docker).

Amazon Prime Gaming

Run node prime-gaming (locally or in Docker).

Claiming the Amazon Games works out-of-the-box, however, for games on external stores you need to either link your account or redeem a key.

  • Stores that require account linking: Epic Games, Battle.net, Origin.

  • Stores that require redeeming a key: GOG.com, Microsoft Games, Legacy Games.

    Keys and URLs are printed to the console, included in notifications and saved in data/prime-gaming.json. A screenshot of the page with the key is also saved to data/screenshots. TODO: redeem keys on external stores.

Run periodically

How often?

Epic Games usually has two free games every week, before Christmas every day. Prime Gaming has new games every month or more often during Prime days. GOG usually has one new game every couples of weeks. Unreal Engine has new assets to claim every first Tuesday of a month.

It is safe to run the scripts every day.

How to schedule?

The container/scripts will claim currently available games and then exit. If you want it to run regularly, you have to schedule the runs yourself:

  • Linux/macOS: crontab -e (example)
  • macOS: launchd
  • Windows: task scheduler, other options, or just put the command in a .bat file in Autostart if you restart often...
  • any OS: use a process manager like pm2
  • Docker Compose command: bash -c "node epic-games; node prime-gaming; node gog; echo sleeping; sleep 1d" additionally add restart: unless-stopped to it.

TODO: add some server-mode where the script just keeps running and claims games e.g. every day.

Problems?

Check the open issues and comment there or open a new issue.

If you're a developer, you can use PWDEBUG=1 ... to inspect which opens a debugger where you can step through the script.

History/DevLog

Click to expand

Tried epicgames-freebies-claimer, but had problems since epicgames introduced hcaptcha (see issue).

Played around with puppeteer before, now trying newer https://playwright.dev which is pretty similar. Playwright Inspector and codegen to generate scripts are nice, but failed to generate the right code for clicking a button in an iframe.

Added main.spec.ts which was the test script generated by npx playwright codegen with manual fix for clicking buttons in the created iframe. Can be executed by npx playwright test. The test runner has options --debug and --timeout and can execute typescript which is nice. However, this only worked up to the button 'I Agree', and then showed an hcaptcha.

Added main.captcha.js which uses beta of playwright-extra@next and @extra/recaptcha@next (from comment on puppeteer-extra). However, playwright-extra seems to be old and missing :has-text selector (fixed here) and page.frameLocator, so the script did not run without adjustments. Also, solving via 2captcha is a paid service which takes time and may be unreliable.

Added main.stealth.js which uses the stealth plugin without playwright-extra wrapper but up-to-date playwright (from comment). The listed evasions are enough to not show an hcaptcha. Script claimed game successfully in non-headless mode.

Removed main.captcha.js. Using Playwright Test (main.spec.ts) instead of Library (main.stealth.js) has the advantage of free CLI like --debug and --timeout.

Button selectors should preferably use text in order to be more stable against changes in the DOM.

Renamed repository from epicgames-claimer to free-games-claimer since a script for Amazon Prime Gaming was also added. Removed all old scripts in favor of just epic-games.js and prime-gaming.js.

epic games: headless mode gets hcaptcha challenge. More details/references in issue.

#11 introduced a Dockerfile for running non-headless inside the container via xvfb which makes it headless for the host running the container.

v1.0 Standalone scripts node epic-games and node prime-gaming using Chromium.

Changed to Firefox for all scripts since Chromium led to captchas. Claiming then also worked in headless mode without Docker.

Added options via env vars, configurable in data/config.env.

Added OTP generation via otplib for automatic login, even with 2FA.

Added notifications via apprise.

Star History Chart

Alt


Logo with smaller aspect ratio (for Telegram bot etc.): 👾 - emojipedia

logo-fgc

free-games-claimer's People

Contributors

4n4n4s avatar dependabot[bot] avatar gladiopeace avatar jackblk avatar jumoog avatar kevinmatthe avatar luke-rie avatar oj7 avatar primajin avatar vogler avatar xegare avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

free-games-claimer's Issues

page.waitForURL: Navigation failed because page was closed!

When logging into prime gaming I get this error:

page.waitForURL: Navigation failed because page was closed!
=========================== logs ===========================
waiting for navigation to "https://gaming.amazon.com/home?signedIn=true" until "load"
============================================================
    at file:///.../free-games-claimer/prime-gaming.js:83:16

No idea why.

[Store/DLC] Claim in-game content on Amazon Prime

This is more of a nice to have thing, but within the Amazon Games site, a number of developers offer in game content and items (For example Two Point Hospital does every month)
Would there be a way to enable claiming this alongside the free games?

The delivery mechanism is essentially the same as the existing games we’re claiming, and filtering could potentially be done by the listed game name, which each tile has on it, if we were to define in an environmental variable the names of the games we want to claim content for, then the tool could look for only those, and claim them.

As I said it’s not an urgent request or anything, if possible it would be a great value-add to the existing tool, especially if the existing code can be adapted to grab it with minimal effort.

Timeout claiming Prime games

Hi,
i've done a fresh install of NodeJs (19.6.0 and npm 9.5.0) on a Windows 10 machine. I've no problem using GOG and EPic Games claimer (i'm using the latest version available updated 13hours ago). This is the error i'm getting:

Catch error: page.click: Timeout 20000ms exceeded.
=========================== logs ===========================
waiting for locator('button[data-type="Game"]')
============================================================
    at file:///C:/Users/ 'xxx' /Downloads/free-games-claimer-main/prime-gaming.js:85:14 {
  name: 'TimeoutError'
}

Unable to choose Twitch account

Hey there, thanks for all your work on this!

I'm trying to claim prime gaming games, but am unable to scroll down and choose the Twitch account I'm claiming on as I have more than one linked to the Amazon account.

image

The code waits for the element to become visible around 30 times and then eventually times out.

404 Error when script clicks link.

C:\Users\nick\Downloads\free-games-claimer\update>node epic-games
userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Sa
fari/537.36
Signed in.
Number of free games: 2
urlSlug /en-US/p/runbow-fc9fa4
locator.innerText: Timeout 20000ms exceeded.
=========================== logs ===========================
waiting for selector "//button[@data-testid="purchase-cta-button"][not(contains(.,"Loading"))] >> nth=0"
============================================================
    at file:///C:/Users/nick/Downloads/free-games-claimer/update/epic-games.js:83:124 {
  name: 'TimeoutError'
}

[NOTIFICATIONS] Telegram notification won't work

Hi!

I followed the instructions of apprise for the notification via Telegram. Unfortunately it doesn't seem to work

I have the TOKEN API provided by "BotFather" I have my chat id, but I can't receive anything.

Someone have this issue ?

Unable to go past "Verify you are a human" check

Hi everyone,
i'm trying to get this script working using Docker (the latest versiona available, downloaded today) and followring your instructions (i'm not a programming expert).
I've managed to login using http://localhost:6080 and using my Facebook credentials. The script is getting stuck in the next part, where Epic Games store is asking "One more step". I'm clicking on "I'm a human" (or something similar) but the script simply stops there.

Is there any workaround? Am i missing something?

Docker errors

Hello. All problems in the screenshot. Instead of $(pwd) specified an absolute path
1651407543

refactor `epic-games.json`: remove `.runs`, lift `.claimed`

Does anyone use the .runs field?
I think it would be nicer to just have a map {urlSlug: game}, then the file is just a database of claimed games.
Objects apparently also have insertion order for non-number strings, so there's not need for a list: https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order
I'll refactor the logging and save it to data/logs/epic-games.log, then this file will contain the events.

Not scraping for GOG Games

This script is outstanding! I have started using it today. I have been able to get everything working with Epic and Prime. I have not been prompted for creds for GOG, is this expected behaviour if there are no available games or is there an issue where it isn't prompting for GOG creds/scraping for GOG games?

Unhandled "This product is currently unavailable in your region"

Ran on docker

Scenario:
There are multiple free games to be claimed, but some of them are unavailable in the user's region.

Expected behaviour:
Games that are unavailable are skipped and games that are available are claimed.

Existing behaviour:
Script exited after first attempt on unavailable game due to time out.

image

Logs:

$ docker run --rm -p 6080:6080 -v fgc:/fgc/data ghcr.io/vogler/free-games-claimer node epic-games
Xvfb display server created screen with resolution 1280x1280
VNC is running on port 5900 (no password!)
noVNC (VNC via browser) is running on http://localhost:6080

2023-01-13 01:34:39.763 started checking epic-games
Signed in as ***********
Free games: [
  'https://store.epicgames.com/en-US/p/divine-knockout--standard',
  'https://store.epicgames.com/en-US/p/first-class-trouble',
  'https://store.epicgames.com/en-US/p/gamedec'
]
Current free game: Divine Knockout (DKO)
  Not in library yet! Click GET.
locator.click: Timeout 20000ms exceeded.
=========================== logs ===========================
  waiting for frameLocator('#webPurchaseContainer iframe')
  locator resolved to visible <iframe class="" src="/purchase?highlightColor=0078f2&of…></iframe>
waiting for frameLocator('#webPurchaseContainer iframe').locator('button:has-text("Place Order")')
============================================================
    at file:///fgc/epic-games.js:151:62 {
  name: 'TimeoutError'
}

GOG Error 'TypeError: Cannot read properties of null (reading '1')'

Full Command Log:

2023-02-17 04:16:59.405 started checking gog
Signed in as 'username'
TypeError: Cannot read properties of null (reading '1')
    at file:///.../free-games-claimer/gog.js:90:58
    at runNextTicks (node:internal/process/task_queues:60:5)
    at process.processImmediate (node:internal/timers:442:9)

Line of code the error resides from:
const title = text.match(/Claim (.*) and don't miss/)[1];

Specifically the array item selection [1]

Redeem keys on external stores (GOG, Microsoft, Legacy Games)

TODO for prime-gaming: redeem shown game keys on external stores:

From README:

Claiming the Amazon Games works out-of-the-box, however, for games on external stores you need to either link your account or redeem a key.

  • Stores that require account linking: Epic Games, Battle.net, Origin.
  • Stores that require redeeming a key: GOG.com, Microsoft Games, Legacy Games.

headless mode fails at hcaptcha challenge

Currently the script runs not in headless mode, i.e., the automated browser is visible.
Comment out this line to not show the browser:
https://github.com/vogler/epicgames-claimer/blob/fd3f947223733b187c5e1903be1209f8fd3b618c/main.stealth.js#L28

Running in headless mode resulted in the 20s timeout and the game not being claimed.
https://github.com/vogler/epicgames-claimer/blob/fd3f947223733b187c5e1903be1209f8fd3b618c/main.stealth.js#L124
Running in headful mode afterwards successfully claimed the game.

Assumption is that the captcha is shown in headless mode, despite the stealth plugin.

Error SystemPageSize

Hello and thank you for this program.
I run into trouble claiming prime-games.

This is my edited docker-compose.yml:

# docker compose up
services:
  free-games-claimer:
    container_name: fgc # is printed in front of every output line
    image: ghcr.io/vogler/free-games-claimer # otherwise image name will be free-games-claimer-free-games-claimer
    build: .
    command: sh -c "node epic-games.js && node prime-gaming.js"
    ports:
      - "25568:5900"
      - "25569:6080"
    volumes:
      - ./data:/fgc/data

And this is my docker-compose up run output:

[+] Running 1/0
 ⠿ Container fgc  Recreated                                         0.1s      
Attaching to fgc
fgc  | Xvfb display server created screen with resolution 1280x1280.
fgc  | VNC is running on port 5900 (no password!).
fgc  | noVNC is running on http://localhost:6080
fgc  |
fgc  | Signed in as ***********
fgc  | Free games: [ 'https://store.epicgames.com/en-US/p/thems-fightin-herds' ]
fgc  | Current free game: Them's Fightin' Herds
fgc  |   Already in library! Nothing to claim.
fgc  | node:internal/process/esm_loader:97
fgc  |     internalBinding('errors').triggerUncaughtException(
fgc  |                               ^
fgc  |
fgc  | browserType.launchPersistentContext: Browser closed.
fgc  | ==================== Browser output: ====================
fgc  | <launching> /root/.cache/ms-playwright/chromium-1040/chrome-linux/chrome --disable-field-trial-config --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --no-sandbox --user-data-dir=/fgc/data/browser --remote-debugging-pipe about:blank
fgc  | <launched> pid=516
fgc  | [pid=516][err] ../../base/allocator/partition_allocator/partition_root.cc(799) Check failed: (internal::SystemPageSize() == (size_t{1} << 12)) || (internal::SystemPageSize() == (size_t{1} << 14))
fgc  | =========================== logs ===========================
fgc  | <launching> /root/.cache/ms-playwright/chromium-1040/chrome-linux/chrome --disable-field-trial-config --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,DialMediaRouteProvider,AcceptCHFrame,AutoExpandDetailsElement,CertificateTransparencyComponentUpdater,AvoidUnnecessaryBeforeUnloadCheckSync,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --no-sandbox --user-data-dir=/fgc/data/browser --remote-debugging-pipe about:blank
fgc  | <launched> pid=516
fgc  | [pid=516][err] ../../base/allocator/partition_allocator/partition_root.cc(799) Check failed: (internal::SystemPageSize() == (size_t{1} << 12)) || (internal::SystemPageSize() == (size_t{1} << 14))
fgc  | ============================================================
fgc  |     at async file:///fgc/prime-gaming.js:25:17 {
fgc  |   name: 'Error'
fgc  | }
fgc exited with code 1

Can you please help me with my problem?

Notify only upon newly claimed game

Very happy to see the NOTIFY config option added! However, a notification each time the script is run, even if there are no newly claimed games, seems unnecessary and decreases the value of notifications. I don't need to know when the script did nothing.

Could a new config option be added to change this behavior?

restarting container fails

when i restart the container i get this error:
ozone_platform_x11.cc(246)] Missing X server or $DISPLAY

Playwright Firefox missing in latest Docker Image

After updating from Docker Image 269ebc1bbea5 to cb43362ac418, I am seeing the following error with a Docker Compose installation. This issue did not exist before the latest update.

docker-compose.yml:

version: "3"
services:
  free-games-claimer:
    container_name: free-games-claimer
    image: voglerr/free-games-claimer:latest
    ports:
      - 5900:5900
      - 6080:6080
    volumes:
      - /home/ethan/free-games-claimer:/fgc/data

Logs:

Xvfb display server created screen with resolution 1280x1280.
VNC is running on port 5900 (no password!).
noVNC is running on http://localhost:6080
node:internal/process/esm_loader:97
    internalBinding('errors').triggerUncaughtException(
                              ^
browserType.launchPersistentContext: Executable doesn't exist at /root/.cache/ms-playwright/firefox-1369/firefox/firefox
╔═════════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just installed or updated. ║
║ Please run the following command to download new browsers:              ║
║                                                                         ║
║     npx playwright install                                              ║
║                                                                         ║
║ <3 Playwright Team                                                      ║
╚═════════════════════════════════════════════════════════════════════════╝
    at async file:///fgc/epic-games.js:36:17 {
  name: 'Error'
}

Run on Raspberry Pi -> requires 64-bit OS

Chromium runs on Raspberry Pi, but Playwright seems to not support it out-of-the-box.
Only tried running headless via ssh, maybe it works otherwise.
Reported architectures (uname -m) are
rpi3: armv7l
rpi4: aarch64 (64-bit kernel via arm_64bit=1)

$ npx playwright open google.de
browserType.launch: Browser closed.
==================== Browser output: ====================
<launching> /home/pi/.cache/ms-playwright/chromium-939194/chrome-linux/chrome --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,AcceptCHFrame --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --no-sandbox --user-data-dir=/tmp/playwright_chromiumdev_profile-FjzIbQ --remote-debugging-pipe --no-startup-window
<launched> pid=4731
[pid=4731][err] /home/pi/.cache/ms-playwright/chromium-939194/chrome-linux/chrome: 1: Syntax error: Unterminated quoted string
[pid=4731] <process did exit: exitCode=2, signal=null>
[pid=4731] starting temporary directories cleanup
=========================== logs ===========================
<launching> /home/pi/.cache/ms-playwright/chromium-939194/chrome-linux/chrome --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,AcceptCHFrame --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --no-sandbox --user-data-dir=/tmp/playwright_chromiumdev_profile-FjzIbQ --remote-debugging-pipe --no-startup-window
<launched> pid=4731
[pid=4731][err] /home/pi/.cache/ms-playwright/chromium-939194/chrome-linux/chrome: 1: Syntax error: Unterminated quoted string
[pid=4731] <process did exit: exitCode=2, signal=null>
[pid=4731] starting temporary directories cleanup
============================================================
    at launchContext (/home/pi/epicgames-claimer/node_modules/playwright-core/lib/cli/cli.js:298:37)
    at Command.listener [as _actionHandler] (/home/pi/epicgames-claimer/node_modules/commander/lib/command.js:488:17)
    at /home/pi/epicgames-claimer/node_modules/commander/lib/command.js:1227:65
    at Command._chainOrCall (/home/pi/epicgames-claimer/node_modules/commander/lib/command.js:1144:12)
    at Command._parseCommand (/home/pi/epicgames-claimer/node_modules/commander/lib/command.js:1227:27)
    at Command._dispatchSubcommand (/home/pi/epicgames-claimer/node_modules/commander/lib/command.js:1050:25)
    at Command._parseCommand (/home/pi/epicgames-claimer/node_modules/commander/lib/command.js:1193:19)
    at Command.parse (/home/pi/epicgames-claimer/node_modules/commander/lib/command.js:897:10) {
  name: 'Error'
}

Adding executablePath: '/usr/bin/chromium-browser' to https://github.com/vogler/epicgames-claimer/blob/fd3f947223733b187c5e1903be1209f8fd3b618c/main.stealth.js#L26 gives

$ npm start

> start
> node main.stealth

node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

browserType.launchPersistentContext: Browser closed.
==================== Browser output: ====================
<launching> /usr/bin/chromium-browser --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,AcceptCHFrame --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --no-sandbox --user-data-dir=userDataDir --remote-debugging-pipe about:blank
<launched> pid=25655
[pid=25655][err] [0110/114804.067560:ERROR:elf_dynamic_array_reader.h(61)] tag not found
=========================== logs ===========================
<launching> /usr/bin/chromium-browser --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=ImprovedCookieControls,LazyFrameLoading,GlobalMediaControls,DestroyProfileOnBrowserClose,MediaRouter,AcceptCHFrame --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --no-sandbox --user-data-dir=userDataDir --remote-debugging-pipe about:blank
<launched> pid=25655
[pid=25655][err] [0110/114804.067560:ERROR:elf_dynamic_array_reader.h(61)] tag not found
============================================================
    at /home/pi/epicgames-claimer/main.stealth.js:26:34
    at Object.<anonymous> (/home/pi/epicgames-claimer/main.stealth.js:137:3) {
  name: 'Error'
}

but that's likely due to my rpi4 running headless since it shows the same error without Playwright:

$ chromium-browser
[0110/122436.415559:ERROR:elf_dynamic_array_reader.h(61)] tag not found
[1]    16438 trace trap  chromium-browser

unable to login

Hi, have followed your instructions but I am not able to login because I am receiving °incorrect response° error. Userid and password are correct .

Questions about setup, docker compose, config via env vars

Hello Everyone

I just came across this project and have run in to an issues that was bough up to me

  1. I'm running this as a docker-compose i know how
  2. I also have someone else look over this and pointed out two things witch i didn't see first time

I'm happy to upload my docker-compose if needed but for not i will upload a screen shot and the info needed

I'm trying to run this as a docker-compose with docker nothing new I'm doing this via my Synology NAS witch is fine
But I'm getting error witch can be see from the Attach files
Capture02
Capture

the issues is "npx playwright install"
The author can fix this but including this as part of it or it will fail and not run during build.

Please fix this or help me work out how to fix it I don't get how to install npx on a synology nas but besides the point should be part of the build as its a container

timeout epic

hi
i got timeouts.

/usr/bin/docker run --rm -p 6080:6080 -p 5900:5900 -v /mnt/nfs/export/docker/free-games-claimer_jackblk/epic-games/data:/fgc/data --name free-games-claimer_jackblk-epic-games free-games-claimer-epic-games
userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36
Signed in.
Number of free games: 2
locator.innerText: Timeout 20000ms exceeded.
=========================== logs ===========================
waiting for selector "//button[@data-testid="purchase-cta-button"][not(contains(.,"Loading"))] >> nth=0"
============================================================
    at file:///fgc/epic-games.js:71:124 {
  name: 'TimeoutError'
}

any ideas about that?
thanks

How does one update the docker container?

I installed it using the docker run --rm -it -p 6080:6080 -v fgc:/fgc/data ghcr.io/vogler/free-games-claimer method, and recently Epic Games changed the page layout (cecc540).
I'm just seeing timeouts, with the error waiting for locator('h1 div').first(), which is probably because I'm running on the same version since I installed it.

How does one update the container to the latest version?

GoG Free Games

On occasion there are banners on the GoG Website and Launcher giving you the opportunity to grab stuff for free

in HTML there are snippets like this:

<div class="giveaway-banner--with-consent__content"> <a ng-href="/en/game/the_witcher_goodies_collection" giveaway-banner="" giveaway-banner-id="1653256799000" with-marketing-consent="1" class="container giveaway-banner giveaway-banner--with-consent is-claimed" ng-class="{ 'is-loading': giveaway.isLoading, 'is-claiming': giveaway.isClaiming, 'is-claimed': giveaway.isClaimed }" onclick="window.gogTools.sendPromotionClick( '\u007B\u0022id\u0022\u003A\u00222a222a59\u002D5d0b\u002D4dc0\u002D9b1e\u002D5fad137b8b47\u0022,\u0022endTime\u0022\u003A1653256799000,\u0022background\u0022\u003A\u0022c645f5f33e1ef1e456b8698566b0c318afc03930498644f77aa3198d7ebe4181\u0022,\u0022mobileBackground\u0022\u003A\u0022ab4cf414b593142da6efe98039cd8801fc5da61e99bc2fef96301e9fdab178a8\u0022,\u0022title\u0022\u003A\u0022The\u0020Witcher\u0020Goodies\u0020Collection\u0022,\u0022logo\u0022\u003A\u007B\u0022image\u0022\u003A\u002298a7194007a04dd602dca9847bbbb5a42a5282688c13e7612049fa4b366a99a5\u0022,\u0022styles\u0022\u003A\u007B\u0022mobile\u0022\u003A\u007B\u0022top\u0022\u003A\u00220px\u0022,\u0022left\u0022\u003A\u00220px\u0022,\u0022width\u0022\u003A\u0022auto\u0022\u007D,\u0022tablet\u0022\u003A\u007B\u0022top\u0022\u003A\u00220px\u0022,\u0022left\u0022\u003A\u00220px\u0022,\u0022width\u0022\u003A\u0022auto\u0022\u007D,\u0022desktop\u0022\u003A\u007B\u0022top\u0022\u003A\u00220px\u0022,\u0022left\u0022\u003A\u00220px\u0022,\u0022width\u0022\u003A\u0022auto\u0022\u007D\u007D\u007D,\u0022gameUrl\u0022\u003A\u0022\\\/en\\\/game\\\/the_witcher_goodies_collection\u0022,\u0022backgroundColour\u0022\u003A\u0022rgba\u002875,22,22,1\u0029\u0022,\u0022marketingConsentType\u0022\u003A\u0022promo\u0022\u007D',

[GOG] TypeError: Cannot read properties of null (reading '1')

Docker Compose

version: "3"
services:
  free-games-claimer:
    container_name: free-games-claimer
    image: voglerr/free-games-claimer:latest
    environment:
      WIDTH: 1280
      HEIGHT: 720
      NOTIFY: discord://XXXXX
      EMAIL: XXXXX
      EG_PASSWORD: XXXXX
      EG_OTPKEY: XXXXX
      PG_PASSWORD: XXXXX
      PG_OTPKEY: XXXXX
      GOG_PASSWORD: XXXXX
    ports:
      - 5900:5900
      - 6080:6080
    volumes:
      - /home/ethan/free-games-claimer:/fgc/data

Logs

2023-02-15 17:00:16.213 started checking gog
Signed in as 'Ethan'
TypeError: Cannot read properties of null (reading '1')
    at file:///fgc/gog.js:90:58

Feature: save/load cookies instead of userDataDir

Currently the script will save userDataDir to reuse next time, this is inefficient and we cannot use it for multiple accounts.

Instead, we can save the cookies and inject the cookie into a new session. This way, we can also start a new container with cookies as env var.

It's working with no captcha when we disable headless, so I think this is the best approach so far.

Epic games error timeout

hey, can someone help me why this happens? It says he logged me in and displays the free games then after this happens:

locator.innerText: Timeout 20000ms exceeded.
=========================== logs ===========================
waiting for locator('h1 div').first()

[RFC] headless firefox works for epic-games

Just tried headless mode in firefox and had no captcha problem for epic-games:

image

Should have tried Firefox instead of Chrome earlier...
Maybe some people can confirm that it works reliably, then we can change the default to be headless and only show the browser for login. Maybe it makes sense to have a smaller docker image without the xvfb stuff if we know that login including 2FA can be handled reliably via the terminal.

Related: #2, #9, #11

check if there are new games to claim before launching browser?

Feature

Why not determine if the promotion entity is already in the library before the claim-task is executed?

I think handling this pre-work before launching the browser would greatly improve workflow efficiency (If the identity token is cached).

Description

Key: the namespace of a promotion is a unique value.

Pseudo code

def promotions_filter(self):
    # Get historical order data (10 items)
    order_history = self.explorer.game_manager.get_order_history(self._ctx_cookies)
    # Get weekly free game promotion data
    promotions = self.get_promotions()
    # Marks the in-library status of the promotion
    for promotion in promotions:
        # Check order.orderStatus == "COMPLETED" and promotion.namespace == order.namespace
        promotion.in_library = order_history.get(promotion.namespace, False)
        # Skip tasks that correspond to promotions already in the library
        self.task_queue_pending.put(promotion)

[Question] Misjudgment | This game contains mature content recommended only for ages 18+

Description

  • In my case, this week's free games are in the library.
  • The header browser starts normally and is displayed on the 《Insurmountable》 page.
  • Then, I didn't observe the next browser behavior until it timeout quit.
  • I restarted the program 3 times in the same way and all encountered the same problem, so I think it is most likely a bug.

Log screenshot

image

My opinion

  • I think this game contains mature content and is only recommended for people over 18 years old is a misjudgment.
  • I visited this page with a pure driver and no warning popped up. In other words there are no clickable (Continue) elements in the page. You can test it on this page 《Amnesia: Rebirth》.

TypeError: Cannot read properties of undefined (reading 'push')

when i run the prime script i get this error wat do i have to do to get it working?

C:\Users%username%\free-games-claimer-main> node prime-gaming
userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/107.0.5304.18 Safari/537.36
Signed in.
Number of already claimed games (total): 7
Number of free unclaimed games (Prime Gaming): 0
Number of free unclaimed games (external stores): 0
file:///C:/Users/%username%/free-games-claimer-main/prime-gaming.js:145
db.data.runs.push(run);
^

TypeError: Cannot read properties of undefined (reading 'push')
at file:///C:/Users/%username%/free-games-claimer-main/prime-gaming.js:145:16

Node.js v19.0.1

How to edit options? (to setup the NOTIFY function)

Hello, firstly thank you very much for this program. It is precisely what I have been looking for! Pardon me for asking what is likely a very simple question. I have messed with it for quite a while and properly set it up so that it runs on windows 11 using docker. By typing in the script "docker run --rm -it -p 6080:6080 -v fgc:/fgc/data --pull=always ghcr.io/vogler/free-games-claimer" on a windows cmd prompt I am able to get the program to run successfully with no issues and set it up so it does it automatically every time I turn on my PC. My question is how to edit/find the options listed in the chart under configuration/options. If I can be pointed in the right direction that should suffice, I am just VERY novice to this and don't know where to look/start. I am wanting to set up the NOTIFY function specifically but without knowing how to even find the options I have no idea how to begin. Thank you very much for helping me learn and pardon if this is a dumb question! :)

GOG Fails to Authenticate, Results in Timeout and TypeError

As GOG is now run by default in Docker, I've found that it is failing to authenticate using credentials provided via environment variables. After an unsuccessful attempt to claim the current free game, FGC opens the login form but does not submit credentials.

FGCFailGOG.mp4

Docker Compose

version: "3"
services:
  free-games-claimer:
    container_name: free-games-claimer
    image: voglerr/free-games-claimer:latest
    environment:
      WIDTH: 1280
      HEIGHT: 720
      NOTIFY: discord://XXXXX/XXXXX
      EMAIL: XXXXX
      EG_PASSWORD: XXXXX
      EG_OTPKEY: XXXXX
      PG_PASSWORD: XXXXX
      PG_OTPKEY: XXXXX
      GOG_PASSWORD: XXXXX
    ports:
      - 5900:5900
      - 6080:6080
    volumes:
      - /home/XXXXX/free-games-claimer:/fgc/data

Logs

2023-01-29 00:06:33.929 started checking gog
Signed in as ''
Current free game: CDPR Goodie Pack - https://gog.com/en/game/cdpr_goodie_pack
Unauthorized 
Unsubscribe from 'Promotions and hot deals' newsletter
locator.uncheck: Timeout 20000ms exceeded.
=========================== logs ===========================
waiting for locator('li:has-text("Promotions and hot deals") label')
============================================================
    at file:///fgc/gog.js:121:73 {
  name: 'TimeoutError'
}
file:///fgc/gog.js:125
  if (!error.message.contains('Target closed')) // e.g. when killed by Ctrl-C
                     ^
TypeError: error.message.contains is not a function
    at file:///fgc/gog.js:125:22
Node.js v19.5.0

noVNC/portal, tunnel, notifications, ARM, docker

Planning/discussion issue for the ideas that came up in #11

  • noVNC to remote-control browser for login or captcha

  • tunnel / reverse proxy for easy access from outside the local network

    @jackblk: I think implementing noVNC is nice, because if we meet captcha, we can send a notification to our device (maybe use apprise?). Then user can open noVNC to control the browser, solve the captcha & claim the game. It has password built in so it's fine to forward the port. Maybe we can use ngrok to tunnel it as well.

    @vogler: ngrok docs look like you need an API key to use it? Here are some alternatives we could try:

    Via ssh in docker: https://serveo.net

    Alternative: puppeteer-extra-plugin-portal, but unclear if it works with Playwright.

  • notifications

    apprise is in Python and I didn't find any JS bindings or an alternative project for nodejs.
    We could use it in the docker image, but it would be nicer to send notifications from the JS files.
    We could shell out from JS, but then you'd still have the setup problem for people not using the docker image. @vogler

  • GitHub actions to upload to Docker hub

  • Reduce the image size (alpine, Firefox instead of Chromium) #68

    @jackblk: As much as I want to use Alpine image, it doesn't work with Playwright due to browser binaries again (alpine uses musl instead of glibc).

  • ARM support #3

    @jackblk: Consider using Firefox? -> can fix raspberry arm 32bit issue, smaller size
    @jackblk: Playwright browser binaries only fully supports amd64 and arm64 for now. This means the docker image will not work for Raspberry <4.
    For arm 32 bit, using local built browser for armhf won't work even if we use executablePath. If you can find a way for it to work with executablePath then we can consider but I doubt it.
    @vogler: Raspberry Pi (3, 4, Zero 2): Raspbian won't work since it's 32-bit, but Raspberry Pi OS (64-bit) or Ubuntu will.

[discussion] Another headless approach

Not really an issue, just a discussion.

After reading your repo a bit, I want to ask you some questions & contribute if possible. Can you let me know if you see captcha when running in headful state (with clean IP)?

If not, there's an approach I think we can consider: run a headful browser inside Docker with headless X11 server. That way, the browser is still headful, but for us it's still headless. I can help with this if the headful does not meet captcha.

Can not login due to hcaptcha

I try to enter my credentials via browser and I get a hcaptcha trigger
But before I can login, it just reloads the hcaptcha, marking it as failed - saying "Incorrect response. Please refresh the page."
Making it impossible to login

"Unavailable" games make the script halt and quit

As per title, I'm in a region where a particular game (Epic Cheerleader Pack) isn't available so the script cannot redeem it and exit with a Timeout error. This is the error:

Current free game: Epic Cheerleader Pack
Not in library yet! Click GET.
page.click: Timeout 20000ms exceeded.
=========================== logs ===========================
waiting for selector "[data-testid="purchase-cta-button"]"
selector resolved to visible <button disabled class="css-1rcvlh3" aria-disabled="true…>…
attempting click action
waiting for element to be visible, enabled and stable
element is not enabled - waiting...

at file:///C:/Users/thekr/Downloads/Bottini/free-games-claimer-main/epic-games.js:137:18 {

name: 'TimeoutError'

[Docker] Prime Gaming TimeoutError waiting for Complete Claim button

Using the latest Docker image, FGC is now claiming Prime Gaming freebies. It seems to fail on unclaimed games from external stores; in this example, that would be Quake on the Epic Games Store. I believe the script does not properly handle if your external account (Epic) was not connected to your Prime Gaming account at the time of the attempted claim.

docker-compose.yml

version: "3"
services:
  free-games-claimer:
    container_name: free-games-claimer
    image: voglerr/free-games-claimer:latest
    ports:
      - 5900:5900
      - 6080:6080
    volumes:
      - /home/ethan/free-games-claimer:/fgc/data

Logs

2022-12-25 02:18:18.634 started checking prime-gaming
userAgent: Mozilla/5.0 (X11; Linux x86_64; rv:107.0) Gecko/20100101 Firefox/107.0
Signed in.
Number of already claimed games (total): 6
Number of free unclaimed games (Prime Gaming): 0
Number of free unclaimed games (external stores): 2
Current free game: Quake
[AggregateError: All promises were rejected] {
  [errors]: [
    page.click: Timeout 20000ms exceeded.
    =========================== logs ===========================
    waiting for locator('button:has-text("Claim now")')
      locator resolved to visible <button data-a-target="AvailableButton" class="tw-intera…>…</button>
    attempting click action
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #1
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #2
      waiting 20ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #3
      waiting 100ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #4
      waiting 100ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #5
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #6
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #7
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #8
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #9
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #10
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #11
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #12
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #13
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #14
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #15
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #16
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #17
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #18
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #19
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #20
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #21
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #22
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #23
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #24
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #25
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #26
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #27
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #28
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #29
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #30
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #31
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #32
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #33
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #34
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #35
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="ReactModal__Overlay ReactModal__Overlay--…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #36
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #37
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #38
      waiting 500ms
      waiting for element to be visible, enabled and stable
      element is visible, enabled and stable
      scrolling into view if needed
      done scrolling
      <div class="tw-flex-nowrap tw-tower tw-tower--240 tw-…>…</div> from <div class="ReactModalPortal">…</div> subtree intercepts pointer events
    retrying click action, attempt #39
      waiting 500ms
    ============================================================
        at file:///fgc/prime-gaming.js:102:29 {
      name: 'TimeoutError'
    },
    page.click: Timeout 20000ms exceeded.
    =========================== logs ===========================
    waiting for locator('button:has-text("Complete Claim")')
    ============================================================
        at file:///fgc/prime-gaming.js:102:73 {
      name: 'TimeoutError'
    }
  ]
}

Claim Free Asset Packs from the Unreal Engine Marketplace (Epic Games Store)

Each month, Epic releases a handful of asset packs for the Unreal Engine for free to all developers. These assets are made available on the Unreal Engine Marketplace, which seems to be a curated version of the Epic Games Store. There is a "Free for the Month" filter on the Unreal Engine Marketplace to find these product listings.

Here is the latest drop: Featured free Unreal Marketplace content—January 2023

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.