From 6c10710256d5372217c6ddc86d940d05798a8bc0 Mon Sep 17 00:00:00 2001 From: Michael Kenzel Date: Mon, 15 Jul 2024 03:31:47 +0200 Subject: [PATCH] Introduce passive mode (#107) In passive mode, Wheatley will not advertise or react to commands, and only load components that are marked as passive. This is to allow additional secondary instances of the bot to coexist with a running primary instance on the same server without interference, e.g., for testing new features. --- README.md | 7 ++++++- src/bot-component.ts | 4 ++++ src/wheatley.ts | 18 ++++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5ad34d3c..6beab964 100644 --- a/README.md +++ b/README.md @@ -54,13 +54,15 @@ Secrets and other bot info must be configured in the `auth.json` file. An exampl "host": "127.0.0.1", // optional "port": 27017 // optional }, - "freestanding": false + "freestanding": false, // optional + "passive": false // optional } ``` Mongo credentials can be omitted locally if you don't need to work on components that use mongo. `freestanding: true` can be specified to turn on only components which don't rely on channels etc. specific to Together C & C++ to exist. Freestanding mode also disables connecting to MongoDB. +`passive: true` can be specified to run the bot in passive mode, where it will not advertise or react to commands, and only load components that are marked as passive (useful for testing new features in a second instance without interfering with a running primary instance). ## Bot Component Abstraction @@ -71,6 +73,9 @@ export class BotComponent { static get is_freestanding() { return false; } + static get is_passive() { + return false; + } // Add a command add_command( command: diff --git a/src/bot-component.ts b/src/bot-component.ts index cac6e984..359b5cc3 100644 --- a/src/bot-component.ts +++ b/src/bot-component.ts @@ -15,6 +15,10 @@ export class BotComponent { return false; } + static get is_passive() { + return false; + } + constructor(protected readonly wheatley: Wheatley) { wheatley.event_hub.on("wheatley_ready", this.wrap(this.on_wheatley_ready.bind(this))); } diff --git a/src/wheatley.ts b/src/wheatley.ts index 71ea899d..5ee9a073 100644 --- a/src/wheatley.ts +++ b/src/wheatley.ts @@ -66,6 +66,7 @@ export type wheatley_auth = { guild?: string; token: string; freestanding?: boolean; + passive?: boolean; mongo?: wheatley_database_credentials; sentry?: string; virustotal?: string; @@ -316,6 +317,8 @@ export class Wheatley { readonly guildId: string; // True if freestanding mode is enabled. Defaults to false. readonly freestanding: boolean; + // True if passive mode is enabled. Defaults to false. + readonly passive: boolean; // Some emojis readonly pepereally = "<:pepereally:643881257624666112>"; @@ -426,6 +429,7 @@ export class Wheatley { ) { this.id = auth.id; this.freestanding = auth.freestanding ?? false; + this.passive = auth.passive ?? false; this.guildId = auth.guild ?? TCCPP_ID; this.parameters = drop_token(auth); @@ -602,8 +606,12 @@ export class Wheatley { await wrap(() => this.fetch_root_mod_list(this.client)); } - async add_component(component: { new (w: Wheatley): T; get is_freestanding(): boolean }) { - if (!this.freestanding || component.is_freestanding) { + async add_component(component: { + new (w: Wheatley): T; + get is_freestanding(): boolean; + get is_passive(): boolean; + }) { + if ((!this.passive || component.is_passive) && (!this.freestanding || component.is_freestanding)) { M.log(`Initializing ${component.name}`); assert(!this.components.has(component.name), "Duplicate component name"); const instance = new component(this); @@ -964,6 +972,9 @@ export class Wheatley { | MessageContextMenuInteractionBuilder | ModalInteractionBuilder, ) { + if (this.passive) { + return; + } if (command instanceof TextBasedCommandBuilder) { for (const descriptor of command.to_command_descriptors(this)) { assert(!(descriptor.name in this.text_commands)); @@ -986,6 +997,9 @@ export class Wheatley { // returns false if the message was not a wheatley command async handle_text_command(message: Discord.Message, prev_command_obj?: TextBasedCommand) { + if (this.passive) { + return false; + } const match = message.content.match(Wheatley.command_regex); if (match) { const command_name = match[1];