diff --git a/packages/core/src/bot.ts b/packages/core/src/bot.ts index 9ce5dad0..f841ec9a 100644 --- a/packages/core/src/bot.ts +++ b/packages/core/src/bot.ts @@ -1,5 +1,5 @@ -import { clone, Dict, pick, remove } from 'cosmokit' -import { Context, Logger } from 'cordis' +import { clone, Dict, pick } from 'cosmokit' +import { Context, Logger, Service } from 'cordis' import h from '@satorijs/element' import { Adapter } from './adapter' import { MessageEncoder } from './message' @@ -22,7 +22,11 @@ export abstract class Bot implements Login static reusable = true static MessageEncoder?: new (bot: Bot, channelId: string, guildId?: string, options?: SendOptions) => MessageEncoder - public self = this + public [Service.tracker] = { + associate: 'bot', + property: 'ctx', + } + public user = {} as User public isBot = true public hidden = false @@ -33,7 +37,6 @@ export abstract class Bot implements Login public error?: Error public callbacks: Dict = {} public logger: Logger - public [Context.current]: C // Same as `this.ctx`, but with a more specific type. protected context: Context @@ -42,13 +45,11 @@ export abstract class Bot implements Login constructor(public ctx: C, public config: T, platform?: string) { this.internal = null this.context = ctx - this[Context.current] = ctx - const self = Context.associate(this, 'bot') - ctx.bots.push(self) - self.context.emit('bot-added', self) + ctx.bots.push(this) + this.context.emit('bot-added', this) if (platform) { - self.logger = ctx.logger(platform) - self.platform = platform + this.logger = ctx.logger(platform) + this.platform = platform } this.proxyUrls = [`upload://temp/${ctx.satori.uid}/`] @@ -58,18 +59,16 @@ export abstract class Bot implements Login ctx.on('ready', async () => { await Promise.resolve() - self.dispatchLoginEvent('login-added') - return self.start() + this.dispatchLoginEvent('login-added') + return this.start() }) - ctx.on('dispose', () => self.dispose()) + ctx.on('dispose', () => this.dispose()) ctx.on('interaction/button', (session) => { const cb = this.callbacks[session.event.button.id] if (cb) cb(session) }) - - return self } registerUpload(path: string, callback: (path: string) => Promise) { @@ -85,9 +84,12 @@ export abstract class Bot implements Login } dispose() { - remove(this.ctx.bots, this) - this.context.emit('bot-removed', this) - this.dispatchLoginEvent('login-removed') + const index = this.ctx.bots.findIndex(bot => bot.sid === this.sid) + if (index >= 0) { + this.ctx.bots.splice(index, 1) + this.context.emit('bot-removed', this) + this.dispatchLoginEvent('login-removed') + } return this.stop() } @@ -105,7 +107,7 @@ export abstract class Bot implements Login set status(value) { if (value === this._status) return this._status = value - if (this.ctx.bots?.includes(this)) { + if (this.ctx.bots?.some(bot => bot.sid === this.sid)) { this.context.emit('bot-status-updated', this) this.dispatchLoginEvent('login-updated') } @@ -143,7 +145,7 @@ export abstract class Bot implements Login await this.context.parallel('bot-disconnect', this) await this.adapter?.disconnect(this) } catch (error) { - this.context.emit('internal/error', error) + this.context.emit(this.ctx, 'internal/error', error) } finally { this.offline() } @@ -216,7 +218,7 @@ export abstract class Bot implements Login delete this.ctx.satori._tempStore[id] } } - const _dispose = this[Context.current].on('dispose', dispose) + const _dispose = this.ctx.on('dispose', dispose) return ids.map(id => `upload://temp/${this.ctx.satori.uid}/${id}`) } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 37b9c3a5..ccdcc2e2 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,5 +1,5 @@ import { Context, Logger, Service, z } from 'cordis' -import { Awaitable, Dict, makeArray, remove } from 'cosmokit' +import { Awaitable, defineProperty, Dict, makeArray, remove } from 'cosmokit' import { Bot } from './bot' import { Session } from './session' import { HTTP } from '@cordisjs/plugin-http' @@ -135,6 +135,8 @@ export class Satori extends Service { return this._tempStore[id] ?? { status: 404 } }) + defineProperty(this.bots, Service.tracker, {}) + const self = this ;(ctx as Context).on('http/file', async function (url, options) { if (!url.startsWith('upload://')) return @@ -180,7 +182,7 @@ export class Satori extends Service { } upload(path: UploadRoute['path'], callback: UploadRoute['callback'], proxyUrls: UploadRoute['path'][] = []) { - return this[Context.current].effect(() => { + return this.ctx.effect(() => { const route: UploadRoute = { path, callback } this._uploadRoutes.push(route) proxyUrls.push(path) diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index 61dc74f9..9e180f79 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -1,6 +1,6 @@ import { Channel, Event, GuildMember, Message, User } from '@satorijs/protocol' import { defineProperty, isNullable } from 'cosmokit' -import { Context } from 'cordis' +import { Context, Service } from 'cordis' import { Bot } from './bot' import h from '@satorijs/element' @@ -30,6 +30,11 @@ export interface Session { export class Session { static counter = 0 + public [Service.tracker] = { + associate: 'session', + property: 'ctx', + } + public id: number public bot: Bot public app: C['root']