From 5d7b3c1ceea5b416534a870a4ae3c414e92a8efc Mon Sep 17 00:00:00 2001 From: Navy Date: Mon, 28 Oct 2024 19:14:13 +0200 Subject: [PATCH 1/3] Implement functionality to reset settings --- @types/Client.ts | 13 ++-- src/client/DiscordClient.ts | 2 +- .../commands/administration/Settings.ts | 62 ++++++++++++++++++- .../components/settings/logging/Moderation.ts | 4 +- .../components/wrappers/GuildWrapper.ts | 5 ++ .../en_gb/commands/en_gb_administration.lang | 12 ++++ src/utilities/Util.ts | 5 ++ 7 files changed, 89 insertions(+), 14 deletions(-) diff --git a/@types/Client.ts b/@types/Client.ts index 45f9107..c68b526 100644 --- a/@types/Client.ts +++ b/@types/Client.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-duplicate-enum-values */ // Galactic - Discord moderation bot // Copyright (C) 2024 Navy.gif @@ -307,12 +308,8 @@ export type SettingAction = { } export type SettingMethod = 'add' | 'remove' | 'edit' | 'list' | 'reset' export type SettingTypeResolve = 'USER' | 'GUILD'; -export type SettingEmojiOption = { - // -} -export type SettingApiDefinitions = { - // -} +export type SettingEmojiOption = object +export type SettingApiDefinitions = object export type BaseSetting = object export type SettingOptions = { name?: string, @@ -372,9 +369,7 @@ export type AdditionalInfractionData = { seconds?: number, } -export type InfractionFlags = { - // -} +export type InfractionFlags = object export type InfractionChangeType = | 'UNRESOLVE' diff --git a/src/client/DiscordClient.ts b/src/client/DiscordClient.ts index 712fbf5..113d5c9 100644 --- a/src/client/DiscordClient.ts +++ b/src/client/DiscordClient.ts @@ -380,7 +380,7 @@ class DiscordClient extends Client } } this.#defaultConfig[type] = def; - return JSON.parse(JSON.stringify(def)); + return Util.clone(def); } // Helper function to pass options to the logger in a unified way diff --git a/src/client/components/commands/administration/Settings.ts b/src/client/components/commands/administration/Settings.ts index e3969c7..66cb161 100644 --- a/src/client/components/commands/administration/Settings.ts +++ b/src/client/components/commands/administration/Settings.ts @@ -15,12 +15,14 @@ // along with this program. If not, see . import { APIEmbed, APIEmbedField } from 'discord.js'; -import { CommandOptionType } from '../../../../../@types/Client.js'; +import { CommandOptionType, CommandParams } from '../../../../../@types/Client.js'; import DiscordClient from '../../../DiscordClient.js'; import SlashCommand from '../../../interfaces/commands/SlashCommand.js'; import InvokerWrapper from '../../wrappers/InvokerWrapper.js'; import Util from '../../../../utilities/Util.js'; import { EmbedDefaultColor, EmbedLimits, ZeroWidthChar } from '../../../../constants/Constants.js'; +import CommandError from '../../../interfaces/CommandError.js'; +import Setting from '../../../interfaces/Setting.js'; class SettingsCommand extends SlashCommand { @@ -44,15 +46,46 @@ class SettingsCommand extends SlashCommand name: 'export', description: 'Display ALL current configurations (big embed)', type: CommandOptionType.SUB_COMMAND + }, { + name: 'reset', + description: 'Reset the setting', + type: CommandOptionType.SUB_COMMAND, + options: [ + { + name: 'setting', + description: 'Setting to reset', + type: CommandOptionType.COMPONENT + }, + { + name: 'all', + description: 'Reset all settings', + type: CommandOptionType.BOOLEAN, + flag: true, + valueOptional: true, + defaultValue: true, + } + ] } ], memberPermissions: [ 'ManageGuild' ] }); } - async execute (invoker: InvokerWrapper) + async execute (invoker: InvokerWrapper, opts: CommandParams) { const subcmd = invoker.subcommand!.name; + + if (subcmd === 'reset') + { + if (opts.all && opts.all.value) + return this.#resetSettings(invoker); + if (!opts.setting) + throw new CommandError(invoker, { index: 'COMMAND_SETTINGS_MANDATORY_MISSING' }); + const setting = opts.setting.value; + if (!(setting instanceof Setting)) + throw new CommandError(invoker, { index: 'COMMAND_SETTINGS_INVALID' }); + return this.#resetSetting(invoker, setting); + } if (subcmd === 'list') return this.#listSettings(invoker); else if (subcmd === 'current') @@ -162,6 +195,31 @@ class SettingsCommand extends SlashCommand // } + async #resetSetting (invoker: InvokerWrapper, setting: Setting) + { + const { guild } = invoker; + const def = setting.default; + guild._settings[setting.name] = def[setting.name]; + await guild.updateSettings(def); + await invoker.reply({ + index: 'COMMAND_SETTINGS_RESET_SUCCESS', + params: { setting: setting.name }, + emoji: 'success' + }); + } + + async #resetSettings (invoker: InvokerWrapper) + { + const { guild } = invoker; + const defaults = this.client.defaultConfig('GUILD'); + guild._settings = defaults; + await guild.updateSettings(defaults); + await invoker.reply({ + index: 'COMMAND_SETTINGS_RESET_ALL', + emoji: 'success' + }); + } + } export default SettingsCommand; \ No newline at end of file diff --git a/src/client/components/settings/logging/Moderation.ts b/src/client/components/settings/logging/Moderation.ts index 892daf9..7faa1dc 100644 --- a/src/client/components/settings/logging/Moderation.ts +++ b/src/client/components/settings/logging/Moderation.ts @@ -59,7 +59,7 @@ class ModerationLog extends Setting infractions: Infractions, anonymous: false, enabled: false, - autoLog: true, + autolog: true, }, definitions: { channel: 'GUILD_TEXT', @@ -193,7 +193,7 @@ class ModerationLog extends Setting inline: true }, { name: 'GENERAL_CHANNEL', - value: `<#${setting.channel}>`, + value: setting.channel ? `<#${setting.channel}>` : '**N/A**', inline: true }, { name: 'GENERAL_INFRACTIONS', diff --git a/src/client/components/wrappers/GuildWrapper.ts b/src/client/components/wrappers/GuildWrapper.ts index 2f091fe..9b5449c 100644 --- a/src/client/components/wrappers/GuildWrapper.ts +++ b/src/client/components/wrappers/GuildWrapper.ts @@ -551,6 +551,11 @@ class GuildWrapper return this.#settings; } + set _settings (val: GuildSettings) + { + this.#settings = val; + } + // Primarily used by the API toJSON (): GuildJSON { diff --git a/src/localization/en_gb/commands/en_gb_administration.lang b/src/localization/en_gb/commands/en_gb_administration.lang index c8f1b22..0bbe328 100644 --- a/src/localization/en_gb/commands/en_gb_administration.lang +++ b/src/localization/en_gb/commands/en_gb_administration.lang @@ -69,6 +69,18 @@ Configure utility settings. [COMMAND_ADMINISTRATION_HELP] Configure administrative settings. +[COMMAND_SETTINGS_MANDATORY_MISSING] +Missing mandatory option "setting" + +[COMMAND_SETTINGS_INVALID] +The provided component does not seem to be a setting + +[COMMAND_SETTINGS_RESET_ALL] +Successfully reset all settings. + +[COMMAND_SETTINGS_RESET_SUCCESS] +Successfully reset {setting} setting. + // Import [COMMAND_IMPORT_HELP] Import configuration and data from old versions of the bot. diff --git a/src/utilities/Util.ts b/src/utilities/Util.ts index 4803b1c..d838780 100644 --- a/src/utilities/Util.ts +++ b/src/utilities/Util.ts @@ -259,6 +259,11 @@ class Util return result; } + static clone (object: object) + { + return JSON.parse(JSON.stringify(object)); + } + static wait (ms: number) { return this.delayFor(ms); From b3898a498ba5ea22a895fb06288271ac845c4090 Mon Sep 17 00:00:00 2001 From: Navy Date: Tue, 29 Oct 2024 13:26:26 +0200 Subject: [PATCH 2/3] Make ping quotes sequential but shuffled --- .../components/commands/utility/Ping.ts | 19 +++++++++++----- src/utilities/Util.ts | 22 +++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/client/components/commands/utility/Ping.ts b/src/client/components/commands/utility/Ping.ts index a1e7e50..6087e1b 100644 --- a/src/client/components/commands/utility/Ping.ts +++ b/src/client/components/commands/utility/Ping.ts @@ -18,19 +18,23 @@ import { SlashCommand } from '../../../interfaces/index.js'; import DiscordClient from '../../../DiscordClient.js'; import InvokerWrapper from '../../wrappers/InvokerWrapper.js'; import Quotes from '../../../../constants/Quotes.js'; +import Util from '../../../../utilities/Util.js'; class PingCommand extends SlashCommand { - + #index: number; + #quotes: string[][]; constructor (client: DiscordClient) { - super(client, { name: 'ping', description: 'Ping? Pong!', moduleName: 'utility', }); + this.#index = 0; + this.#quotes = [ ...Quotes ]; + Util.shuffle(this.#quotes); } async execute (invoker: InvokerWrapper) @@ -39,11 +43,16 @@ class PingCommand extends SlashCommand const number = (ping / 40); const repeat = number > 1 ? number : 1; - const index = Math.floor(Quotes.length * Math.random()); - const [ quote, author ] = Quotes[index]; + if (this.#index >= this.#quotes.length) + { + this.#index = 0; + Util.shuffle(this.#quotes); + } + + const index = this.#index++; + const [ quote, author ] = this.#quotes[index]; return invoker.reply(`P${'o'.repeat(repeat)}ng! \`${ping}ms\`\n\n> ${quote.replaceAll('\n', '\n> ')}\n\\- *${author}*`, { emoji: 'success' }); } - } export default PingCommand; \ No newline at end of file diff --git a/src/utilities/Util.ts b/src/utilities/Util.ts index d838780..f99e679 100644 --- a/src/utilities/Util.ts +++ b/src/utilities/Util.ts @@ -196,6 +196,28 @@ class Util throw error; } + /** + * Shuffles array in place + * @date 3/25/2024 - 11:25:09 AM + * + * @static + * @template T + * @param {T[]} array + * @returns {T[]} + */ + static shuffle (array: T[]): T[] + { + let current = array.length; + let random = 0; + while (current > 0) + { + random = Math.floor(Math.random() * current); + current--; + [ array[current], array[random] ] = [ array[random], array[current] ]; + } + return array; + } + static paginate (items: Array, page = 1, pageLength = 10) { const maxPage = Math.ceil(items.length / pageLength); From 36e320ab1b14d60d55d9dfc467da5a1b257ffad5 Mon Sep 17 00:00:00 2001 From: Navy Date: Mon, 11 Nov 2024 11:53:25 +0200 Subject: [PATCH 3/3] Add author id to bulk delete logs --- src/client/components/observers/GuildLogging.ts | 2 +- src/client/components/wrappers/MessageWrapper.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client/components/observers/GuildLogging.ts b/src/client/components/observers/GuildLogging.ts index 3d1784c..72e4b70 100644 --- a/src/client/components/observers/GuildLogging.ts +++ b/src/client/components/observers/GuildLogging.ts @@ -565,7 +565,7 @@ class GuildLogger extends Observer const value = stripIndents`${content ? content.substring(0, cutOff) : wrapper.format('BULK_DELETE_NO_CONTENT')}`; // ${message.attachments.size > 0 ? `__(Attachments: ${attStr})__` : '' } fields.push({ - name: `${Util.escapeMarkdown(author.tag)} @ ${moment.utc(message.createdAt).format('D/M/YYYY H:m:s')} UTC (MSG ID: ${id})`, + name: `${Util.escapeMarkdown(author.tag)} (${author.id}) (MSG ID: ${id})`, value }); diff --git a/src/client/components/wrappers/MessageWrapper.ts b/src/client/components/wrappers/MessageWrapper.ts index f714cbf..4183875 100644 --- a/src/client/components/wrappers/MessageWrapper.ts +++ b/src/client/components/wrappers/MessageWrapper.ts @@ -45,10 +45,10 @@ class MessageWrapper this.#caller = null; } - // get message () - // { - // return this.#message; - // } + get message () + { + return this.#message; + } get id () {