From 27391869a687ac28c3d33a60182326d8101817c5 Mon Sep 17 00:00:00 2001 From: GregTCLTK Date: Sun, 22 Oct 2023 21:45:33 +0200 Subject: [PATCH] fix partner command and change booster rewards --- db.ts | 70 +++++++++++++------------------------------ interactions.ts | 58 ++++++++++++++++++++---------------- main.ts | 79 +++++++++++-------------------------------------- 3 files changed, 69 insertions(+), 138 deletions(-) diff --git a/db.ts b/db.ts index 7d8cafa..b238cf5 100644 --- a/db.ts +++ b/db.ts @@ -1,4 +1,4 @@ -import { load } from "https://deno.land/std@0.201.0/dotenv/mod.ts"; +import { load } from "https://deno.land/std@0.204.0/dotenv/mod.ts"; import { MongoClient, ObjectId } from "https://deno.land/x/mongo@v0.32.0/mod.ts"; await load({ @@ -11,11 +11,11 @@ await mongoClient.connect(Deno.env.get("DB_URL")!); const db = mongoClient.database("one_bbn"); -export async function finduser(discordid: string) { +export async function findUser(discordId: string) { const user = await db.collection("users").findOne({ authentication: { $elemMatch: { - id: discordid, + id: discordId, type: "oauth", provider: "discord" } @@ -27,8 +27,8 @@ export async function finduser(discordid: string) { return user._id; } -export async function getCoins(discordid: string) { - const user = await finduser(discordid); +export async function getCoins(discordId: string) { + const user = await findUser(discordId); if (!user) return null; const access = await db.collection("@bbn/hosting/access").findOne({ owner: user @@ -37,9 +37,9 @@ export async function getCoins(discordid: string) { return access.coins; } -export async function setCoins(discordid: string, coins: number) { +export async function setCoins(discordId: string, coins: number) { // check if user exists - const user = await finduser(discordid); + const user = await findUser(discordId); if (!user) return null; // update user return await db.collection("@bbn/hosting/access").updateOne({ @@ -51,9 +51,9 @@ export async function setCoins(discordid: string, coins: number) { }); } -export async function addCoins(discordid: string, coins: number) { +export async function addCoins(discordId: string, coins: number) { // check if user exists - const user = await finduser(discordid); + const user = await findUser(discordId); if (!user) return null; // update user return await db.collection("@bbn/hosting/access").updateOne({ @@ -65,9 +65,9 @@ export async function addCoins(discordid: string, coins: number) { }); } -export async function removeCoins(discordid: string, coins: number) { +export async function removeCoins(discordId: string, coins: number) { // check if user exists - const user = await finduser(discordid); + const user = await findUser(discordId); if (!user) return null; // update user return await db.collection("@bbn/hosting/access").updateOne({ @@ -79,9 +79,9 @@ export async function removeCoins(discordid: string, coins: number) { }); } -export async function getLastDaily(discordid: string) { +export async function getLastDaily(discordId: string) { // check if user exists - const user = await finduser(discordid); + const user = await findUser(discordId); if (!user) return null; const access = await db.collection("@bbn/hosting/access").findOne({ owner: user @@ -90,8 +90,8 @@ export async function getLastDaily(discordid: string) { return access.lastDaily; } -export async function setLastDaily(discordid: string, lastDaily: number) { - const user = await finduser(discordid); +export async function setLastDaily(discordId: string, lastDaily: number) { + const user = await findUser(discordId); if (!user) return null; return await db.collection("@bbn/hosting/access").updateOne({ owner: user @@ -102,8 +102,8 @@ export async function setLastDaily(discordid: string, lastDaily: number) { }); } -export async function getServerURLs(discordid: string) { - const user = await finduser(discordid); +export async function getServerURLs(discordId: string) { + const user = await findUser(discordId); if (!user) return null; const servers = await db.collection("@bbn/hosting/servers").find({ user: user @@ -111,8 +111,8 @@ export async function getServerURLs(discordid: string) { return servers.map(server => `https://panel.bbn.one/server/${server.identifier}`).join("\n"); } -export async function lastLogin(discordid: string) { - const user = await finduser(discordid); +export async function lastLogin(discordId: string) { + const user = await findUser(discordId); if (!user) return null; const userevent = await db.collection("user-events").findOne({ type: "auth", @@ -128,43 +128,13 @@ export async function lastLogin(discordid: string) { platform: userevent.source.platform, platformVersion: userevent.source.platformVersion, legacyUserAgent: userevent.source.legacyUserAgent, - }, `${location.country ? String.fromCodePoint(...(location.country as string).toUpperCase().split('').map(char => 127397 + char.charCodeAt(0))) : ""} ${location.city} (${location.timezone})`, location.timezone ]; + }, location.bogon ? undefined : `${String.fromCodePoint(...(location.country as string).toUpperCase().split('').map(char => 127397 + char.charCodeAt(0)))} ${location.city} (${location.timezone})`, location.timezone ]; } export async function saveTranscript(transcript: any) { await db.collection("@bbn/bot/transcripts").insertOne(transcript); } -export async function addBoosterRewards(discordid: string) { - const user = await finduser(discordid); - if (!user) return null; - return await db.collection("@bbn/hosting/access").updateOne({ - owner: user - }, { - $inc: { - "limits.memory": 1500, - "limits.disk": 2000, - "limits.cpu": 100, - "limits.slots": 1 - } - }); -} - -export async function removeBoosterRewards(discordid: string) { - const user = await finduser(discordid); - if (!user) return null; - return await db.collection("@bbn/hosting/access").updateOne({ - owner: user - }, { - $inc: { - "limits.memory": -1500, - "limits.disk": -2000, - "limits.cpu": -100, - "limits.slots": -1 - } - }); -} - export async function addPartner(member: ObjectId, cpu: number, memory: number, disk: number, slots: number, invite: string) { await db.collection("@bbn/bot/partners").insertOne({ owner: member, diff --git a/interactions.ts b/interactions.ts index e674539..00ea3ef 100644 --- a/interactions.ts +++ b/interactions.ts @@ -1,9 +1,7 @@ import { ActionRowBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, ChannelType, EmbedBuilder, GuildMember, GuildMemberRoleManager, Interaction, Message, ModalBuilder, PermissionsBitField, TextChannel, TextInputBuilder, TextInputStyle, UserSelectMenuBuilder, VoiceChannel } from "npm:discord.js" -import { saveTranscript, finduser, lastLogin, getServerURLs, getLastDaily, addCoins, setLastDaily, getCoins, removeCoins, addPartner, removePartner, getPartners, getMemberFromBBNId } from "./db.ts"; -import { delay } from "https://deno.land/std@0.202.0/async/delay.ts"; +import { saveTranscript, findUser, lastLogin, getServerURLs, getLastDaily, addCoins, setLastDaily, getCoins, removeCoins, addPartner, removePartner, getPartners, getMemberFromBBNId } from "./db.ts"; export async function handleInteraction(interaction: Interaction) { - if (interaction.isButton()) { switch (interaction.customId) { case "lock": { @@ -37,33 +35,33 @@ export async function handleInteraction(interaction: Interaction) { content: `> We're closing your ticket. Please be patient. Ticket closed by ${interaction.user.tag}`, }); - // get all messages from channel const messages: Message[] = []; - // Create message pointer let message = await channel.messages .fetch({ limit: 1 }) - .then((messagePage: any) => (messagePage.size === 1 ? messagePage.at(0) : null)); + .then(messagePage => (messagePage.size === 1 ? messagePage.at(0) : null)); while (message) { await channel.messages .fetch({ limit: 100, before: message.id }) - .then((messagePage: any) => { - messagePage.forEach((msg: any) => messages.push(msg)); - // Update our message pointer to be the last message on the page of messages + .then(messagePage => { + messagePage.forEach(msg => messages.push(msg)); message = 0 < messagePage.size ? messagePage.at(messagePage.size - 1) : null; }); } let member; try { member = await interaction.guild?.members.fetch(channel.name.split("-")[ 1 ]); + // deno-lint-ignore no-empty } catch (_) { } + // deno-lint-ignore no-explicit-any const transcript: any = { messages: [], closed: `Ticket closed by ${interaction.user.tag}`, with: `${member ? member.user.tag : "Unknown User"} (${channel.name.split("-")[ 1 ]})` }; for (const message of messages.values()) { + // deno-lint-ignore no-explicit-any const obj: any = { author: message.author.tag, authorid: message.author.id, @@ -72,7 +70,7 @@ export async function handleInteraction(interaction: Interaction) { avatar: message.author.displayAvatarURL(), }; if (message.attachments.size > 0) { - obj.attachments = message.attachments.map((a: any) => a.url); + obj.attachments = message.attachments.map(a => a.url); } if (message.embeds.length > 0) { obj.embed = message.embeds[ 0 ].toJSON(); @@ -106,7 +104,7 @@ export async function handleInteraction(interaction: Interaction) { if (interaction.isModalSubmit()) { try { const ticket_user_reason = interaction.fields.getTextInputValue("ticket_reason"); - const dbuser = await finduser(interaction.user.id); + const dbuser = await findUser(interaction.user.id); const ticketname = `ticket-${interaction.user.id}`; const possibleChannel = interaction.guild?.channels.cache.find(ch => ch.name === ticketname); if (possibleChannel) { @@ -146,13 +144,12 @@ export async function handleInteraction(interaction: Interaction) { value: `\`\`\`${JSON.stringify(login[ 0 ] ?? "none")}\`\`\``, }); embed.setFooter({ - text: login[ 1 ] ?? "No Login" as string, + text: login[ 1 ] ?? "No Login", iconURL: interaction.user.displayAvatarURL(), }) embed.setTimestamp(new Date(new Date().toLocaleString('en-US', { timeZone: login[ 2 ] ?? "UTC" }))) } - setTimeout(() => { ch.permissionOverwrites.create(interaction.user.id, { "ViewChannel": true @@ -176,6 +173,10 @@ export async function handleInteraction(interaction: Interaction) { }); } catch (e) { + await interaction.reply({ + content: `> Error while creating your ticket. Please try again later.`, + ephemeral: true, + }); console.error(e); } } @@ -225,7 +226,6 @@ export async function handleInteraction(interaction: Interaction) { .setCustomId("create_ticket") .setStyle(ButtonStyle.Success) .setLabel("Create Ticket") - ]); await ticketChannel.send({ embeds: [ embed ], @@ -268,19 +268,17 @@ export async function handleInteraction(interaction: Interaction) { } if (interaction.commandName == "daily") { - // Check if the user has already claimed their daily reward getLastDaily(interaction.user.id).then(async result => { if (result !== null) { - // Calculate the time difference in hours const timeDiff = (Date.now() - result) / 3600000; if (timeDiff < 24) { - // Calculate the number of hours return interaction.reply(`You have already claimed your daily reward. Please wait ${Math.ceil(24 - timeDiff)} hours before claiming again.`); } } - // Give the user their daily reward - const reward = 10 + (Math.floor(Math.random() * 10)); + let reward = 10 + (Math.floor(Math.random() * 10)); + if ((await interaction.guild!.members.fetch(interaction.user.id)).premiumSince) + reward *= 10; const res = await addCoins(interaction.user.id, reward); if (res === null) { interaction.reply("We couldn't find your account. Please [log in via Discord here]()"); @@ -292,7 +290,6 @@ export async function handleInteraction(interaction: Interaction) { } if (interaction.commandName == "balance") { - // Retrieve the user's balance from the database const possiblemember = interaction.options.getMentionable("user", false); let { id } = interaction.user; if (possiblemember) { @@ -300,8 +297,7 @@ export async function handleInteraction(interaction: Interaction) { interaction.reply("You do not have permission to view other users' balances."); return; } - const member = possiblemember as GuildMember; - id = member.id; + id = (possiblemember as GuildMember).id; } await getCoins(id).then(result => { if (result === null) { @@ -349,7 +345,7 @@ export async function handleInteraction(interaction: Interaction) { } const member = interaction.options.getMentionable("user", true) as GuildMember; - const dbmember = await finduser(member.id); + const dbmember = await findUser(member.id); if (!dbmember) { interaction.reply("We couldn't find an bbn account in our database"); return; @@ -371,13 +367,14 @@ export async function handleInteraction(interaction: Interaction) { addPartner(dbmember, cpu, ram, storage, slots, invite.code); interaction.reply(`Added ${member.user.username} as a partner.\n\nFollowing resources got added: \nCPU: ${cpu} \nMemory: ${ram} \nStorage: ${storage} \nSlots: ${slots} \nInvite code: https://discord.gg/${invite.code}`); } + if (interaction.commandName == "removepartner") { if (!interaction.memberPermissions?.has(PermissionsBitField.Flags.Administrator)) { interaction.reply("You do not have permission to remove partners."); return; } const member = interaction.options.getMentionable("user", true) as GuildMember; - const dbmember = await finduser(member.id); + const dbmember = await findUser(member.id); if (!dbmember) { interaction.reply("We couldn't find an bbn account in our database"); return; @@ -385,6 +382,7 @@ export async function handleInteraction(interaction: Interaction) { removePartner(dbmember); interaction.reply(`Removed ${member.user.username} as a partner.`); } + if (interaction.commandName == "partners") { if (!interaction.memberPermissions?.has(PermissionsBitField.Flags.Administrator)) { interaction.reply("You do not have permission to list partners."); @@ -392,8 +390,16 @@ export async function handleInteraction(interaction: Interaction) { } let out = "Owner - CPU, RAM, Storage, Slots, Invitecode, last invite, uses\n"; const partners = await getPartners(); - out += (await Promise.all(partners.map(async (partner: any) => `<@${(await interaction.guild?.members.fetch(await getMemberFromBBNId(partner.owner))) ? (await interaction.guild?.members.fetch(await getMemberFromBBNId(partner.owner)))!.user.id : "USER QUIT"}> (${partner.owner}) - ${partner.cpu}, ${partner.memory}, ${partner.disk}, ${partner.slots}, ${partner.invite}, , ${(await interaction.guild?.invites.fetch(partner.invite))?.uses}`))).join("\n"); - interaction.reply(out); + + await interaction.deferReply(); + + out += (await Promise.all(partners.map(async partner => + `<@${await getMemberFromBBNId(partner.owner)}> \`${partner.owner}\` - \`${partner.cpu}\` \`${partner.memory}\` \`${partner.disk}\` \`${partner.slots}\` \`${partner.invite}\` \`${(await interaction.guild?.invites.fetch(partner.invite)!).uses}\``))).join("\n"); + + const embed = new EmbedBuilder() + .setTitle(`Partners`) + .setDescription(out) + interaction.editReply({ embeds: [ embed ] }); } } diff --git a/main.ts b/main.ts index 3a9b925..8579296 100644 --- a/main.ts +++ b/main.ts @@ -1,8 +1,8 @@ -import { ActivityType, CategoryChannel, Client, Message, MessageType, REST, Routes } from 'npm:discord.js' +import { ActivityType, CategoryChannel, Client, REST, Routes, TextChannel } from 'npm:discord.js' import { handleShowcaseMessage, sendBanMessage, sendLeaveMessage, sendPrivateMessage, sendVoice } from './helper.ts'; import { handleInteraction } from "./interactions.ts"; import { PartnerManager } from './partner.ts'; -import { addBoosterRewards, finduser, removeBoosterRewards } from "./db.ts"; +import { findUser } from "./db.ts"; const client = new Client({ intents: 3276799 }); @@ -147,17 +147,10 @@ client.on("ready", () => { const partnerManager = new PartnerManager(client); -client.on('inviteCreate', async () => { - await partnerManager.cacheInvites(); -}); - -client.on('inviteDelete', async () => { - await partnerManager.cacheInvites(); -}); +client.on('inviteCreate', async () => await partnerManager.cacheInvites()); +client.on('inviteDelete', async () => await partnerManager.cacheInvites()); -client.on('guildMemberAdd', async (member) => { - await partnerManager.onMember(member, 'join'); -}); +client.on('guildMemberAdd', async (member) => await partnerManager.onMember(member, 'join')); client.on('guildBanAdd', (ban) => sendBanMessage(ban, true)) client.on('guildBanRemove', (ban) => sendBanMessage(ban, false)) @@ -169,70 +162,32 @@ client.on('messageCreate', (message) => handleShowcaseMessage(message)); client.on('voiceStateUpdate', sendVoice); client.on('interactionCreate', (interaction) => handleInteraction(interaction)); -client.on('messageCreate', async (message) => { - if (message.type === MessageType.GuildBoost && message.channelId === Deno.env.get("LOG_CHANNEL")! && message.guild) { - const dbuser = await finduser(message.author.id); + +client.on('guildMemberUpdate', async (oldMember, newMember) => { + if (oldMember.premiumSince !== newMember.premiumSince && newMember.premiumSince) { + const dbuser = await findUser(newMember.id); if (dbuser) { - await addBoosterRewards(message.author.id); - await message.channel.send(`Added booster rewards for https://discord.com/channels/${message.guildId}/${message.channelId}/${message.id}`); + (await newMember.guild.channels.fetch(Deno.env.get("GENERAL_CHANNEL")!) as TextChannel).send(`<@${newMember.id}> will now get a 10x /daily reward for the duration of their boost!`); } else { - if (message.guild.channels.cache.find((channel) => channel.name === `link-${message.author.id}`)) { - await message.channel.send(`https://discord.com/channels/${message.guildId}/${message.channelId}/${message.id} already has a link channel`); + if (newMember.guild.channels.cache.find((channel) => channel.name === `link-${newMember.id}`)) return; - } - const channel = await message.guild.channels.create({ - name: `link-${message.author.id}`, - parent: await message.guild.channels.fetch(Deno.env.get("LINK_CATEGORY")!) as CategoryChannel, + + const channel = await newMember.guild.channels.create({ + name: `link-${newMember.id}`, + parent: await newMember.guild.channels.fetch(Deno.env.get("LINK_CATEGORY")!) as CategoryChannel, permissionOverwrites: [ { - id: message.author.id, + id: newMember.id, allow: [ 'ViewChannel' ] } ] }); - await channel?.send({ content: `<@${message.author.id}> Looks like you just boosted the server! Unfortunately, you are not linked to your BBN account yet. Please send your Email address to this channel to link your account. Our Team will respond as soon as possible.`, allowedMentions: { users: [ message.author.id ] } }); - await message.channel.send(`https://discord.com/channels/${message.guildId}/${message.channelId}/${message.id} created channel https://discord.com/channels/${message.guildId}/${channel?.id} to link`); + await channel.send({ content: `<@${newMember.id}> Looks like you just boosted the server! Unfortunately, you are not linked to your BBN account yet. Please send your Email address to this channel to link your account. Our Team will respond as soon as possible.`, allowedMentions: { users: [ newMember.id ] } }); } } }) -async function checkBoosts() { - console.log('Checking boosts'); - const guild = await client.guilds.fetch(Deno.env.get("GUILD_ID")!); - const log_channel = await guild.channels.fetch(Deno.env.get("LOG_CHANNEL")!); - if (!log_channel?.isTextBased()) return; - // Get all messages in the last 32 days - const messages: Message[] = []; - let scan = true; - let last_id = await log_channel.messages.fetch({ limit: 1 }).then((msgs) => msgs.first()!.id); - while (scan) { - const msgs = await log_channel.messages.fetch({ limit: 100, before: last_id }); - last_id = msgs.last()!.id; - if (msgs.size === 0 || msgs.last()!.createdAt.getTime() < Date.now() - 33 * 24 * 60 * 60 * 1000) { - scan = false; - } else { - msgs.forEach((msg: Message) => { - if (msg.type === MessageType.GuildBoost && msg.createdAt.getTime() < Date.now() - 30 * 24 * 60 * 60 * 1000) { - messages.push(msg); - } - }) - } - } - messages.forEach(async (msg) => { - const user = await finduser(msg.author.id); - if (user) { - await removeBoosterRewards(msg.author.id); - await msg.channel.send(`Removed booster rewards for https://discord.com/channels/${guild.id}/${msg.channelId}/${msg.id}`); - } else { - await msg.channel.send({ content: 'User not found, <@757969277063266407> please check this user https://discord.com/channels/${guild.id}/${msg.channelId}/${msg.id}', allowedMentions: { roles: [ '757969277063266407' ] } }); - } - }); -} - -setInterval(checkBoosts, 24 * 60 * 60 * 1000); - client.login(Deno.env.get("TOKEN")!).then(() => { console.log('Logged in'); - checkBoosts(); partnerManager.cacheInvites(); }); \ No newline at end of file