UNPKG

steam-user

Version:

Steam client for Individual and AnonUser Steam account types

264 lines (218 loc) 8.74 kB
const BinaryKVParser = require('binarykvparser'); const StdLib = require('@doctormckay/stdlib'); const Helpers = require('./helpers.js'); const EMsg = require('../enums/EMsg.js'); const EResult = require('../enums/EResult.js'); const SteamUserBase = require('./00-base.js'); const SteamUserLogon = require('./09-logon.js'); class SteamUserAccount extends SteamUserLogon { requestValidationEmail(callback) { return StdLib.Promises.timeoutCallbackPromise(10000, null, callback, true, (resolve, reject) => { let body = Buffer.alloc(1, 0x0); // pre-fills with 0x0 this._send(EMsg.ClientRequestValidationMail, body, (response) => { let err = Helpers.eresultError(response.readUint32()); err ? reject(err) : resolve(); }); }); } getSteamGuardDetails(callback) { let callbackArgs = [ 'isSteamGuardEnabled', 'timestampSteamGuardEnabled', 'timestampMachineSteamGuardEnabled', 'canTrade', 'timestampTwoFactorEnabled', 'isPhoneVerified' ]; return StdLib.Promises.timeoutCallbackPromise(10000, callbackArgs, callback, (resolve, reject) => { this._sendUnified('Credentials.GetSteamGuardDetails#1', {}, (body) => { let res = {}; res.canTrade = true; let hasHadTwoFactorForWeek = (body.is_twofactor_enabled && body.timestamp_twofactor_enabled && Math.floor(Date.now() / 1000) - body.timestamp_twofactor_enabled >= (60 * 60 * 24 * 7)); if (!body.is_steamguard_enabled) { res.canTrade = false; // SG is not enabled } else if (!body.timestamp_steamguard_enabled || Math.floor(Date.now() / 1000) - body.timestamp_steamguard_enabled < (60 * 60 * 24 * 15)) { res.canTrade = false; // SG has not been enabled for 15 days } else if ( !hasHadTwoFactorForWeek && ( !body.session_data || !body.session_data[0] || !body.session_data[0].timestamp_machine_steamguard_enabled || Math.floor(Date.now() / 1000) - body.session_data[0].timestamp_machine_steamguard_enabled < (60 * 60 * 24 * 7) ) ) { res.canTrade = false; // Haven't had 2FA for 7 days, and this machine's auth is less than 7 days old } res.isSteamGuardEnabled = !!body.is_steamguard_enabled; res.timestampSteamGuardEnabled = body.timestamp_steamguard_enabled ? new Date(body.timestamp_steamguard_enabled * 1000) : null; res.timestampMachineSteamGuardEnabled = body.session_data && body.session_data[0] && body.session_data[0].timestamp_machine_steamguard_enabled ? new Date(body.session_data[0].timestamp_machine_steamguard_enabled * 1000) : null; res.isTwoFactorEnabled = !!body.is_twofactor_enabled; res.timestampTwoFactorEnabled = body.timestamp_twofactor_enabled ? new Date(body.timestamp_twofactor_enabled * 1000) : null; res.isPhoneVerified = !!body.is_phone_verified; resolve(res); }); }); } getCredentialChangeTimes(callback) { let callbackArgs = [ 'timestampLastPasswordChange', 'timestampLastPasswordReset', 'timestampLastEmailChange' ]; return StdLib.Promises.timeoutCallbackPromise(10000, callbackArgs, callback, (resolve, reject) => { this._sendUnified('Credentials.GetCredentialChangeTimeDetails#1', {}, (body) => { resolve({ timestampLastPasswordChange: body.timestamp_last_password_change ? new Date(body.timestamp_last_password_change * 1000) : null, timestampLastPasswordReset: body.timestamp_last_password_reset ? new Date(body.timestamp_last_password_reset * 1000) : null, timestampLastEmailChange: body.timestamp_last_email_change ? new Date(body.timestamp_last_email_change * 1000) : null }); }); }); } getAuthSecret(callback) { return StdLib.Promises.timeoutCallbackPromise(10000, ['secretID', 'key'], callback, (resolve, reject) => { this._sendUnified('Credentials.GetAccountAuthSecret#1', {}, (body) => { resolve({ secretID: body.secret_id, key: body.secret }); }); }); } /** * Get your account's profile privacy settings. * @param {function} [callback] * @returns {Promise<{privacy_state: int, privacy_state_inventory: int, privacy_state_gifts: int, privacy_state_ownedgames: int, privacy_state_playtime: int, privacy_state_friendslist: int}>} */ getPrivacySettings(callback) { return StdLib.Promises.timeoutCallbackPromise(10000, null, callback, (resolve, reject) => { this._sendUnified('Player.GetPrivacySettings#1', {}, (body, hdr) => { let err = Helpers.eresultError(hdr.proto); if (err) { return reject(err); } resolve(body.privacy_settings); }); }); } // Honestly not sure what this is for, but it works. /*getStreamingEncryptionKey(callback) { this._send(EMsg.ClientUnlockStreaming, {}, function(body) { if (body.eresult != EResult.OK) { callback(Helpers.eresultError(body.eresult)); return; } callback(null, body.encryption_key); }); }*/ } SteamUserBase.prototype._handlerManager.add(EMsg.ClientAccountInfo, function(body) { // Steam appears to send this twice on logon. Let's collapse it down to one event. let info = { name: body.persona_name, country: body.ip_country, authedMachines: body.count_authed_computers, flags: body.account_flags, facebookID: body.facebook_id ? body.facebook_id.toString() : null, facebookName: body.facebook_name }; if (this.accountInfo) { // Check if everything is identical let anythingDifferent = false; for (let i in this.accountInfo) { if (Object.hasOwnProperty.call(this.accountInfo, i) && Object.hasOwnProperty.call(info, i) && this.accountInfo[i] != info[i]) { anythingDifferent = true; break; } } if (!anythingDifferent) { return; } } this.emit('accountInfo', info.name, info.country, info.authedMachines, info.flags, info.facebookID, info.facebookName); this.accountInfo = info; }); SteamUserBase.prototype._handlerManager.add(EMsg.ClientEmailAddrInfo, function(body) { this.emit('emailInfo', body.email_address, body.email_is_validated); this.emailInfo = { address: body.email_address, validated: body.email_is_validated }; }); SteamUserBase.prototype._handlerManager.add(EMsg.ClientIsLimitedAccount, function(body) { this.emit('accountLimitations', body.bis_limited_account, body.bis_community_banned, body.bis_locked_account, body.bis_limited_account_allowed_to_invite_friends); this.limitations = { limited: body.bis_limited_account, communityBanned: body.bis_community_banned, locked: body.bis_locked_account, canInviteFriends: body.bis_limited_account_allowed_to_invite_friends }; }); SteamUserBase.prototype._handlerManager.add(EMsg.ClientVACBanStatus, function(body) { let appids = [], ranges = []; let numBans = body.readUint32(); let rangeStart, rangeEnd, j; for (let i = 0; i < numBans; i++) { rangeStart = body.readUint32(); rangeEnd = body.readUint32(); body.skip(4); // 4-byte unknown "0" value if (rangeEnd < rangeStart) { j = rangeEnd; rangeEnd = rangeStart; rangeStart = j; } ranges.push([rangeStart, rangeEnd]); for (j = rangeStart; j <= rangeEnd; j++) { appids.push(j); } } this.emit('vacBans', numBans, appids, ranges); this.vac = {numBans, appids, ranges}; }); SteamUserBase.prototype._handlerManager.add(EMsg.ClientWalletInfoUpdate, function(body) { if (this.wallet && body.has_wallet == this.wallet.hasWallet && body.currency == this.wallet.currency && body.balance / 100 == this.wallet.balance) { return; // nothing changed } this.emit('wallet', body.has_wallet, body.currency, body.balance / 100); this.wallet = { hasWallet: body.has_wallet, currency: body.currency, balance: body.balance / 100 }; }); SteamUserBase.prototype._handlerManager.add(EMsg.ClientVanityURLChangedNotification, function(body) { this.emit('vanityURL', body.vanity_url); this.vanityURL = body.vanity_url; }); SteamUserBase.prototype._handlerManager.add(EMsg.ClientUpdateGuestPassesList, function(body) { let eresult = body.readUint32(); if (eresult != EResult.OK) { return; } let countToGive = body.readUint32(); let countToRedeem = body.readUint32(); for (let i = 0; i < countToGive; i++) { BinaryKVParser.parse(body); // throw it away, I don't think this should be possible } let gifts = [], gift, key; for (let i = 0; i < countToRedeem; i++) { gift = BinaryKVParser.parse(body).MessageObject; for (key in gift) { if (!Object.hasOwnProperty.call(gift, key)) { continue; } if (key == 'gid') { gift[key] = gift[key].toString(); } if (key.match(/^Time/)) { gift[key] = gift[key] ? new Date(gift[key] * 1000) : null; } } gifts.push(gift); } if (this.gifts && this.gifts.length == gifts.length) { return; // nothing changed } this.emit('gifts', gifts); this.gifts = gifts; }); module.exports = SteamUserAccount;