From e3c0fc0f5a9e67bafe93e57a817aceb84c5f52d4 Mon Sep 17 00:00:00 2001 From: Micah Benac <66775276+OfficialSirH@users.noreply.github.com> Date: Thu, 11 Apr 2024 16:00:33 -0400 Subject: [PATCH] feat: remove love, pop, rate (#2615) --- src/commands/Fun/love.ts | 46 ------- src/commands/Fun/pop.ts | 118 ------------------ src/commands/Fun/rate.ts | 48 ------- src/languages/en-US/commands/fun.json | 87 +------------ .../i18n/languageKeys/keys/commands/Fun.ts | 18 --- src/lib/util/util.ts | 26 ---- tests/lib/util.test.ts | 22 ---- 7 files changed, 1 insertion(+), 364 deletions(-) delete mode 100644 src/commands/Fun/love.ts delete mode 100644 src/commands/Fun/pop.ts delete mode 100644 src/commands/Fun/rate.ts diff --git a/src/commands/Fun/love.ts b/src/commands/Fun/love.ts deleted file mode 100644 index e91155b8c58..00000000000 --- a/src/commands/Fun/love.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { LanguageKeys } from '#lib/i18n/languageKeys'; -import { SkyraCommand } from '#lib/structures'; -import { CdnUrls } from '#utils/constants'; -import { getColor, getDisplayAvatar, getTag } from '#utils/util'; -import { EmbedBuilder } from '@discordjs/builders'; -import { ApplyOptions } from '@sapphire/decorators'; -import { send } from '@sapphire/plugin-editable-commands'; -import { PermissionFlagsBits, type Message } from 'discord.js'; - -@ApplyOptions({ - description: LanguageKeys.Commands.Fun.LoveDescription, - detailedDescription: LanguageKeys.Commands.Fun.LoveExtended, - requiredClientPermissions: [PermissionFlagsBits.EmbedLinks] -}) -export class UserCommand extends SkyraCommand { - public override async messageRun(message: Message, args: SkyraCommand.Args) { - const user = await args.pick('userName'); - const isSelf = message.author.id === user.id; - const percentage = isSelf ? 1 : Math.random(); - const estimatedPercentage = Math.ceil(percentage * 100); - - let result: string; - if (estimatedPercentage < 45) { - result = args.t(LanguageKeys.Commands.Fun.LoveLess45); - } else if (estimatedPercentage < 75) { - result = args.t(LanguageKeys.Commands.Fun.LoveLess75); - } else if (estimatedPercentage < 100) { - result = args.t(LanguageKeys.Commands.Fun.LoveLess100); - } else { - result = args.t(isSelf ? LanguageKeys.Commands.Fun.LoveItself : LanguageKeys.Commands.Fun.Love100); - } - - const description = [ - `💗 **${getTag(user)}**`, - `💗 **${getTag(message.author)}**\n`, - `${estimatedPercentage}% \`[${'█'.repeat(Math.round(percentage * 40)).padEnd(40, '\u00A0')}]\`\n`, - `**${args.t(LanguageKeys.Commands.Fun.LoveResult)}**: ${result}` - ].join('\n'); - const embed = new EmbedBuilder() - .setColor(getColor(message)) - .setAuthor({ name: '❤ Love Meter ❤', iconURL: getDisplayAvatar(message.author, { size: 128 }) }) - .setThumbnail(CdnUrls.RevolvingHeartTwemoji) - .setDescription(description); - return send(message, { embeds: [embed] }); - } -} diff --git a/src/commands/Fun/pop.ts b/src/commands/Fun/pop.ts deleted file mode 100644 index 092d0b1a80d..00000000000 --- a/src/commands/Fun/pop.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { LanguageKeys } from '#lib/i18n/languageKeys'; -import { SkyraCommand } from '#lib/structures'; -import { minutes, seconds } from '#utils/common'; -import { Colors } from '#utils/constants'; -import { getTag, random } from '#utils/util'; -import { EmbedBuilder } from '@discordjs/builders'; -import { ApplyOptions } from '@sapphire/decorators'; -import type { Argument } from '@sapphire/framework'; -import { send } from '@sapphire/plugin-editable-commands'; -import type { Message } from 'discord.js'; - -@ApplyOptions({ - description: LanguageKeys.Commands.Fun.PopDescription, - detailedDescription: LanguageKeys.Commands.Fun.PopExtended, - options: ['x', 'width', 'y', 'height', 'l', 'length'] -}) -export class UserCommand extends SkyraCommand { - private readonly characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - - private get integer(): Argument { - return this.container.stores.get('arguments').get('integer') as Argument; - } - - public override async messageRun(message: Message, args: SkyraCommand.Args) { - const time = args.finished ? seconds(30) : await args.pick('timespan', { minimum: seconds(10), maximum: minutes(2) }); - const [width, height, length] = await Promise.all([ - this.parseOption(args, ['x', 'width'], 8, 1, 10), - this.parseOption(args, ['y', 'height'], 3, 1, 8), - this.parseOption(args, ['l', 'length'], 3, 3, 5) - ]); - - const pop = this.generatePop(length); - const solution = this.generateSolution(length); - - const board = [...this.generateBoard(width, height, pop, solution)].join('\n'); - const embed = new EmbedBuilder() - .setColor(Colors.Indigo) - .setTitle(args.t(LanguageKeys.Commands.Fun.PopTitle)) - .setDescription(board) - .setTimestamp(); - - await send(message, { embeds: [embed] }); - const winners = await message.channel.awaitMessages({ - filter: (message: Message) => !message.author.bot && message.content === solution, - max: 1, - time - }); - - if (winners.size === 0) { - embed.setColor(Colors.Red).setTitle(args.t(LanguageKeys.Commands.Fun.PopTitleLost)); - } else { - const value = getTag(winners.first()!.author); - embed.setColor(Colors.Green).setTitle(args.t(LanguageKeys.Commands.Fun.PopTitleWinner, { value })); - } - - embed.setDescription(board.replaceAll('||', '').replaceAll('``', '')); - await send(message, { embeds: [embed] }); - } - - private generatePop(length: number) { - if (length <= 3) return 'pop'; - return `p${'o'.repeat(length - 2)}p`; - } - - private generateSolution(length: number) { - let output = ''; - for (let i = 0; i < length; ++i) { - output += this.characters[random(this.characters.length)]; - } - - return output; - } - - private *generateBoard(width: number, height: number, pop: string, solution: string): IterableIterator { - const wrappedPop = `||\`${pop}\`||`; - const wrappedSolution = `||\`${solution}\`||`; - if (height === 0) { - return yield this.generateBoardLineWithSolution(wrappedPop, wrappedSolution, width); - } - - const solutionY = random(height); - const fullPops = this.generateBoardLineFullPops(wrappedPop, width); - - let y = 0; - for (; y < solutionY; ++y) yield fullPops; - - yield this.generateBoardLineWithSolution(wrappedPop, wrappedSolution, width); - ++y; - - for (; y < height; ++y) yield fullPops; - } - - private generateBoardLineFullPops(pop: string, width: number) { - return pop.repeat(width); - } - - private generateBoardLineWithSolution(pop: string, solution: string, width: number) { - const solutionX = random(width); - return pop.repeat(solutionX) + solution + pop.repeat(width - solutionX - 1); - } - - private async parseOption(args: SkyraCommand.Args, option: string[], defaultValue: number, minimum: number, maximum: number) { - const parameter = args.getOption(...option); - if (parameter === null) return defaultValue; - - const argument = this.integer; - const result = await argument.run(parameter, { - args, - argument, - command: this, - commandContext: args.commandContext, - message: args.message, - minimum, - maximum - }); - return result.unwrapRaw(); - } -} diff --git a/src/commands/Fun/rate.ts b/src/commands/Fun/rate.ts deleted file mode 100644 index b12b48b8d6c..00000000000 --- a/src/commands/Fun/rate.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { LanguageKeys } from '#lib/i18n/languageKeys'; -import { SkyraCommand } from '#lib/structures'; -import { OWNERS } from '#root/config'; -import { escapeMarkdown } from '#utils/External/escapeMarkdown'; -import { oneToTen } from '#utils/util'; -import { ApplyOptions } from '@sapphire/decorators'; -import { send } from '@sapphire/plugin-editable-commands'; -import type { Message } from 'discord.js'; - -@ApplyOptions({ - description: LanguageKeys.Commands.Fun.RateDescription, - detailedDescription: LanguageKeys.Commands.Fun.RateExtended -}) -export class UserCommand extends SkyraCommand { - private devRegex = new RegExp(`^(kyra|favna|${OWNERS.map((owner) => `<@!?${owner}>`).join('|')})$`, 'i'); - private botRegex = new RegExp(`^(you|yourself|skyra|<@!${process.env.CLIENT_ID}>)$`, 'i'); - - public override async messageRun(message: Message, args: SkyraCommand.Args) { - // Escape all markdown - let rateableThing = await args.rest('string'); - - let ratewaifu: string; - let rate: number; - - if (this.botRegex.test(rateableThing)) { - rate = 100; - [ratewaifu, rateableThing] = args.t(LanguageKeys.Commands.Fun.RateMyself); - } else if (this.devRegex.test(rateableThing)) { - rate = 101; - [ratewaifu, rateableThing] = args.t(LanguageKeys.Commands.Fun.RateMyOwners); - } else { - rateableThing = /^(myself|me)$/i.test(rateableThing) - ? message.author.displayName - : escapeMarkdown(rateableThing.replace(/\bmy\b/g, 'your')); - - const rng = Math.round(Math.random() * 100); - [ratewaifu, rate] = [oneToTen((rng / 10) | 0)!.emoji, rng]; - } - - const content = args.t(LanguageKeys.Commands.Fun.RateOutput, { - author: message.author.displayName, - userToRate: rateableThing, - rate, - emoji: ratewaifu - }); - return send(message, { content, allowedMentions: { users: [], roles: [] } }); - } -} diff --git a/src/languages/en-US/commands/fun.json b/src/languages/en-US/commands/fun.json index 1dde94b80a1..178e7522394 100644 --- a/src/languages/en-US/commands/fun.json +++ b/src/languages/en-US/commands/fun.json @@ -3,90 +3,5 @@ "escaperopeExtended": { "extendedHelp": "**Skyra** used **Escape Rope**." }, - "loveDescription": "Lovemeter, online!", - "loveExtended": { - "usages": [ - "User" - ], - "extendedHelp": "Hey! Wanna check the lovemeter? I know it's a ridiculous machine, but many humans love it! Don't be shy and try it!", - "explainedUsage": [ - [ - "user", - "The user to rate." - ] - ], - "examples": [ - "Skyra" - ] - }, - "popDescription": "Generates a board to pop, pop, pop, and pop.", - "popExtended": { - "usages": [ - "Duration", - "--x/--width", - "--y/--height", - "--length" - ], - "extendedHelp": "Allows you to generate a pop board where there is one non-pop word, which you have to find and send to the channel. For example, you must send `e60` from ||`pop`||||`e60`||||`pop`|| to win.", - "explainedUsage": [ - [ - "Duration", - "The amount of time I should allow you to find the non-pop, defaults to 30 seconds." - ], - [ - "--x/--width", - "The amount of columns the board should have, defaults to 8." - ], - [ - "--y/--height", - "The amount of rows the board should have, defaults to 3." - ], - [ - "--length", - "The length of the pops and the solution, defaults to 3." - ] - ], - "examples": [ - "15", - "--x=10", - "--y=5", - "--length=4" - ] - }, - "popTitle": "POP! Let the pops begin!", - "popTitleLost": "POP! Nobody got it in time!", - "popTitleWinner": "POP! We got a winner: {{value}}!", - "rateDescription": "Let bots have opinions and rate somebody.", - "rateExtended": { - "usages": [ - "Content" - ], - "extendedHelp": "Just because I am a bot doesn't mean I cannot rate you properly. I can grade you with a random number generator to ease the process. Okay okay, it's not fair, but I mean... I can also give you a 💯.", - "explainedUsage": [ - [ - "user", - "The user to rate." - ] - ], - "examples": [ - "Skyra", - "me" - ] - }, - "escaperopeOutput": "**{{user}}** used **Escape Rope**", - "loveLess45": "Try again next time...", - "loveLess75": "Good enough!", - "loveLess100": "Good match!", - "love100": "Perfect match!", - "loveItself": "You are a special creature and you should love yourself more than anyone <3", - "loveResult": "Result", - "rateOutput": "**{{author}}**, I would give **{{userToRate}}** a **{{rate}}**/100 {{emoji}}", - "rateMyself": [ - ". I love myself a lot 😊", - "myself" - ], - "rateOwners": [ - ". I love my developers a lot 🥰", - "my developers" - ] + "escaperopeOutput": "**{{user}}** used **Escape Rope**" } diff --git a/src/lib/i18n/languageKeys/keys/commands/Fun.ts b/src/lib/i18n/languageKeys/keys/commands/Fun.ts index 1c4d78f6921..b35d6a40d11 100644 --- a/src/lib/i18n/languageKeys/keys/commands/Fun.ts +++ b/src/lib/i18n/languageKeys/keys/commands/Fun.ts @@ -4,21 +4,3 @@ import { FT, T } from '#lib/types'; export const EscapeRopeDescription = T('commands/fun:escaperopeDescription'); export const EscapeRopeExtended = T('commands/fun:escaperopeExtended'); export const EscapeRopeOutput = FT<{ user: string }, string>('commands/fun:escaperopeOutput'); -export const Love100 = T('commands/fun:love100'); -export const LoveDescription = T('commands/fun:loveDescription'); -export const LoveExtended = T('commands/fun:loveExtended'); -export const LoveItself = T('commands/fun:loveItself'); -export const LoveLess100 = T('commands/fun:loveLess100'); -export const LoveLess45 = T('commands/fun:loveLess45'); -export const LoveLess75 = T('commands/fun:loveLess75'); -export const LoveResult = T('commands/fun:loveResult'); -export const PopDescription = T('commands/fun:popDescription'); -export const PopExtended = T('commands/fun:popExtended'); -export const PopTitle = T('commands/fun:popTitle'); -export const PopTitleLost = T('commands/fun:popTitleLost'); -export const PopTitleWinner = FT<{ value: string }, string>('commands/fun:popTitleWinner'); -export const RateDescription = T('commands/fun:rateDescription'); -export const RateExtended = T('commands/fun:rateExtended'); -export const RateMyOwners = T<[string, string]>('commands/fun:rateOwners'); -export const RateMyself = T<[string, string]>('commands/fun:rateMyself'); -export const RateOutput = FT<{ author: string; userToRate: string; rate: number; emoji: string }, string>('commands/fun:rateOutput'); diff --git a/src/lib/util/util.ts b/src/lib/util/util.ts index 48e53aeb900..21a7f0b81d9 100644 --- a/src/lib/util/util.ts +++ b/src/lib/util/util.ts @@ -23,20 +23,6 @@ import { } from 'discord.js'; import { first } from './common/iterators.js'; -const ONE_TO_TEN = new Map([ - [0, { emoji: '😪', color: 0x5b1100 }], - [1, { emoji: '😪', color: 0x5b1100 }], - [2, { emoji: '😫', color: 0xab1100 }], - [3, { emoji: '😔', color: 0xff2b00 }], - [4, { emoji: '😒', color: 0xff6100 }], - [5, { emoji: '😌', color: 0xff9c00 }], - [6, { emoji: '😕', color: 0xb4bf00 }], - [7, { emoji: '😬', color: 0x84fc00 }], - [8, { emoji: '🙂', color: 0x5bf700 }], - [9, { emoji: '😃', color: 0x24f700 }], - [10, { emoji: '😍', color: 0x51d4ef }] -]); - /** * Image extensions: * - bmp @@ -56,13 +42,6 @@ export const IMAGE_EXTENSION = /\.(bmp|jpe?g|png|gif|webp)$/i; */ export const MEDIA_EXTENSION = /\.(bmp|jpe?g|png|gifv?|web[pm]|wav|mp[34]|ogg)$/i; -export function oneToTen(level: number): UtilOneToTenEntry | undefined { - level |= 0; - if (level < 0) level = 0; - else if (level > 10) level = 10; - return ONE_TO_TEN.get(level); -} - /** * Get the content from a message. * @param message The Message instance to get the content from @@ -377,11 +356,6 @@ export function isUserSelf(userId: Snowflake) { return userId === process.env.CLIENT_ID; } -export interface UtilOneToTenEntry { - emoji: string; - color: number; -} - export interface MuteOptions { reason?: string; duration?: number | string | null; diff --git a/tests/lib/util.test.ts b/tests/lib/util.test.ts index 61964f6c232..979a4f3d4ea 100644 --- a/tests/lib/util.test.ts +++ b/tests/lib/util.test.ts @@ -31,28 +31,6 @@ describe('Utils', () => { }); }); - describe('oneToTen', () => { - test('GIVEN positive rational number THEN returns level 0 (😪)', () => { - expect(utils.oneToTen(2 / 3)).toStrictEqual({ color: 5968128, emoji: '😪' }); - }); - - test('GIVEN negative rational number THEN returns level 0 (😪)', () => { - expect(utils.oneToTen(-2 / 3)).toStrictEqual({ color: 5968128, emoji: '😪' }); - }); - - test('GIVEN positive integer number THEN returns level 2 (😫)', () => { - expect(utils.oneToTen(2)).toStrictEqual({ color: 11211008, emoji: '😫' }); - }); - - test('GIVEN negative integer number THEN returns level 0 (😪)', () => { - expect(utils.oneToTen(-5)).toStrictEqual({ color: 5968128, emoji: '😪' }); - }); - - test('GIVEN positive integer over 10 THEN returns level 10 (😍)', () => { - expect(utils.oneToTen(11)).toStrictEqual({ color: 5362927, emoji: '😍' }); - }); - }); - describe('extractDetailedMentions', () => { test('GIVEN empty string THEN returns empty results', () => { const result = utils.extractDetailedMentions('');