diff --git a/package.json b/package.json index e529140..0495681 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dotenv": "^10.0.0", "escape-string-regexp": "4.0.0", "humanize-duration": "^3.27.1", - "moment": "^2.29.2", + "moment": "^2.29.3", "mongodb": "^4.5.0", "node-fetch": "2", "object-hash": "^3.0.0", diff --git a/src/constants/FilterPresets.json b/src/constants/FilterPresets.json index ae80ab3..8983002 100644 --- a/src/constants/FilterPresets.json +++ b/src/constants/FilterPresets.json @@ -504,6 +504,7 @@ "blobsob", "poggers", "night", + "nights", "nightmare", "nightmares", "nightcore", diff --git a/src/localization/en_gb/commands/en_gb_moderation.lang b/src/localization/en_gb/commands/en_gb_moderation.lang index 4797079..4e61b76 100644 --- a/src/localization/en_gb/commands/en_gb_moderation.lang +++ b/src/localization/en_gb/commands/en_gb_moderation.lang @@ -331,41 +331,38 @@ If you absolutely need this, contact a bot developer in our support server. [COMMAND_CASE_HELP] View a specific case -[C_CASE_INVALID] -Case ID `{caseID}` is invalid! Make sure it's an integer above 0. - -[C_CASE_NOTFOUND] +[COMMAND_CASE_NOTFOUND] No case matching ID `{caseID}` was found. -[C_CASE_TITLE] +[COMMAND_CASE_TITLE] {emoji_book} Case **#{caseID}** -[C_CASE_TITLE_VERBOSE] +[COMMAND_CASE_TITLE_VERBOSE] {emoji_book} Case **#{caseID} (verbose)** -[C_CASE_CHANGES_TITLE] +[COMMAND_CASE_CHANGES_TITLE] {emoji_note} Changes to case **#{case}** -[C_CASE_CHANGES_NONE] +[COMMAND_CASE_CHANGES_NONE] No changes have been made to the case. -[C_CASE_CHANGE_BASE] +[COMMAND_CASE_CHANGE_BASE] **Timestamp:** {date} | {timeAgo} ago **Staff:** {staff} -[C_CASE_CHANGES_RESOLVE] +[COMMAND_CASE_CHANGES_RESOLVE] **Reason:** {reason} -[C_CASE_CHANGES_REASON] +[COMMAND_CASE_CHANGES_REASON] **Old reason:** {reason} -[C_CASE_CHANGES_DURATION] +[COMMAND_CASE_CHANGES_DURATION] **Old duration:** {duration} -[C_CASE_CHANGE_NOREASON] +[COMMAND_CASE_CHANGE_NOREASON] `No reason given` -[C_CASE_TEMPLATE] +[COMMAND_CASE_TEMPLATE] **[Jump to message (if available)](https://discord.com/channels/{guild}/{channel}/{message})** **Unique ID:** {uniqueID} @@ -375,7 +372,7 @@ No changes have been made to the case. **Staff:** {staff} **Changes:** {nrChanges} -[C_CASE_TEMPLATE_VERBOSE] +[COMMAND_CASE_TEMPLATE_VERBOSE] **[Jump to message (if available)](https://discord.com/channels/{guild}/{channel}/{message})** **Unique ID:** {uniqueID} **Type:** {type} @@ -386,34 +383,34 @@ No changes have been made to the case. **Amount of changes:** {nrChanges} **Changes:** {changes} -[C_CASE_MODPOINTS] +[COMMAND_CASE_MODPOINTS] **Points:** {points} **Expires:** {expires} -[C_CASE_REASON] +[COMMAND_CASE_REASON] **Reason:** ```{reason}``` -[C_CASE_SLOWMODE] +[COMMAND_CASE_SLOWMODE] **Slowmode:** {readable} -[C_CASE_SLOWMODE_VERBOSE] +[COMMAND_CASE_SLOWMODE_VERBOSE] **Slowmode:** {readable} ({seconds}) seconds -[C_CASE_TARGET_USER] +[COMMAND_CASE_TARGET_USER] **User:** {target} -[C_CASE_TARGET_CHANNEL] +[COMMAND_CASE_TARGET_CHANNEL] **Channel:** #{target} -[C_CASE_TARGET_USER_VERBOSE] +[COMMAND_CASE_TARGET_USER_VERBOSE] **User:** {target} ({targetID}) -[C_CASE_TARGET_CHANNEL_VERBOSE] +[COMMAND_CASE_TARGET_CHANNEL_VERBOSE] **Channel:** #{target} ({targetID}) -[C_CASE_LENGTH] +[COMMAND_CASE_LENGTH] **Length:** {time} -[C_CASE_LENGTH_VERBOSE] +[COMMAND_CASE_LENGTH_VERBOSE] **Length:** {time} ({inSeconds} seconds) \ No newline at end of file diff --git a/src/localization/en_gb/observers/en_gb_commandHandler.lang b/src/localization/en_gb/observers/en_gb_commandHandler.lang index efdbbec..dfe6965 100644 --- a/src/localization/en_gb/observers/en_gb_commandHandler.lang +++ b/src/localization/en_gb/observers/en_gb_commandHandler.lang @@ -32,6 +32,9 @@ The command option {option} requires a command or setting. [O_COMMANDHANDLER_DEPEDENCY] The command option **{option}** depends on another option: **{dependency}**. +[O_COMMANDHANDLER_REQUIRED] +Option **{option}** is required. + [O_COMMANDHANDLER_ERROR] An error occured while executing that command. It is recommended to contact a developer about this issue. diff --git a/src/structure/client/Resolver.js b/src/structure/client/Resolver.js index 41dd4c5..ab90452 100644 --- a/src/structure/client/Resolver.js +++ b/src/structure/client/Resolver.js @@ -1,4 +1,5 @@ const timestring = require('timestring'); +const moment = require('moment'); // eslint-disable-next-line no-unused-vars // const { DiscordClient } = require('../DiscordClient'); // eslint-disable-next-line no-unused-vars @@ -60,6 +61,20 @@ class Resolver { return time; } + resolveDate(string) { + let date = null; + const matches = string.match(/([0-9]{4}(?:\/|-)[0-9]{1,2}(?:\/|-)[0-9]{1,2})/gimu); //YYYY-MM-DD is REQUIRED. + if (matches && matches.length > 0) { + try { + const string = matches[0].replace(/\//giu, '-'); + date = moment(string); + } catch (error) { + return null; + } + } + return date; + } + /** * Resolve several user resolveables * diff --git a/src/structure/client/wrappers/InvokerWrapper.js b/src/structure/client/wrappers/InvokerWrapper.js index b41dc9c..2612bed 100644 --- a/src/structure/client/wrappers/InvokerWrapper.js +++ b/src/structure/client/wrappers/InvokerWrapper.js @@ -124,6 +124,8 @@ class InvokerWrapper { if (this.deferred && !this.replied) options._edit = true; + if(options.embed) options.embeds = [options.embed]; + if (options.embeds) options.embeds.forEach((embed) => { if (!embed.color) embed.color = 619452; }); diff --git a/src/structure/components/observers/CommandHandler.js b/src/structure/components/observers/CommandHandler.js index 161f0fb..22ed177 100644 --- a/src/structure/components/observers/CommandHandler.js +++ b/src/structure/components/observers/CommandHandler.js @@ -89,6 +89,9 @@ class CommandHandler extends Observer { }); if (response.dependency) content = invoker.format(`O_COMMANDHANDLER_DEPEDENCY`, { option: response.option.name, dependency: response.dependency }); + if (response.required) content = invoker.format(`O_COMMANDHANDLER_REQUIRED`, { + option: response.option.name + }); return invoker.reply({ content, emoji: 'failure', @@ -148,11 +151,6 @@ class CommandHandler extends Observer { const { subcommand } = interaction; - // Handled by inhibitors -- cleanup later - // if(!interaction.guild && command.guildOnly) { - // return interaction.reply({ index: 'O_COMMANDHANDLER_GUILDONLY', emoji: 'failure', ephemeral: true }); - // } - let error = null; const options = {}; // Find the option through the subcommand incase the subcommands have options with the same name @@ -189,6 +187,12 @@ class CommandHandler extends Observer { options[matched.name] = newOption; } + // Discord should handle this but just in case + const required = _subcommand.options.filter((opt) => opt.required); + for (const req of required) { + if(!options[req.name]) return { option: req, error: true, required: true }; + } + // Ensure option dependencies for (const opt of Object.values(options)) { let hasDep = false; @@ -344,6 +348,11 @@ class CommandHandler extends Observer { if(option.minimum !== undefined && float < option.minimum) return { error: true }; if(option.maximum !== undefined && float > option.maximum) return { error: true }; return { error: false, value: parseFloat(float) }; + }, + DATE: async (str) => { + const date = await this.client.resolver.resolveDate(str); + if (!date) return { error: true }; + return { error: false, value: date }; } }; diff --git a/src/structure/interfaces/CommandOption.js b/src/structure/interfaces/CommandOption.js index d7a01f2..32db73f 100644 --- a/src/structure/interfaces/CommandOption.js +++ b/src/structure/interfaces/CommandOption.js @@ -11,6 +11,7 @@ const Constants = { TEXT_CHANNELS: 3, VOICE_CHANNELS: 3, TIME: 3, // timestring + DATE: 3, COMPONENT: 3, STRING: 3, INTEGER: 4, @@ -50,6 +51,8 @@ class CommandOption { this.minimum = typeof options.minimum === 'number' ? options.minimum : undefined; //Used for INTEGER/NUMBER/FLOAT types. this.maximum = typeof options.maximum === 'number' ? options.maximum : undefined; + this.flag = true; // used with message based command options + this.value = undefined; this._rawValue = options._rawValue ?? null; //Raw value input from Discord. -- use ?? where the value is potentially false, otherwise we end up with false -> null diff --git a/yarn.lock b/yarn.lock index b4a39d5..45d2f9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2581,10 +2581,10 @@ minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== -moment@^2.29.2: - version "2.29.2" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4" - integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg== +moment@^2.29.3: + version "2.29.3" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3" + integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw== mongodb-connection-string-url@^2.5.2: version "2.5.2"