Jump to content
McKay Development

App token & depot key dumper


Revadike
 Share

Recommended Posts

global._mckay_statistics_opt_out = true; // opting out any statistical collection program

// modules being used
const SteamUser = require("steam-user");
const path = require("path");
const fs = require("fs");

const config = require(path.join(__dirname, "config.js"));

process.on('unhandledRejection', (reason, p) => {
    console.error(reason, 'Unhandled Rejection at Promise', p);
}).on('uncaughtException', err => {
    console.error(err, 'Uncaught Exception thrown');
});
const appTokens = fs.existsSync(path.join(__dirname, "apptokens.json")) ? JSON.parse(fs.readFileSync(path.join(__dirname, "apptokens.json"), "utf8").toString() || "{}") : {};
const depotKeys = fs.existsSync(path.join(__dirname, "depotkeys.json")) ? JSON.parse(fs.readFileSync(path.join(__dirname, "depotkeys.json"), "utf8").toString() || "{}") : {};
const running = {
    apptokens: false,
    depotkeys: false,
};

const user = new SteamUser({
    enablePicsCache: true
});

user.logOn(config.loginAnonymous ? undefined : require(path.join(__dirname, "login.js"))); // logging in using your username and password, more info about this function: https://github.com/DoctorMcKay/node-steam-user/blob/master/components/logon.js#L9
user.on("loggedOn", () => {
    console.log("Logged onto Steam as " + user.steamID.getSteamID64());

    const chunksize = 10000; // seems best chunk size
    const idList = [];
    for (let i = chunksize; i < 1000000; i += chunksize) {
        const idSubList = [];
        for (let j = i - chunksize; j < i; j++) {
            idSubList.push(j);
        }
        idList.push(idSubList);
    }

    // doing this for all appids or packages just hangs forever
    running.apptokens = true;
    getTokens();

    function getTokens() {
        const idSubList = idList.shift();
        user.getProductAccessToken(idSubList.filter(id => !appTokens.hasOwnProperty(id)), [], (apps, packageTokens, appDeniedTokens) => {
            console.log("Tokens denied for " + appDeniedTokens.length + " apps of range " + idSubList[0] + "-" + idSubList[idSubList.length - 1]);

            for (let appid in apps) {
                if (apps.hasOwnProperty(appid)) {
                    const token = apps[appid].toString();
                    appTokens[appid] = token;

                    if (token !== "0") { // otherwise it'd be too spammy
                        console.log("App " + appid + ": " + apps[appid].toString());
                    }
                }
            }

            if (idList.length > 0) {
                getTokens();
            } else {
                fs.writeFileSync(path.join(__dirname, "apptokens.json"), JSON.stringify(appTokens, null, 4), "utf8");
                console.log("Dumped product access tokens to apptokens.json!");

                running.apptokens = false;
                if (!running.apptokens && !running.depotkeys) {
                    console.log("Logging off of Steam");
                    user.logOff();
                }
            }
        });
    }
});

user.on("appOwnershipCached", getDepotKeys);

function getDepotKeys() {
    console.log("App ownership cached. Requesting appinfos...");
    let logger = setInterval(console.log, 6000, "Still requesting appinfos...");
    running.depotkeys = true;

    user.getProductInfo(user.getOwnedApps().map(appid => parseInt(appid, 10)), [], true, (apps, packages, unknownApps) => {
        clearInterval(logger);
        console.log("Got appinfos of " + Object.keys(apps).length + " apps");

        if (unknownApps.length > 0) {
            console.log("Found " + unknownApps.length + " unknown apps");
        }

        const depots = {};
        for (let appid in apps) {
            if (!apps.hasOwnProperty(appid) || !apps[appid].hasOwnProperty(`appinfo`) || !apps[appid].appinfo.hasOwnProperty(`depots`)) { // skip if no depot info
                continue;
            }

            Object.keys(apps[appid].appinfo.depots).filter(id => !isNaN(id)).forEach(depotid => depots[depotid] = appid);
        }

        console.log("Requesting depot decryption keys of " + Object.keys(depots).length + " depots");

        for (let depotid in depots) {
            if (depotKeys.hasOwnProperty(depotid)) {
                depots[depotid] = true;
                continue;
            }

            const appid = depots[depotid];
            try {
                user.getDepotDecryptionKey(parseInt(appid, 10), parseInt(depotid, 10), (error, key) => {
                    if (error) {
                        console.log("Depot " + depotid + ": " + error.message);
                    } else {
                        depotKeys[depotid] = key.toString("base64");
                        console.log("Depot " + depotid + ": " + depotKeys[depotid]);
                    }

                    depots[depotid] = true;
                    if (Object.keys(depots).length === Object.values(depots).filter(v => v === true).length) {
                        fs.writeFileSync(path.join(__dirname, "depotkeys.json"), JSON.stringify(depotKeys, null, 4), "utf8");
                        console.log("Dumped depot keys to depotkeys.json!");

                        running.depotkeys = false;
                        if (!running.apptokens && !running.depotkeys) {
                            console.log("Logging off of Steam");
                            user.logOff();
                        }
                    }
                });
            } catch (error) {
                console.log(error);
                depots[depotid] = true;
                if (Object.keys(depots).length === Object.values(depots).filter(v => v === true).length) {
                    fs.writeFileSync(path.join(__dirname, "depotkeys.json"), JSON.stringify(depotKeys, null, 4), "utf8");
                    console.log("Dumped depot keys to depotkeys.json!");

                    running.depotkeys = false;
                    if (!running.apptokens && !running.depotkeys) {
                        console.log("Logging off of Steam");
                        user.logOff();
                    }
                }
            }
        }
    });
}

The app token dumping works just fine, but the depot key dumping thows RangeError's left and right:

RangeError: Index out of range
    at checkOffset (buffer.js:851:11)
    at Buffer.readUInt32LE (buffer.js:913:5)
    at node_modules\steam-user\components\cdn.js:80:58
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:439:3)

At buffer.js:851.

Any idea why? And how we can fix that?

Link to comment
Share on other sites

One of the files in your local cache appears to be corrupted. I'll push a fix to handle this case.

Will disabling the storage, like below, also fix the problem?

    user.storage.on("save", (filename, contents, callback) => callback());
    user.storage.on("read", (filename, callback) => callback());
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...