Merge pull request 'Setting reset functionality and author ID to bulk delete logs' (#24) from development into alpha
Reviewed-on: #24
This commit is contained in:
commit
62416dcf82
@ -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<IsGuildSetting extends boolean> = {
|
||||
name?: string,
|
||||
@ -372,9 +369,7 @@ export type AdditionalInfractionData = {
|
||||
seconds?: number,
|
||||
}
|
||||
|
||||
export type InfractionFlags = {
|
||||
//
|
||||
}
|
||||
export type InfractionFlags = object
|
||||
|
||||
export type InfractionChangeType =
|
||||
| 'UNRESOLVE'
|
||||
|
@ -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
|
||||
|
@ -15,12 +15,14 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
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<true>, 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<true>)
|
||||
{
|
||||
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;
|
@ -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;
|
@ -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}) <t:${message.createdTimestamp}:R> (MSG ID: ${id})`,
|
||||
value
|
||||
});
|
||||
|
||||
|
@ -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',
|
||||
|
@ -551,6 +551,11 @@ class GuildWrapper
|
||||
return this.#settings;
|
||||
}
|
||||
|
||||
set _settings (val: GuildSettings)
|
||||
{
|
||||
this.#settings = val;
|
||||
}
|
||||
|
||||
// Primarily used by the API
|
||||
toJSON (): GuildJSON
|
||||
{
|
||||
|
@ -45,10 +45,10 @@ class MessageWrapper<InGuild extends boolean = boolean>
|
||||
this.#caller = null;
|
||||
}
|
||||
|
||||
// get message ()
|
||||
// {
|
||||
// return this.#message;
|
||||
// }
|
||||
get message ()
|
||||
{
|
||||
return this.#message;
|
||||
}
|
||||
|
||||
get id ()
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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<T> (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<unknown>, page = 1, pageLength = 10)
|
||||
{
|
||||
const maxPage = Math.ceil(items.length / pageLength);
|
||||
@ -259,6 +281,11 @@ class Util
|
||||
return result;
|
||||
}
|
||||
|
||||
static clone (object: object)
|
||||
{
|
||||
return JSON.parse(JSON.stringify(object));
|
||||
}
|
||||
|
||||
static wait (ms: number)
|
||||
{
|
||||
return this.delayFor(ms);
|
||||
|
Loading…
Reference in New Issue
Block a user