diff --git a/packages/bot/src/components/CommandWrapper.tsx b/packages/bot/src/components/CommandWrapper.tsx index e03c2efca..c3fce00fa 100644 --- a/packages/bot/src/components/CommandWrapper.tsx +++ b/packages/bot/src/components/CommandWrapper.tsx @@ -17,7 +17,6 @@ export function CommandWrapper({ children, fat }: CommandWrapperProps) { width: '100%', color: theme.colors.textHighContrast, position: 'relative', - background: theme.colors.appBackground1, }} > {children} diff --git a/packages/bot/src/core/discord/normalizeInteractionReturnable.ts b/packages/bot/src/core/discord/normalizeInteractionReturnable.ts deleted file mode 100644 index 3996f98bf..000000000 --- a/packages/bot/src/core/discord/normalizeInteractionReturnable.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { - ActionRowBuilder, - AttachmentBuilder, - ButtonBuilder, - EmbedBuilder, - InteractionEditReplyOptions, - InteractionReplyOptions, - MessageEditOptions, -} from 'discord.js'; -import { InteractionReturnable } from '../../events/interactionCreate'; -import { Writeable } from '../../types/writable'; -import { jsxToPngThreaded } from '../blitzkit/jsxToPngThreaded'; -import { RenderConfiguration } from '../blitzkit/renderConfiguration'; - -export async function normalizeInteractionReturnable( - returnable: InteractionReturnable, -) { - const images: [number, Buffer][] = []; - const reply: InteractionEditReplyOptions & - InteractionReplyOptions & - MessageEditOptions = {}; - const awaitedReturnable = await returnable; - const normalizedReturnable = Array.isArray(awaitedReturnable) - ? awaitedReturnable - : [awaitedReturnable]; - let renderConfiguration = new RenderConfiguration(); - - await Promise.all( - normalizedReturnable.map(async (item, index) => { - if (typeof item === 'string') { - reply.content = item; - } else if (item instanceof EmbedBuilder) { - if (!reply.embeds) reply.embeds = []; - (reply.embeds as Writeable).push(item); - } else if (item instanceof ButtonBuilder) { - if (!reply.components) - reply.components = [new ActionRowBuilder()]; - (reply.components[0] as ActionRowBuilder).addComponents( - item, - ); - } else if (item instanceof AttachmentBuilder) { - if (!reply.files) reply.files = []; - (reply.files as Writeable).push(item); - } else if (item instanceof RenderConfiguration) { - renderConfiguration = item; - } else if (item === null) { - return; - } else { - const image = await jsxToPngThreaded(item, renderConfiguration); - images.push([index, image]); - } - }), - ); - - if (images.length > 0) { - images.sort(([a], [b]) => b - a); - if (!reply.files) reply.files = []; - images.forEach(([, image]) => - (reply.files as Writeable)?.push(image), - ); - } - - return reply; -} diff --git a/packages/bot/src/core/discord/normalizeInteractionReturnable.tsx b/packages/bot/src/core/discord/normalizeInteractionReturnable.tsx new file mode 100644 index 000000000..015ec3160 --- /dev/null +++ b/packages/bot/src/core/discord/normalizeInteractionReturnable.tsx @@ -0,0 +1,148 @@ +import { imgur } from '@blitzkit/core'; +import { + ActionRowBuilder, + AttachmentBuilder, + ButtonBuilder, + EmbedBuilder, + InteractionEditReplyOptions, + InteractionReplyOptions, + MessageEditOptions, +} from 'discord.js'; +import { InteractionReturnable } from '../../events/interactionCreate'; +import { FunnyType } from '../../events/interactionCreate/handlers/chatInputCommand'; +import { theme } from '../../stitches.config'; +import { Writeable } from '../../types/writable'; +import { jsxToPngThreaded } from '../blitzkit/jsxToPngThreaded'; +import { RenderConfiguration } from '../blitzkit/renderConfiguration'; + +export async function normalizeInteractionReturnable( + returnable: InteractionReturnable, + funnyType?: FunnyType, +) { + const images: [number, Buffer][] = []; + const reply: InteractionEditReplyOptions & + InteractionReplyOptions & + MessageEditOptions = {}; + const awaitedReturnable = await returnable; + const normalizedReturnable = Array.isArray(awaitedReturnable) + ? awaitedReturnable + : [awaitedReturnable]; + let renderConfiguration = new RenderConfiguration(); + + await Promise.all( + normalizedReturnable.map(async (item, index) => { + if (typeof item === 'string') { + reply.content = item; + } else if (item instanceof EmbedBuilder) { + if (!reply.embeds) reply.embeds = []; + (reply.embeds as Writeable).push(item); + } else if (item instanceof ButtonBuilder) { + if (!reply.components) + reply.components = [new ActionRowBuilder()]; + (reply.components[0] as ActionRowBuilder).addComponents( + item, + ); + } else if (item instanceof AttachmentBuilder) { + if (!reply.files) reply.files = []; + (reply.files as Writeable).push(item); + } else if (item instanceof RenderConfiguration) { + renderConfiguration = item; + } else if (item === null) { + return; + } else { + let jsx = item; + + switch (funnyType) { + case FunnyType.Rude: { + jsx = ( +
+ {item} +
+ ); + + break; + } + + case FunnyType.Weird: { + const angle = (Math.random() * 2 - 1) * 10; + jsx = ( +
+ {item} + + + + + + +
+ ); + + break; + } + } + + const image = await jsxToPngThreaded(jsx, renderConfiguration); + images.push([index, image]); + } + }), + ); + + if (images.length > 0) { + images.sort(([a], [b]) => b - a); + if (!reply.files) reply.files = []; + images.forEach(([, image]) => + (reply.files as Writeable)?.push(image), + ); + } + + return reply; +} diff --git a/packages/bot/src/events/interactionCreate/handlers/chatInputCommand.ts b/packages/bot/src/events/interactionCreate/handlers/chatInputCommand.ts index a6228f3f2..2c879b4de 100644 --- a/packages/bot/src/events/interactionCreate/handlers/chatInputCommand.ts +++ b/packages/bot/src/events/interactionCreate/handlers/chatInputCommand.ts @@ -1,3 +1,4 @@ +import { isFunny } from '@blitzkit/core'; import { ActionRowBuilder, AttachmentBuilder, @@ -16,14 +17,64 @@ import { psa } from '../../../core/discord/psa'; import { translator } from '../../../core/localization/translator'; import { Writeable } from '../../../types/writable'; +export enum FunnyType { + Rude, + Weird, +} + +const funnyResponses: Record = { + [FunnyType.Rude]: [ + "Your decisions were calculated, but, man, you're bad at math.", + 'Hey man, have you considered like not lacking?', + 'Let me guess... it was your team?', + 'Confidence is key. Unfortunately, you lost the lock.', + "When I said live green, I wasn't talking about your winrate.", + 'Viewing your stats, publicly? You must be brave.', + 'Bold of you to assume the numbers have gone up since yesterday.', + "I'd give you advice, but I don't think you'd understand.", + "I didn't believe in negative numbers until I saw your stats.", + 'I was gaining hope in humanity. Something changed today.', + "I've seen potatoes aim better than you.", + "I've seen sloths move faster than your tank.", + ], + [FunnyType.Weird]: [ + 'yeah daddy, use me more', + 'uwu, hewe are your swaws... uwu', + 'hehehehe it tickles', + 'yeeeeeeeeeeeeahhhhhh that hits the spot', + 'ooooh yesss my circuits are starting to hurt yeeeeeeee', + ], +}; + export async function handleChatInputCommand( interaction: ChatInputCommandInteraction, ) { + let funny: FunnyType | undefined = undefined; + await interaction.deferReply(); + + if (isFunny) { + const funniesLength = Object.keys(funnyResponses).length; + + if (import.meta.env.DEBUG_FUNNY === 'true') { + // in debug mode, just pick a random one + funny = Math.floor(Math.random() * funniesLength); + } else { + const id = BigInt(interaction.user.id); + funny = Number(id % BigInt(funniesLength)); + } + + const responses = funnyResponses[funny]; + const responseIndex = Math.floor(Math.random() * responses.length); + const response = `### ${responses[responseIndex]}`; + const waitTime = response.length * 45; + + await interaction.editReply(response); + await new Promise((resolve) => setTimeout(resolve, waitTime)); + } + const awaitedCommands = await commands; const registry = awaitedCommands[interaction.commandName]; - await interaction.deferReply(); - try { const returnable = await registry.handler(interaction); @@ -41,7 +92,7 @@ export async function handleChatInputCommand( let index = 0; for (const chunk of chunks.filter((chunk) => chunk.length > 0)) { - const reply = await normalizeInteractionReturnable(chunk); + const reply = await normalizeInteractionReturnable(chunk, funny); if ( psa.data && diff --git a/packages/bot/src/main.ts b/packages/bot/src/main.ts index bf447527e..3ff5f1116 100644 --- a/packages/bot/src/main.ts +++ b/packages/bot/src/main.ts @@ -1,4 +1,4 @@ -import { assertSecret } from '@blitzkit/core'; +import { assertSecret, isFunny } from '@blitzkit/core'; import { ActivityType, ShardingManager } from 'discord.js'; import { discoveredIdsDefinitions, @@ -45,7 +45,7 @@ const interval = setInterval(async () => { const usernames = awaitedDiscoveredIdsDefinitions.count; manager.broadcastEval( - (client, { servers, users, channels, tanks, usernames }) => { + async (client, { servers, users, channels, tanks, usernames }) => { const bios = [ `Living in ${servers.toLocaleString()} servers`, `Serving ${users.toLocaleString()} users`, @@ -62,6 +62,13 @@ const interval = setInterval(async () => { }, ], }); + + for (const guild of client.guilds.cache.values()) { + try { + const botMember = await guild.members.fetch(client.user.id); + await botMember.setNickname(isFunny ? "No One's Kit" : 'BlitzKit'); + } catch {} + } }, { context: { servers, channels, users, tanks, usernames } }, ); diff --git a/packages/core/src/blitzkit/index.ts b/packages/core/src/blitzkit/index.ts index 983def4d7..e51b3b8d4 100644 --- a/packages/core/src/blitzkit/index.ts +++ b/packages/core/src/blitzkit/index.ts @@ -44,6 +44,7 @@ export * from './unwrapBlitzkitResponse'; export * from './votes'; // export * from './withCORSProxy'; export * from './createDefaultProvisions'; +export * from './isFunny'; export * from './metaSortTank'; export * from './romanize'; export * from './youtubers'; diff --git a/packages/core/src/blitzkit/isFunny.ts b/packages/core/src/blitzkit/isFunny.ts new file mode 100644 index 000000000..430b2990a --- /dev/null +++ b/packages/core/src/blitzkit/isFunny.ts @@ -0,0 +1,4 @@ +const now = new Date(); +export const isFunny = + (now.getMonth() === 3 && now.getDate() === 1) || + import.meta.env.DEBUG_FUNNY === 'true';