From 3252073d491ba7678c106fa92fa02c18b2123128 Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Sat, 2 Sep 2023 18:06:27 +0300 Subject: [PATCH] Add commands for enabling/disabling voice commands and automatic joining (#34) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: sweep-ai[bot] <128439645+sweep-ai[bot]@users.noreply.github.com> Co-authored-by: Lassi Säike --- .../commands/DisableAutoJoinCommand.ts | 33 +++++ .../voice_commands/commands/DisableCommand.ts | 33 +++++ .../commands/EnableAutoJoinCommand.ts | 33 +++++ .../voice_commands/commands/EnableCommand.ts | 39 ++++++ src_modules/voice_commands/index.ts | 70 +++++++++-- src_modules/voice_commands/phrases.ts | 118 ++++++++++++++++++ 6 files changed, 316 insertions(+), 10 deletions(-) create mode 100644 src_modules/voice_commands/commands/DisableAutoJoinCommand.ts create mode 100644 src_modules/voice_commands/commands/DisableCommand.ts create mode 100644 src_modules/voice_commands/commands/EnableAutoJoinCommand.ts create mode 100644 src_modules/voice_commands/commands/EnableCommand.ts create mode 100644 src_modules/voice_commands/phrases.ts diff --git a/src_modules/voice_commands/commands/DisableAutoJoinCommand.ts b/src_modules/voice_commands/commands/DisableAutoJoinCommand.ts new file mode 100644 index 0000000..7fa0088 --- /dev/null +++ b/src_modules/voice_commands/commands/DisableAutoJoinCommand.ts @@ -0,0 +1,33 @@ +import { Command, IExecutionContext } from "../../.."; +import VoiceCommandsModule from ".."; +import { autoJoinDisabledPhrase, autoJoinAlreadyDisabledPhrase } from "../phrases"; + +export class DisableAutoJoinCommand extends Command<[]> { + private voiceCommandsModule: VoiceCommandsModule; + + public constructor(voiceCommandsModule: VoiceCommandsModule) { + super( + { + allowedPrivileges: ["admin"], + author: "extcord", + description: "Disable automatic joining", + globalAliases: ["disableautojoin"], + name: "disableautojoin", + }, + [], + ); + + this.voiceCommandsModule = voiceCommandsModule; + } + + public async execute(context: IExecutionContext<[]>) { + const guild = context.guild; + + if (await this.voiceCommandsModule.autoJoinEnabledConfigEntry.guildGet(guild)) { + await this.voiceCommandsModule.autoJoinEnabledConfigEntry.guildSet(guild, false); + return context.respond(autoJoinDisabledPhrase, {}); + } else { + return context.respond(autoJoinAlreadyDisabledPhrase, {}); + } + } +} diff --git a/src_modules/voice_commands/commands/DisableCommand.ts b/src_modules/voice_commands/commands/DisableCommand.ts new file mode 100644 index 0000000..e6f9f30 --- /dev/null +++ b/src_modules/voice_commands/commands/DisableCommand.ts @@ -0,0 +1,33 @@ +import { Command, IExecutionContext } from "../../.."; +import VoiceCommandsModule from ".."; +import { voiceCommandsDisabledPhrase, voiceCommandsAlreadyDisabledPhrase } from "../phrases"; + +export class DisableCommand extends Command<[]> { + private voiceCommandsModule: VoiceCommandsModule; + + public constructor(voiceCommandsModule: VoiceCommandsModule) { + super( + { + allowedPrivileges: ["admin"], + author: "extcord", + description: "Disable voice commands", + globalAliases: [], + name: "disable", + }, + [], + ); + + this.voiceCommandsModule = voiceCommandsModule; + } + + public async execute(context: IExecutionContext<[]>) { + const guild = context.guild; + + if (await this.voiceCommandsModule.voiceCommandsEnabledConfigEntry.guildGet(guild)) { + await this.voiceCommandsModule.voiceCommandsEnabledConfigEntry.guildSet(guild, false); + return context.respond(voiceCommandsDisabledPhrase, {}); + } else { + return context.respond(voiceCommandsAlreadyDisabledPhrase, {}); + } + } +} diff --git a/src_modules/voice_commands/commands/EnableAutoJoinCommand.ts b/src_modules/voice_commands/commands/EnableAutoJoinCommand.ts new file mode 100644 index 0000000..2c9125f --- /dev/null +++ b/src_modules/voice_commands/commands/EnableAutoJoinCommand.ts @@ -0,0 +1,33 @@ +import { Command, IExecutionContext } from "../../.."; +import VoiceCommandsModule from ".."; +import { autoJoinEnabledPhrase, autoJoinAlreadyEnabledPhrase } from "../phrases"; + +export class EnableAutoJoinCommand extends Command<[]> { + private voiceCommandsModule: VoiceCommandsModule; + + public constructor(voiceCommandsModule: VoiceCommandsModule) { + super( + { + allowedPrivileges: ["admin"], + author: "extcord", + description: "Enable automatic joining", + globalAliases: ["enableautojoin"], + name: "enableautojoin", + }, + [], + ); + + this.voiceCommandsModule = voiceCommandsModule; + } + + public async execute(context: IExecutionContext<[]>) { + const guild = context.guild; + + if (await this.voiceCommandsModule.autoJoinEnabledConfigEntry.guildGet(guild)) { + return context.respond(autoJoinAlreadyEnabledPhrase, {}); + } + + await this.voiceCommandsModule.autoJoinEnabledConfigEntry.guildSet(guild, true); + return context.respond(autoJoinEnabledPhrase, {}); + } +} diff --git a/src_modules/voice_commands/commands/EnableCommand.ts b/src_modules/voice_commands/commands/EnableCommand.ts new file mode 100644 index 0000000..906dbde --- /dev/null +++ b/src_modules/voice_commands/commands/EnableCommand.ts @@ -0,0 +1,39 @@ +import { Command, IExecutionContext } from "../../.."; +import VoiceCommandsModule from ".."; +import { voiceCommandsAlreadyEnabledPhrase, voiceCommandsEnabledPhrase, voiceCommandsNotSupportedPhrase } from "../phrases"; + +export class EnableCommand extends Command<[]> { + private voiceCommandsModule: VoiceCommandsModule; + + public constructor(voiceCommandsModule: VoiceCommandsModule) { + super( + { + allowedPrivileges: ["admin"], + author: "extcord", + description: "Enable voice commands", + globalAliases: [], + name: "enable", + }, + [], + ); + + this.voiceCommandsModule = voiceCommandsModule; + } + + public async execute(context: IExecutionContext<[]>) { + const guild = context.guild; + + if (await this.voiceCommandsModule.voiceCommandsEnabledConfigEntry.guildGet(guild)) { + return context.respond(voiceCommandsAlreadyEnabledPhrase, {}); + } + + const backendLanguage = this.voiceCommandsModule.backendLanguageIdPhrase.get(context.language); + + if (backendLanguage === undefined || backendLanguage === "") { + return context.respond(voiceCommandsNotSupportedPhrase, {});; + } + + await this.voiceCommandsModule.voiceCommandsEnabledConfigEntry.guildSet(guild, true); + return context.respond(voiceCommandsEnabledPhrase, {}); + } +} diff --git a/src_modules/voice_commands/index.ts b/src_modules/voice_commands/index.ts index fa8cd72..3126a8e 100644 --- a/src_modules/voice_commands/index.ts +++ b/src_modules/voice_commands/index.ts @@ -4,13 +4,18 @@ import { GatewayIntentBits, Guild, VoiceState, VoiceChannel } from "discord.js"; import { VoiceConnection } from "@discordjs/voice"; -import { BooleanGuildConfigEntry, Bot, Logger, Module, SimplePhrase, StringConfigEntry, NumberConfigEntry } from "../.."; +import { BooleanGuildConfigEntry, Bot, CommandGroup, Logger, Module, SimplePhrase, StringConfigEntry, NumberConfigEntry } from "../.."; +import { voiceCommandsEnabledPhrase, voiceCommandsDisabledPhrase, autoJoinEnabledPhrase, autoJoinDisabledPhrase, voiceCommandsAlreadyDisabledPhrase, voiceCommandsAlreadyEnabledPhrase, autoJoinAlreadyDisabledPhrase, autoJoinAlreadyEnabledPhrase, voiceCommandsNotSupportedPhrase } from "./phrases"; import { GuildListener } from "./GuildListener"; import { VoiceBackendClient } from "./VoiceBackendClient"; import { PhoneticCache } from "./PhoneticCache"; import { SpeechCache } from "./SpeechCache"; import { VoiceCommands } from "./VoiceCommands"; +import { DisableCommand } from "./commands/DisableCommand"; +import { EnableCommand } from "./commands/EnableCommand"; +import { EnableAutoJoinCommand } from "./commands/EnableAutoJoinCommand"; +import { DisableAutoJoinCommand } from "./commands/DisableAutoJoinCommand"; export default class VoiceCommandsModule extends Module { private listeners: Map; @@ -25,8 +30,10 @@ export default class VoiceCommandsModule extends Module { public maxQueuedAsrCountConfigEntry: NumberConfigEntry; public tokenConfigEntry: StringConfigEntry; public voiceCommandsEnabledConfigEntry: BooleanGuildConfigEntry; + public autoJoinEnabledConfigEntry: BooleanGuildConfigEntry; public client: VoiceBackendClient; public voiceCommands: VoiceCommands; + public voiceCommandsGroup: CommandGroup; public phoneticCache: PhoneticCache; public speechCache: SpeechCache; @@ -97,6 +104,10 @@ export default class VoiceCommandsModule extends Module { }, bot.database, true); this.registerConfigEntry(this.voiceCommandsEnabledConfigEntry); + this.autoJoinEnabledConfigEntry = new BooleanGuildConfigEntry({ + name: "autoJoinEnabled", + }, bot.database, false); + this.registerConfigEntry(this.autoJoinEnabledConfigEntry); bot.intents.push(GatewayIntentBits.GuildVoiceStates); @@ -104,6 +115,33 @@ export default class VoiceCommandsModule extends Module { this.voiceCommands = new VoiceCommands(this, bot); this.phoneticCache = new PhoneticCache(this, bot); this.speechCache = new SpeechCache(this, bot); + + this.voiceCommandsGroup = new CommandGroup( + { + allowedPrivileges: ["everyone"], + author: "extcord", + description: "Commands for managing voice commands and automatic joining", + name: "voice-commands", + }, + ); + this.voiceCommandsGroup.addSubcommands( + new EnableCommand(this), + new DisableCommand(this), + new EnableAutoJoinCommand(this), + new DisableAutoJoinCommand(this), + ); + this.voiceCommandsGroup.addPhrases( + voiceCommandsEnabledPhrase, + voiceCommandsDisabledPhrase, + autoJoinEnabledPhrase, + autoJoinDisabledPhrase, + voiceCommandsAlreadyDisabledPhrase, + voiceCommandsAlreadyEnabledPhrase, + autoJoinAlreadyDisabledPhrase, + autoJoinAlreadyEnabledPhrase, + voiceCommandsNotSupportedPhrase, + ); + this.registerCommand(this.voiceCommandsGroup); } public async getListener(guild: Guild): Promise { @@ -143,15 +181,27 @@ export default class VoiceCommandsModule extends Module { if (oldState.channel === null && newState.channel !== null && newState.channel instanceof VoiceChannel && !newState.member?.user.bot) { const channel = newState.channel; - // Someone joined a voice channel - const nonBotUsers = channel.members.filter(member => !member.user.bot); - if (nonBotUsers.size > 0 && this.bot.voice.getConnection(channel.guild) === undefined) { - setTimeout(async () => { - const nonBotUsers = channel.members.filter(member => !member.user.bot); - if (nonBotUsers.size > 0 && this.bot.voice.getConnection(channel.guild) === undefined) { - await this.getConnection(this.bot, channel); - } - }, 5000); + this.bot.database.ensureConnection(); + + const guildEntity = await this.bot.database.repos.guild.getEntity(newState.guild); + + const extendedGuild = { + entity: guildEntity, + guild: newState.guild, + }; + + const autoJoinEnabled = await this.autoJoinEnabledConfigEntry.guildGet(extendedGuild); + + if (autoJoinEnabled) { + const nonBotUsers = channel.members.filter(member => !member.user.bot); + if (nonBotUsers.size > 0 && this.bot.voice.getConnection(channel.guild) === undefined) { + setTimeout(async () => { + const nonBotUsers = channel.members.filter(member => !member.user.bot); + if (nonBotUsers.size > 0 && this.bot.voice.getConnection(channel.guild) === undefined) { + await this.getConnection(this.bot, channel); + } + }, 5000); + } } } diff --git a/src_modules/voice_commands/phrases.ts b/src_modules/voice_commands/phrases.ts new file mode 100644 index 0000000..fa1bd4d --- /dev/null +++ b/src_modules/voice_commands/phrases.ts @@ -0,0 +1,118 @@ +import { MessagePhrase } from "../.."; + +export const voiceCommandsEnabledPhrase = new MessagePhrase( + { + description: "Shown when voice commands are enabled", + name: "voiceCommandsEnabled", + }, + "Voice commands enabled.", + { + timestamp: false, + title: "Voice commands enabled." + }, + {}, +); + +export const voiceCommandsDisabledPhrase = new MessagePhrase( + { + description: "Shown when voice commands are disabled", + name: "voiceCommandsDisabled", + }, + "Voice commands disabled.", + { + timestamp: false, + title: "Voice commands disabled." + }, + {}, +); + +export const autoJoinEnabledPhrase = new MessagePhrase( + { + description: "Shown when automatic joining is enabled", + name: "autoJoinEnabled", + }, + "Automatic joining enabled.", + { + timestamp: false, + title: "Automatic joining enabled." + }, + {}, +); + +export const autoJoinDisabledPhrase = new MessagePhrase( + { + description: "Shown when automatic joining is disabled", + name: "autoJoinDisabled", + }, + "Automatic joining disabled.", + { + timestamp: false, + title: "Automatic joining disabled." + }, + {}, +); + +export const autoJoinAlreadyDisabledPhrase = new MessagePhrase( + { + description: "Shown when automatic joining is already disabled", + name: "autoJoinAlreadyDisabled", + }, + "Automatic joining is already disabled.", + { + timestamp: false, + title: "Automatic joining already disabled." + }, + {}, +); + +export const voiceCommandsAlreadyDisabledPhrase = new MessagePhrase( + { + description: "Shown when voice commands are already disabled", + name: "voiceCommandsAlreadyDisabled", + }, + "Voice commands are already disabled.", + { + timestamp: false, + title: "Voice commands already disabled." + }, + {}, +); + +export const autoJoinAlreadyEnabledPhrase = new MessagePhrase( + { + description: "Shown when automatic joining is already enabled", + name: "autoJoinAlreadyEnabled", + }, + "Automatic joining is already enabled.", + { + timestamp: false, + title: "Automatic joining already enabled." + }, + {}, +); + +export const voiceCommandsAlreadyEnabledPhrase = new MessagePhrase( + { + description: "Shown when voice commands are already enabled", + name: "voiceCommandsAlreadyEnabled", + }, + "Voice commands are already enabled.", + { + timestamp: false, + title: "Voice commands already enabled." + }, + {}, +); + +export const voiceCommandsNotSupportedPhrase = new MessagePhrase( + { + description: "Shown when voice commands are not supported with the language", + name: "voiceCommandsNotSupported", + }, + "Voice commands are not supported with this language.", + { + timestamp: false, + title: "Voice commands are not supported with this language." + }, + {}, +);