diff --git a/packages/core/src/network/config-manager.ts b/packages/core/src/network/config-manager.ts index 8fd520e0..80690d28 100644 --- a/packages/core/src/network/config-manager.ts +++ b/packages/core/src/network/config-manager.ts @@ -16,8 +16,8 @@ export class ConfigManager { return !this._config || this._config.expires < Date.now() / 1000 } - update(): Promise { - if (!this.isStale) return Promise.resolve() + update(force = false): Promise { + if (!force && !this.isStale) return Promise.resolve() if (this._updatingPromise) return this._updatingPromise return (this._updatingPromise = this._update().then((config) => { diff --git a/packages/core/src/network/multi-session-connection.ts b/packages/core/src/network/multi-session-connection.ts index da8ec79b..24b00e50 100644 --- a/packages/core/src/network/multi-session-connection.ts +++ b/packages/core/src/network/multi-session-connection.ts @@ -148,11 +148,16 @@ export class MultiSessionConnection extends EventEmitter { ...this.params, usePfs: this.params.usePfs || this._enforcePfs, isMainConnection: this.params.isMainConnection && i === 0, + withUpdates: + this.params.isMainConnection && + !this.params.disableUpdates, }, session, ) - conn.on('update', (update) => this.emit('update', update)) + if (this.params.isMainConnection) { + conn.on('update', (update) => this.emit('update', update)) + } conn.on('error', (err) => this.emit('error', err, conn)) conn.on('key-change', (key) => { this.emit('key-change', i, key) diff --git a/packages/core/src/network/network-manager.ts b/packages/core/src/network/network-manager.ts index 4825c8aa..6b817c1f 100644 --- a/packages/core/src/network/network-manager.ts +++ b/packages/core/src/network/network-manager.ts @@ -82,7 +82,7 @@ export interface NetworkManagerExtraParams { * Connection count for each connection kind * * Defaults to TDLib logic: - * - main: 1 (should not be changed manually) + * - main: handled internally, **cannot be changed here** * - upload: if premium or dc id is other than 2 or 4, then 8, otherwise 4 * - download: if premium then 8, otherwise 2 * - downloadSmall: if premium then 8, otherwise 2 @@ -195,6 +195,12 @@ export class DcConnectionManager { 'DOWNLOAD_SMALL', ) + private get _mainConnectionCount() { + if (!this.isPrimary) return 1 + + return this.manager.config.getNow()?.tmpSessions ?? 1 + } + constructor( readonly manager: NetworkManager, readonly dcId: number, @@ -212,11 +218,7 @@ export class DcConnectionManager { this.main = new MultiSessionConnection( mainParams, - this.manager._connectionCount( - 'main', - this._dc.id, - this.manager.params.isPremium, - ), + this._mainConnectionCount, this._log, 'MAIN', ) @@ -442,6 +444,9 @@ export class NetworkManager { params.reconnectionStrategy ?? defaultReconnectionStrategy this._connectionCount = params.connectionCount ?? defaultConnectionCountDelegate + + this._onConfigChanged = this._onConfigChanged.bind(this) + config.onConfigUpdate(this._onConfigChanged) } private _switchPrimaryDc(dc: DcConnectionManager) { @@ -462,6 +467,15 @@ export class NetworkManager { this._lastUpdateTime = Date.now() } }, 60_000) + + Promise.resolve(this._storage.getSelf()).then((self) => { + if (self?.isBot) { + // bots may receive tmpSessions, which we should respect + this.config + .update(true) + .catch((e) => this.params._emitError(e)) + } + }) }) dc.main.on('update', (update) => { this._lastUpdateTime = Date.now() @@ -569,6 +583,22 @@ export class NetworkManager { } } + async notifyLoggedIn(auth: tl.auth.TypeAuthorization): Promise { + if (auth._ === 'auth.authorizationSignUpRequired') return + + if (auth.tmpSessions) { + this._primaryDc?.main.setCount(auth.tmpSessions) + } + + // await this.exportAuth() + } + + private _onConfigChanged(config: tl.RawConfig): void { + if (config.tmpSessions) { + this._primaryDc?.main.setCount(config.tmpSessions) + } + } + async changePrimaryDc(newDc: number): Promise { if (newDc === this._primaryDc?.dcId) return @@ -723,7 +753,11 @@ export class NetworkManager { destroy(): void { for (const dc of Object.values(this._dcConnections)) { dc.main.destroy() + dc.upload.destroy() + dc.download.destroy() + dc.downloadSmall.destroy() } if (this._keepAliveInterval) clearInterval(this._keepAliveInterval) + this.config.offConfigUpdate(this._onConfigChanged) } } diff --git a/packages/core/src/network/session-connection.ts b/packages/core/src/network/session-connection.ts index c17fefcf..fa995d9c 100644 --- a/packages/core/src/network/session-connection.ts +++ b/packages/core/src/network/session-connection.ts @@ -39,6 +39,7 @@ export interface SessionConnectionParams extends PersistentConnectionParams { niceStacks?: boolean layer: number disableUpdates?: boolean + withUpdates?: boolean isMainConnection: boolean usePfs?: boolean @@ -266,6 +267,14 @@ export class SessionConnection extends PersistentConnection { protected onConnectionUsable() { super.onConnectionUsable() + if (this.params.withUpdates) { + // we must send some user-related rpc to the server to make sure that + // it will send us updates + this.sendRpc({ _: 'updates.getState' }).catch((err: any) => { + this.log.warn('failed to send updates.getState: %s', err) + }) + } + // just in case this._flushTimer.emitBeforeNext(1000) } @@ -716,10 +725,6 @@ export class SessionConnection extends PersistentConnection { // todo: reset session break } - if (!this.params.isMainConnection) { - this.log.warn('received updates on non-main connection') - break - } this.emit('update', message)