UNPKG

steam-user

Version:

Steam client for Individual and AnonUser Steam account types

257 lines (207 loc) 6 kB
const Crypto = require('crypto'); const OS = require('os'); const SteamID = require('steamid'); const EOSType = require('../enums/EOSType.js'); const EResult = require('../enums/EResult.js'); const FRIEND_CODE_REPLACEMENTS = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 't', 'v', 'w']; /** * If the input isn't already a SteamID object, converts it into one and returns it * @param input * @returns {SteamID} * @private */ exports.steamID = function(input) { if (!input) { return; } if (typeof input !== 'string') { let keys = Object.keys(input); if (['universe', 'type', 'instance', 'accountid'].every(key => keys.includes(key))) { return input; // Looks like it's already a SteamID } input = input.toString(); } return new SteamID(input); }; /** * @param {SteamID} steamID * @returns {string} * @private */ exports.createFriendCode = function(steamID) { let acctIdHex = steamID.accountid.toString(16); let friendCode = ''; for (let i = 0; i < acctIdHex.length; i++) { let char = parseInt(acctIdHex[i], 16); friendCode += FRIEND_CODE_REPLACEMENTS[char]; } let dashPos = Math.floor(friendCode.length / 2); return friendCode.substring(0, dashPos) + '-' + friendCode.substring(dashPos); }; /** * @param {string} friendCode * @returns {SteamID} * @private */ exports.parseFriendCode = function(friendCode) { friendCode = friendCode.replace(/-/g, ''); let acctIdHex = ''; for (let i = 0; i < friendCode.length; i++) { let char = friendCode[i]; acctIdHex += FRIEND_CODE_REPLACEMENTS.indexOf(char).toString(16); } return new SteamID(`[U:1:${parseInt(acctIdHex, 16)}]`); }; /** * Get an machine ID for internal use (not sent to Steam) * @returns {string} * @private */ exports.getInternalMachineID = function() { // Build our machine ID off of hostname, memory, and CPU data let cpus = OS.cpus().map(function(cpu) { return cpu.model; }); cpus.sort(); let id = OS.hostname() + OS.totalmem() + cpus.join(''); let hash = Crypto.createHash('md5'); hash.update(id); return hash.digest('hex'); }; /** * Get an Error object for a particular EResult * @param {int|EResult|object} eresult - Either an EResult value, or an object that contains an eresult property. If undefined or is an object without an eresult property, will assume "Fail". * @returns {null|Error} * @private */ exports.eresultError = function(eresult) { if (typeof eresult == 'undefined') { eresult = EResult.Fail; } else if (typeof eresult == 'object') { eresult = eresult.eresult || EResult.Fail; } if (eresult == EResult.OK) { // no error return null; } let err = new Error(EResult[eresult] || ('Error ' + eresult)); err.eresult = eresult; return err; }; /** * @return {EOSType} * @private */ exports.getOsType = function() { switch (OS.platform()) { case 'darwin': let match = OS.release().match(/Darwin Kernel Version (\d+)\.(\d+)\.(\d+)/); if (!match) { return EOSType.MacOSUnknown; } if (match[1] == 10 && match[2] == 0 && match[3] == 0) { return EOSType.MacOS106; // Snow Leopard } if (match[1] == 11 && match[2] == 3) { return EOSType.MacOS107; // Lion } if (match[1] == 12 && match[2] == 2) { return EOSType.MacOS108; // Mountain Lion } if (match[1] == 13 && match[2] == 0) { return EOSType.MacOS109; // Mavericks } if (match[1] == 14 && match[2] == 0) { return EOSType.MacOS1010; // Yosemite } return EOSType.MacOSUnknown; case 'win32': // http://prajwaldesai.com/windows-operating-system-version-numbers/ let verParts = OS.release().split('.'); if (verParts.length < 3) { return EOSType.WinUnknown; } if (verParts[0] == 3) { return EOSType.Win311; // yeah right } if (verParts[0] == 4 && parseInt(verParts[1], 10) <= 3) { return EOSType.Win95; } if (verParts[0] == 4 && verParts[1] == 10) { return EOSType.Win98; } if (verParts[0] == 4 && verParts[1] == 90) { return EOSType.WinME; } if (verParts[0] == 5 && verParts[1] == '00' && verParts[2] == 1515) { return EOSType.WinNT; } if (verParts[0] == 5 && parseInt(verParts[1], 10) < 1) { return EOSType.Win200; } if (verParts[0] == 5 && verParts[1] == 1) { return EOSType.WinXP; } if (verParts[0] == 5 && verParts[1] == 2) { return EOSType.Win2003; } if (verParts[0] == 6 && verParts[1] == 0 && verParts[2] == 6001) { return EOSType.Win2008; } if (verParts[0] == 6 && verParts[1] == 0) { return EOSType.WinVista; } if (verParts[0] == 6 && verParts[1] == 1) { return EOSType.Win7; } if (verParts[0] == 6 && verParts[1] == 2) { return EOSType.Win8; } if (verParts[0] == 6 && verParts[1] == 3) { return EOSType.Win81; } if (verParts[0] == 10) { return EOSType.Win10; } return EOSType.WinUnknown; default: return EOSType.LinuxUnknown; } }; /** * @param {object} arr * @returns {Array} * @private */ exports.fixVdfArray = function(arr) { arr.length = Object.keys(arr).length; return Array.prototype.slice.call(arr); }; /** * @param {number} timeoutMilliseconds * @param {EventEmitter} emitter * @param {string} event * @param {function} handler * @private */ exports.onceTimeout = function(timeoutMilliseconds, emitter, event, handler) { let timeout; let internalHandler = function() { clearTimeout(timeout); handler.apply(emitter, [null].concat(Array.prototype.slice.call(arguments))); }; timeout = setTimeout(() => { emitter.removeListener(event, internalHandler); handler.call(emitter, new Error('Request timed out')); }, timeoutMilliseconds); emitter.once(event, internalHandler); }; exports.decodeJwt = function(jwt) { let parts = jwt.split('.'); if (parts.length != 3) { throw new Error('Invalid JWT'); } let standardBase64 = parts[1].replace(/-/g, '+') .replace(/_/g, '/'); return JSON.parse(Buffer.from(standardBase64, 'base64').toString('utf8')); };