From 617229f65974f84f5509d849e9b1a7f578dd7d26 Mon Sep 17 00:00:00 2001 From: 4n4n4s Date: Fri, 10 Nov 2023 16:43:47 +0000 Subject: [PATCH] * Format and fix sonar issues --- README.md | 2 +- config.js | 4 +-- steam-games.js | 72 ++++++++++++++++++++++---------------------------- 3 files changed, 35 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index f339f7c..371617a 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ Available options/variables and their default values: | STEAM_PASSWORD | | Steam password for login. Overrides PASSWORD. | | STEAM_JSON | 0 | Claims steam games from json. STEAM_JSON_URL can be defined. | | STEAM_JSON_URL | [steam-games.json](https://raw.githubusercontent.com/vogler/free-games-claimer/main/steam-games.json) | A list of steam urls in json format to claim the games. | -| STEAM_GAMERPOWER | 1 | Claims steam games using [gamerpower api](https://www.gamerpower.com/api/giveaways?platform=steam&type=game). | +| STEAM_GAMERPOWER | 0 | Claims steam games using [gamerpower api](https://www.gamerpower.com/api/giveaways?platform=steam&type=game). | See `config.js` for all options. diff --git a/config.js b/config.js index 4ffafb4..92c0675 100644 --- a/config.js +++ b/config.js @@ -51,7 +51,7 @@ export const cfg = { steam_username: process.env.STEAM_USERNAME, steam_password: process.env.STEAM_PASSWORD || process.env.PASSWORD, - steam_json: false || process.env.STEAM_JSON == '1', + steam_json: process.env.STEAM_JSON == '1', steam_json_url: process.env.STEAM_JSON_URL || 'https://raw.githubusercontent.com/vogler/free-games-claimer/main/steam-games.json', - steam_gamerpower: true || process.env.STEAM_GAMERPOWER == '1', + steam_gamerpower: process.env.STEAM_GAMERPOWER == '1', }; diff --git a/steam-games.js b/steam-games.js index ba68f8c..fef893f 100644 --- a/steam-games.js +++ b/steam-games.js @@ -3,7 +3,6 @@ import { resolve, jsonDb, datetime, prompt, stealth, notify, html_game_list, han import path from 'path'; import { existsSync, writeFileSync } from 'fs'; import { cfg } from './config.js'; -import { config } from 'dotenv'; const screenshot = (...a) => resolve(cfg.dir.screenshots, 'steam', ...a); @@ -22,11 +21,10 @@ const context = await firefox.launchPersistentContext(cfg.dir.browser, { // channel: 'chrome', // https://playwright.dev/docs/browsers#google-chrome--microsoft-edge headless: false, viewport: { width: cfg.width, height: cfg.height }, - userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36', // see replace of Headless in util.newStealthContext. TODO Windows UA enough to avoid 'device not supported'? update if browser is updated? - // userAgent for firefox: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0 + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36', locale: "en-US", // ignore OS locale to be sure to have english text for locators - recordVideo: cfg.record ? { dir: 'data/record/', size: { width: cfg.width, height: cfg.height } } : undefined, // will record a .webm video for each page navigated; without size, video would be scaled down to fit 800x800 - recordHar: cfg.record ? { path: `data/record/eg-${datetime()}.har` } : undefined, // will record a HAR file with network requests and responses; can be imported in Chrome devtools + recordVideo: cfg.record ? { dir: 'data/record/', size: { width: cfg.width, height: cfg.height } } : undefined, + recordHar: cfg.record ? { path: `data/record/eg-${datetime()}.har` } : undefined, args: [ // https://peter.sh/experiments/chromium-command-line-switches // don't want to see bubble 'Restore pages? Chrome didn't shut down correctly.' // '--restore-last-session', // does not apply for crash/killed @@ -47,16 +45,16 @@ const page = context.pages().length ? context.pages()[0] : await context.newPage const notify_games = []; let user; -async function doLogin(){ +async function doLogin() { await page.goto(URL_LOGIN, { waitUntil: 'domcontentloaded' }); // default 'load' takes forever - if (cfg.steam_username && cfg.steam_password){ + if (cfg.steam_username && cfg.steam_password) { console.info('Using username and password from environment.'); } else { console.info('Press ESC to skip the prompts if you want to login in the browser (not possible in headless mode).'); } - const username = cfg.steam_username || await prompt({message: 'Enter username'}); - const password = username && (cfg.steam_password || await prompt({type: 'password', message: 'Enter password'})); + const username = cfg.steam_username || await prompt({ message: 'Enter username' }); + const password = username && (cfg.steam_password || await prompt({ type: 'password', message: 'Enter password' })); if (username && password) { await page.type('input[type=text]:visible', username); await page.type('input[type=password]:visible', password); @@ -66,10 +64,8 @@ async function doLogin(){ } const auth = await page.getByText('You have a mobile authenticator protecting this account.').first(); let isFirstCheck = true; - while (await auth.isVisible()) - { - if (isFirstCheck) - { + while (await auth.isVisible()) { + if (isFirstCheck) { console.log("Steam requires confirmation from authenticator"); notify(`Steam requires confirmation from authenticator`); isFirstCheck = false; @@ -78,9 +74,9 @@ async function doLogin(){ } } -async function claim(){ +async function claim() { await page.goto(URL_CLAIM, { waitUntil: 'domcontentloaded' }); // default 'load' takes forever - await context.addCookies([{name: 'cookieSettings', value: '%7B%22version%22%3A1%2C%22preference_state%22%3A2%2C%22content_customization%22%3Anull%2C%22valve_analytics%22%3Anull%2C%22third_party_analytics%22%3Anull%2C%22third_party_content%22%3Anull%2C%22utm_enabled%22%3Atrue%7D', domain: 'store.steampowered.com', path: '/'}]); // Decline all cookies to get rid of banner to save space on screen. + await context.addCookies([{ name: 'cookieSettings', value: '%7B%22version%22%3A1%2C%22preference_state%22%3A2%2C%22content_customization%22%3Anull%2C%22valve_analytics%22%3Anull%2C%22third_party_analytics%22%3Anull%2C%22third_party_content%22%3Anull%2C%22utm_enabled%22%3Atrue%7D', domain: 'store.steampowered.com', path: '/' }]); // Decline all cookies to get rid of banner to save space on screen. const signIn = page.locator('a:has-text("Sign In")').first(); while (await signIn.isVisible()) { @@ -101,18 +97,16 @@ async function claim(){ } } -async function claimJson(){ +async function claimJson() { console.log("Claiming JSON"); const response = await page.goto(cfg.steam_json_url); const items = await response.json(); for (const item of items) { - if (!await isClaimedUrl(item.url)){ + if (!await isClaimedUrl(item.url)) { console.log(item); - if (item.hasOwnProperty("startDate")) - { + if (item.hasOwnProperty("startDate")) { const date = Date.parse(item.startDate); - if (date >= Date.now()) - { + if (date >= Date.now()) { console.log("game not available yet " + new Date(date)); return; } @@ -122,7 +116,7 @@ async function claimJson(){ } } -async function claimGamerpower(){ +async function claimGamerpower() { console.log("Claiming Gamerpower"); const response = await page.goto("https://www.gamerpower.com/api/giveaways?platform=steam&type=game"); const items = await response.json(); @@ -131,8 +125,8 @@ async function claimGamerpower(){ await page.goto(item.open_giveaway_url, { waitUntil: 'domcontentloaded' }); const url = page.url(); - if (url.includes("https://store.steampowered.com/app")){ - if (!await isClaimedUrl(url)){ + if (url.includes("https://store.steampowered.com/app")) { + if (!await isClaimedUrl(url)) { await claimGame(url); } } @@ -142,11 +136,11 @@ async function claimGamerpower(){ } } -async function claimGame(url){ - await page.goto(url, { waitUntil: 'domcontentloaded'}); +async function claimGame(url) { + await page.goto(url, { waitUntil: 'domcontentloaded' }); const title = await page.locator('#appHubAppName').first().innerText(); const pattern = "/app/"; - let game_id = page.url().substring(page.url().indexOf(pattern)+pattern.length); + let game_id = page.url().substring(page.url().indexOf(pattern) + pattern.length); game_id = game_id.substring(0, game_id.indexOf("/")); db.data[user][game_id] ||= { title, time: datetime(), url: page.url() }; // this will be set on the initial run only! @@ -154,13 +148,11 @@ async function claimGame(url){ notify_games.push(notify_game); // status is updated below const alreadyOwned = await page.locator('.game_area_already_owned').first(); - if (await alreadyOwned.isVisible()) - { + if (await alreadyOwned.isVisible()) { console.log("Game " + title + " already in library"); db.data[user][game_id].status ||= 'existed'; // does not overwrite claimed or failed } - else - { + else { await page.locator(('#freeGameBtn')).click(); console.log("purchased"); db.data[user][game_id].status = 'claimed'; @@ -172,15 +164,15 @@ async function claimGame(url){ } async function isClaimedUrl(url) { - try { - const pattern = "/app/"; - let game_id = url.substring(url.indexOf(pattern)+pattern.length); - game_id = game_id.substring(0, game_id.indexOf("/")); - var status = db.data[user][game_id]["status"]; - return status === "existed" || status === "claimed"; - } catch (error) { - return false; - } + try { + const pattern = "/app/"; + let game_id = url.substring(url.indexOf(pattern) + pattern.length); + game_id = game_id.substring(0, game_id.indexOf("/")); + const status = db.data[user][game_id]["status"]; + return status === "existed" || status === "claimed"; + } catch (error) { + return false; + } } try {