diff --git a/components/00-base.js b/components/00-base.js index fbcc46b4..0690c12a 100644 --- a/components/00-base.js +++ b/components/00-base.js @@ -8,6 +8,11 @@ const HandlerManager = require('./classes/HandlerManager.js'); * @property {number} lastTimeout */ +// Important backoffs will be logged to debug rather than debug-verbose +const IMPORTANT_BACKOFFS = [ + 'logOn' +]; + /** * I admit, this is a pretty unorthodox pattern, but this is the only way I've found to define a class across multiple * files while also making sure that IDE intellisense can figure out which methods belong to the final class. @@ -19,23 +24,29 @@ class SteamUserBase extends EventEmitter { _exponentialBackoffs = {}; /** + * @param {boolean} [isConnecting=false] * @protected */ - _resetAllExponentialBackoffs() { + _resetAllExponentialBackoffs(isConnecting) { for (let i in this._exponentialBackoffs) { - this._resetExponentialBackoff(i); + // Don't clear logOn's backoff timer if we're currently connecting + this._resetExponentialBackoff(i, isConnecting && i == 'logOn'); } } /** * @param {string} backoffName + * @param {boolean} [dontClearBackoffTime=false] * @protected */ - _resetExponentialBackoff(backoffName) { + _resetExponentialBackoff(backoffName, dontClearBackoffTime) { if (this._exponentialBackoffs[backoffName]) { - this.emit('debug-verbose', `[EBO] Resetting exponential backoff "${backoffName}"`); + this.emit('debug-verbose', `[EBO] ${dontClearBackoffTime ? 'Soft-resetting' : 'Resetting'} exponential backoff "${backoffName}"`); clearTimeout(this._exponentialBackoffs[backoffName].timeout); - delete this._exponentialBackoffs[backoffName]; + + if (!dontClearBackoffTime) { + delete this._exponentialBackoffs[backoffName]; + } } } @@ -55,7 +66,8 @@ class SteamUserBase extends EventEmitter { timeout = Math.max(timeout, minimumTimeout); timeout = Math.min(timeout, maximumTimeout); - this.emit('debug-verbose', `[EBO] Queueing exponential backoff "${backoffName}" with timeout ${timeout}`); + let isImportant = IMPORTANT_BACKOFFS.includes(backoffName); + this.emit(isImportant ? 'debug' : 'debug-verbose', `[EBO] Queueing exponential backoff "${backoffName}" with timeout ${timeout}`); this._exponentialBackoffs[backoffName] = { lastTimeout: timeout, timeout: setTimeout(resolve, timeout) diff --git a/components/02-connection.js b/components/02-connection.js index 223e43c5..76520fbd 100644 --- a/components/02-connection.js +++ b/components/02-connection.js @@ -58,7 +58,7 @@ class SteamUserConnection extends SteamUserEnums { this._connecting = false; this._loggingOff = false; - this._cancelReconnectTimers(); + this._cancelReconnectTimers(true); clearInterval(this._heartbeatInterval); this._connectionClosed = true; @@ -68,9 +68,8 @@ class SteamUserConnection extends SteamUserEnums { this._clearChangelistUpdateTimer(); } - _cancelReconnectTimers() { - clearTimeout(this._logonTimeout); - clearTimeout(this._logonMsgTimeout); + _cancelReconnectTimers(dontClearBackoffTime) { + this._resetExponentialBackoff('logOn', dontClearBackoffTime); clearTimeout(this._reconnectForCloseDuringAuthTimeout); } diff --git a/components/09-logon.js b/components/09-logon.js index 666560f4..010914b2 100644 --- a/components/09-logon.js +++ b/components/09-logon.js @@ -57,8 +57,8 @@ class SteamUserLogon extends SteamUserMachineAuth { } this.steamID = null; - this._cancelReconnectTimers(); - this._initProperties(); + this._cancelReconnectTimers(true); + this._initProperties(true); this._connecting = true; this._loggingOff = false; @@ -494,10 +494,7 @@ class SteamUserLogon extends SteamUserMachineAuth { * @private */ _enqueueLogonAttempt() { - let timer = this._logonTimeoutDuration || 1000; - this._logonTimeoutDuration = Math.min(timer * 2, 60000); // exponential backoff, max 1 minute - this.emit('debug', `Enqueueing login attempt in ${timer} ms`); - this._logonTimeout = setTimeout(() => { + this._exponentialBackoff('logOn', 1000, 60000).then(() => { if (this.steamID || this._connecting) { // Not sure why this happened, but we're already connected let whyFail = this.steamID ? 'already connected' : 'already attempting to connect'; @@ -507,7 +504,7 @@ class SteamUserLogon extends SteamUserMachineAuth { this.emit('debug', 'Firing queued login attempt'); this.logOn(true); - }, timer); + }); } /** @@ -676,9 +673,10 @@ class SteamUserLogon extends SteamUserMachineAuth { // if we're manually relogging, or we got disconnected because steam went down, enqueue a reconnect if (!wasLoggingOff || this._relogging) { - this._logonTimeout = setTimeout(() => { + this._resetExponentialBackoff('logOn'); + this._exponentialBackoff('logOn', 1000, 1000).then(() => { this.logOn(true); - }, 1000); + }); } this._loggingOff = false; @@ -724,7 +722,7 @@ class SteamUserLogon extends SteamUserMachineAuth { switch (body.eresult) { case EResult.OK: - delete this._logonTimeoutDuration; // success, so reset reconnect timer + this._resetExponentialBackoff('logOn'); // success, so reset reconnect timer this._logOnDetails.last_session_id = this._sessionID; this._logOnDetails.client_instance_id = body.client_instance_id; @@ -820,7 +818,7 @@ class SteamUserLogon extends SteamUserMachineAuth { case EResult.AccountLoginDeniedNeedTwoFactor: case EResult.TwoFactorCodeMismatch: // server is up, so reset logon timer - delete this._logonTimeoutDuration; + this._resetExponentialBackoff('logOn'); this._disconnect(true); @@ -844,7 +842,7 @@ class SteamUserLogon extends SteamUserMachineAuth { default: // server is up, so reset logon timer - delete this._logonTimeoutDuration; + this._resetExponentialBackoff('logOn'); let error = new Error(EResult[body.eresult] || body.eresult); error.eresult = body.eresult; diff --git a/index.js b/index.js index f4eca1f4..68e9d045 100644 --- a/index.js +++ b/index.js @@ -89,7 +89,7 @@ class SteamUser extends SteamUserTwoFactor { this._initialized = true; } - _initProperties() { + _initProperties(isConnecting) { // Account info this.limitations = null; this.vac = null; @@ -133,7 +133,7 @@ class SteamUser extends SteamUserTwoFactor { this._ttlCache = new StdLib.DataStructures.TTLCache(1000 * 60 * 5); // default 5 minutes this._getCmListAttempts = 0; - this._resetAllExponentialBackoffs(); + this._resetAllExponentialBackoffs(isConnecting); delete this._machineAuthToken; delete this._shouldAttemptRefreshTokenRenewal;