First commit.

This commit is contained in:
Matt Low 2021-11-28 12:09:39 -07:00
commit 21e8c5d645
5 changed files with 151 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
**/.env*
**/node_modules/*

33
README.md Normal file
View File

@ -0,0 +1,33 @@
# steamcmd-app-update
Outputs one `app_update <app-id> [-validate]` line per game in your Steam library.
A useful tool if you intend to automate the fetching of your entire
steam library :)
# Usage
Configuration
```sh
## .env
# Steam API key.
export STEAM_API_KEY=
# The profile ID to fetch the list of owned games of.
export STEAM_PROFILE_ID=
# Comma separated list of games to skip
export SKIP_GAMES='Dota 2 Test, Metro Exodus, 1240440'
# Whether to force game file validation by adding -validate
# Any value = true, unset/empty = false
export FORCE_VALIDATE=
```
Execution
```sh
source .env && node ./index.js
# Or integrate this into your library updating docker container!
```

53
index.js Executable file
View File

@ -0,0 +1,53 @@
#! /usr/bin/env node
const STEAM_API_KEY = process.env.STEAM_API_KEY;
if (!STEAM_API_KEY) {
console.error(
"The STEAM_API_KEY environment variale should contain your Steam API key."
);
console.error("See: https://steamcommunity.com/dev/apikey");
process.exit(1);
}
const steam = new (require("steamapi"))(STEAM_API_KEY);
const STEAM_PROFILE_ID = process.env.STEAM_PROFILE_ID;
if (!STEAM_PROFILE_ID) {
console.error("The STEAM_PROFILE_ID environment variable is required.");
process.exit(1);
}
const skipGames = [];
if (process.env.SKIP_GAMES) {
process.env.SKIP_GAMES.split(",")
.map((game) => game.trim())
.forEach((game) => {
skipGames.push(game);
});
}
function shouldSkip(gameId, gameTitle) {
return (
// We could be comparing strings against numbers here, that's fine
skipGames.find((game) => game == gameId || game == gameTitle) !== undefined
);
}
const shouldValidate = !!process.env.FORCE_VALIDATE;
steam.getUserOwnedGames(STEAM_PROFILE_ID).then((games) =>
games
.filter((game) => !shouldSkip(game.appID, game.name))
.sort((a, b) => a.appID - b.appID)
.forEach((game) => {
console.log(
`// ${game.name} - https://store.steampowered.com/app/${game.appID}`
);
console.log(
`app_update ${game.appID}${shouldValidate ? " -validate" : ""}`
);
})
);

43
package-lock.json generated Normal file
View File

@ -0,0 +1,43 @@
{
"name": "steamcmd-app-update",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"steamapi": "^2.1.2"
}
},
"node_modules/steamapi": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/steamapi/-/steamapi-2.2.0.tgz",
"integrity": "sha512-2UWklLzYQruuUC0a5AUgll1dU91/CWgiAhm/7y+rqc43kbBWereGTtmwo8wr6imjC64iV5893KChXghW0zK8Gg==",
"dependencies": {
"steamid": "^2.0.0"
}
},
"node_modules/steamid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/steamid/-/steamid-2.0.0.tgz",
"integrity": "sha512-+BFJMbo+IxzyfovLR37E7APkaNfmrL3S+88T7wTMRHnQ6LBhzEawPnjfWNKM9eUL/dH45j+7vhSX4WaGXoa4/Q==",
"engines": {
"node": ">=12.0.0"
}
}
},
"dependencies": {
"steamapi": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/steamapi/-/steamapi-2.2.0.tgz",
"integrity": "sha512-2UWklLzYQruuUC0a5AUgll1dU91/CWgiAhm/7y+rqc43kbBWereGTtmwo8wr6imjC64iV5893KChXghW0zK8Gg==",
"requires": {
"steamid": "^2.0.0"
}
},
"steamid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/steamid/-/steamid-2.0.0.tgz",
"integrity": "sha512-+BFJMbo+IxzyfovLR37E7APkaNfmrL3S+88T7wTMRHnQ6LBhzEawPnjfWNKM9eUL/dH45j+7vhSX4WaGXoa4/Q=="
}
}
}

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"dependencies": {
"steamapi": "^2.1.2"
},
"name": "steamcmd-app-update",
"description": "Outputs one `app_update <app-id> [-validate]` line per game in your Steam library.",
"version": "1.0.0",
"main": "index.js",
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"steam",
"steamcmd",
"app_update"
],
"author": "Matt Low <matt@mlow.ca>",
"license": "MIT"
}