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);