From f3bc4f9535804abc89aed9bfcdd56b3a4dfb6529 Mon Sep 17 00:00:00 2001 From: maamokun/MikanDev Date: Thu, 12 Dec 2024 22:05:20 +0900 Subject: [PATCH] feat: ratelimiting with redis instead of db --- prisma/schema.prisma | 7 +++---- src/commands/ping.ts | 2 +- src/handlers/lvl.ts | 10 ++++------ src/handlers/ratelimit.ts | 21 +++++++++++++++++++-- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e528ab3..6bd45c0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -23,10 +23,9 @@ model User { } model guildLvl { - id String @id - level Int - xp Int - cooldown DateTime @default(now()) + id String @id + level Int + xp Int } model server { diff --git a/src/commands/ping.ts b/src/commands/ping.ts index da98f23..3bacd80 100644 --- a/src/commands/ping.ts +++ b/src/commands/ping.ts @@ -14,7 +14,7 @@ export default { }, interactionRun: async (interaction: CommandInteraction) => { const ping = Math.abs(Math.round(interaction.client.ws.ping)); - await interaction.reply("Loading..."); + await interaction.reply(""); const roundtrip = Math.abs(Date.now() - interaction.createdTimestamp); interaction.editReply( `API Latency: ${ping}ms\nRoundtrip: ${roundtrip}ms`, diff --git a/src/handlers/lvl.ts b/src/handlers/lvl.ts index 757ac80..3053f7a 100644 --- a/src/handlers/lvl.ts +++ b/src/handlers/lvl.ts @@ -1,11 +1,10 @@ import { PrismaClient } from "@prisma/client"; +import { setMessageRatelimit, checkMessageRatelimit } from "./ratelimit.ts"; import type { Message } from "discord.js"; import { initGuild } from "./initGuild"; const prisma = new PrismaClient(); -const cooldown = 5000; - function getLevelFromXP(xp: number): number { let level = 1; let xpRequired = 50; // XP required for level 2 @@ -56,10 +55,9 @@ export async function handleLevel(message: Message) { const levelMessage = guildDB?.levelsMessage; if (lvlDB) { + const limited = await checkMessageRatelimit("msg", message); + if (limited) return; const newXP = lvlDB.xp + increment; - const currentCooldown = lvlDB.cooldown; - if (currentCooldown > new Date()) return; - const cooldownTime = new Date(Date.now() + cooldown); const level = getLevelFromXP(newXP); const lvlMessage = levelMessage ?.replace(/{user}/g, message.author.toString()) @@ -77,8 +75,8 @@ export async function handleLevel(message: Message) { data: { xp: newXP, level: level, - cooldown: cooldownTime, }, }); + setMessageRatelimit("msg", message); } } diff --git a/src/handlers/ratelimit.ts b/src/handlers/ratelimit.ts index 2288b04..4d63f87 100644 --- a/src/handlers/ratelimit.ts +++ b/src/handlers/ratelimit.ts @@ -1,12 +1,29 @@ import { createClient } from "redis"; -import { type CommandInteraction } from "discord.js"; +import { type CommandInteraction, type Message } from "discord.js"; const redis = createClient({ url: process.env.REDIS_URL, }); -export default function setRatelimit(type: string, interaction: CommandInteraction) { +export function setMessageRatelimit(type: string, message: Message) { if (type == "msg") { + redis.set( + `message:${message.guildId}:${message.author.id}`, + `${message.guildId}`, + { EX: 5 }, + ); + } +} +export async function checkMessageRatelimit(type: string, message: Message) { + if (type == "msg") { + const isLimited = await redis.get( + `message:${message.guildId}:${message.author.id}`, + ); + if (isLimited == `${message.guildId}`) { + return true; + } else { + return false; + } } }