diff --git a/prisma/migrations/20240812145842_guild/migration.sql b/prisma/migrations/20240812145842_guild/migration.sql new file mode 100644 index 0000000..c7cbb34 --- /dev/null +++ b/prisma/migrations/20240812145842_guild/migration.sql @@ -0,0 +1,16 @@ +/* + Warnings: + + - You are about to drop the column `logChhannel` on the `server` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "server" DROP COLUMN "logChhannel", +ADD COLUMN "logChannel" TEXT NOT NULL DEFAULT 'none', +ALTER COLUMN "prefix" SET DEFAULT 'm?', +ALTER COLUMN "autoRole" SET DEFAULT 'none', +ALTER COLUMN "autoRoleChannel" SET DEFAULT 'none', +ALTER COLUMN "verificationRole" SET DEFAULT 'none', +ALTER COLUMN "verificationChannel" SET DEFAULT 'none', +ALTER COLUMN "levelsEnabled" SET DEFAULT false, +ALTER COLUMN "levelsMessage" SET DEFAULT 'Congratulations, {user}! You''ve leveled up to level {level}!'; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e93211e..6f9d4db 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -33,15 +33,15 @@ model guildLvl { model server { id String @id name String - ownerId String + ownerId String premium Boolean @default(false) premiumUntil DateTime? - logChhannel String - prefix String - autoRole String - autoRoleChannel String - verificationRole String - verificationChannel String - levelsEnabled Boolean - levelsMessage String + logChannel String @default("none") + prefix String @default("m?") + autoRole String @default("none") + autoRoleChannel String @default("none") + verificationRole String @default("none") + verificationChannel String @default("none") + levelsEnabled Boolean @default(false) + levelsMessage String @default("Congratulations, {user}! You've leveled up to level {level}!") } \ No newline at end of file diff --git a/src/commands/rank.ts b/src/commands/rank.ts new file mode 100644 index 0000000..fbfd530 --- /dev/null +++ b/src/commands/rank.ts @@ -0,0 +1,91 @@ +import { type CommandInteraction, AttachmentBuilder } from "discord.js"; +import { PrismaClient } from "@prisma/client"; +import { start } from "../api/server"; + +const prisma = new PrismaClient(); + +function getLevelFromXP(xp: number): number { + let level = 1; + let xpRequired = 50; // XP required for level 2 + let totalXP = 0; + + while (xp >= totalXP + xpRequired) { + totalXP += xpRequired; + xpRequired *= 2; // Double the XP required for the next level + level++; + } + + return xpRequired; +} + +function getXPfromLevel(level: number): number { + let xp = 0; + for (let i = 1; i < level; i++) { + xp += 50 * 2 ** (i - 1); + } + return xp; +} + +export default { + name: "rank", + description: "Check your rank!", + cooldown: 0, + isPremium: false, + botPermissions: [], + userPermissions: [], + validations: [], + slashCommand: { + enabled: true, + options: [], + }, + interactionRun: async (interaction: CommandInteraction) => { + const username = interaction.user.displayName; + const avatar = interaction.user.displayAvatarURL(); + const guildDB = await prisma.server.findUnique({ + where: { + id: interaction.guild?.id, + }, + }); + if (!guildDB?.levelsEnabled) { + return interaction.reply("Levels are disabled in this server"); + } + await interaction.reply(""); + const userDb = await prisma.user.findUnique({ + where: { + id: interaction.user.id, + }, + }); + const uid = userDb?.mdUID + const premium = userDb?.premium + const bg = userDb?.levelCard + + const lvlDB = await prisma.guildLvl.findMany({ + where: { + id: { startsWith: `${interaction.guild?.id}-` }, + }, + orderBy: { + xp: "desc", + }, + }); + + const rank = lvlDB.findIndex((x) => x.id === `${interaction.guild?.id}-${interaction.user.id}`) + 1; + + const userLevel = lvlDB.find((x) => x.id === `${interaction.guild?.id}-${interaction.user.id}`); + + const level = userLevel?.level; + const xp = userLevel?.xp; + + const xpRequired = getXPfromLevel(level + 1); + + const url = `${process.env.IMG_BACKEND}/level?level=${level}&username=${username}¤tXP=${xp}&totalXP=${xpRequired}&rank=${rank}&mdAcc=${uid !== "unlinked"}&premium=${premium}&avatar=${avatar}&bg=${bg}`; + + const response = await fetch(url); + + const buffer = Buffer.from(await response.arrayBuffer()); + + const attachment = new AttachmentBuilder(buffer,{ name: "rank.png" }); + + interaction.editReply({ content: "", files: [attachment] }); + }, +}; + diff --git a/src/handlers/initGuild.ts b/src/handlers/initGuild.ts index 059a1db..06357ec 100644 --- a/src/handlers/initGuild.ts +++ b/src/handlers/initGuild.ts @@ -14,6 +14,8 @@ export async function initGuild(guild: Guild) { await prisma.server.create({ data: { id: guild.id, + name: guild.name, + ownerId: guild.ownerId, }, }); } diff --git a/src/handlers/lvl.ts b/src/handlers/lvl.ts index 9bc617c..c76a47f 100644 --- a/src/handlers/lvl.ts +++ b/src/handlers/lvl.ts @@ -1,5 +1,6 @@ import { PrismaClient } from "@prisma/client"; import type { Message } from "discord.js"; +import { initGuild } from "./initGuild"; const prisma = new PrismaClient(); @@ -26,6 +27,21 @@ export async function handleLevel(message: Message) { }, }); + const guildDB = await prisma.server.findUnique({ + where: { + id: message.guild?.id, + }, + }); + + if (!guildDB) { + // biome-ignore lint/style/noNonNullAssertion: + await initGuild(message.guild!); + } + + if (!guildDB?.levelsEnabled) { + return console.log("Levels are disabled in this server"); + } + if (!lvlDB) { await prisma.guildLvl.create({ data: { @@ -37,6 +53,7 @@ export async function handleLevel(message: Message) { } const increment = Math.floor(Math.random() * 10) + 15; + const levelMessage = guildDB?.levelsMessage; if (lvlDB) { const newXP = lvlDB.xp + increment; @@ -44,9 +61,10 @@ export async function handleLevel(message: Message) { 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()).replace( /{level}/g, level.toString()); if (lvlDB.level < level) { message.channel.send( - `Congratulations ${message.author}, you have leveled up to level ${level}!`, + lvlMessage || `Congratulations ${message.author.toString()}! You have leveled up to level ${level}!`, ); } await prisma.guildLvl.update({