diff --git a/config.json b/config.json index 4f7d2e8..af88da2 100644 --- a/config.json +++ b/config.json @@ -27,6 +27,7 @@ }, "discord": { "default": "🌹 SkyStats 🌹 ~ Hypixel And SkyBlock Bot", + "farming_weight": "🌹 SkyStats 🌹 ~ Elite Farmers Weight Calculation", "support": "🌹 SkyStats 🌹 ~ Support", "defaultbetter": "🌹 SkyStats 🌹 ~ run [/help] for help", "owner": "🌹 Axle#9171 🌹", diff --git a/ecosystem.config.js b/ecosystem.config.js index 536f5b0..80433bf 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -4,6 +4,7 @@ module.exports = { name: "SkyStats-Production", script: "./start/production_start.js", instances: 1, + mode: "fork", autorestart: true, watch: true, max_memory_restart: "4G", diff --git a/package.json b/package.json index 1b7093a..1e0f506 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "skystats", - "version": "1.4.5", + "version": "1.4.6", "description": "A Hypixel Skyblock Metrics Bot For Discord.", - "changelog": "SkyStats Nightly Build minor changes to how getNetworth() is called, and backend changes to getSkyHelper(), networthEmbed(), networthCommand", + "changelog": "SkyStats Nightly\n1.4.6 Weight command beta\n+farmingWeight()\n+senitherWeight()\n+Sanitization for both\n+weightCommand.js\nNote that weight command is not finished and this is only the framework\n**TODO** Buttons and switching", "main": "index.js", "scripts": { "start": "pm2 start --only SkyStats-Production", @@ -49,6 +49,7 @@ "prettier": "3.0.3", "prismarine-nbt": "^2.4.0", "rss-parser": "^3.13.0", + "senitherweight": "^1.0.8", "skyhelper-networth": "^1.18.0", "util": "^0.12.5" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6bbdfb..c2d9e38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,6 +90,9 @@ dependencies: rss-parser: specifier: ^3.13.0 version: 3.13.0 + senitherweight: + specifier: ^1.0.8 + version: 1.0.8 skyhelper-networth: specifier: ^1.18.0 version: 1.18.0 @@ -315,6 +318,12 @@ packages: engines: {node: '>=v14.0.0', npm: '>=7.0.0'} dev: false + /@types/klaw@3.0.6: + resolution: {integrity: sha512-BErW5TrTz4nzt/c3VRGf0Bug4JyQJ1o807F4mAfXfvOzFZ8SKgFeHJ0T28Y1KtqlMEB+cUgN7S7CsyQDQ/qxqg==} + dependencies: + '@types/node': 20.10.5 + dev: false + /@types/node@20.10.5: resolution: {integrity: sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==} dependencies: @@ -936,6 +945,12 @@ packages: graceful-fs: 4.2.11 dev: false + /klaw@3.0.0: + resolution: {integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==} + dependencies: + graceful-fs: 4.2.11 + dev: false + /lilyweight@2.7.2: resolution: {integrity: sha512-jJJfiq4HFok1iiZ4d77synztcAQQd1FgTYA9/eREPILP99DiyFH8FSDUH1Z8WXAHzeWBrP0xZ5tFceQHVUJ0Xw==} dependencies: @@ -1286,6 +1301,13 @@ packages: lru-cache: 6.0.0 dev: false + /senitherweight@1.0.8: + resolution: {integrity: sha512-ZI9TZqemHKKMckY2RG70vj+NKOUZeR8lPGuMTe9O/R1KgS3nXP+pCc5CwJif/L8VZmIDSIuDM+F719fGJAWhVg==} + dependencies: + '@types/klaw': 3.0.6 + klaw: 3.0.0 + dev: false + /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: false diff --git a/src/contracts/weight/senitherWeight.js b/src/contracts/weight/senitherWeight.js deleted file mode 100644 index 29ca31a..0000000 --- a/src/contracts/weight/senitherWeight.js +++ /dev/null @@ -1,9 +0,0 @@ -const { calculateTotalSenitherWeight,} = require("../../../API/stats/senitherWeight"); -const { getLatestProfile } = require("../../../API/functions/getLatestProfile"); - -async function getSenitherWeight(username) { - const profile = await getLatestProfile(username); - return await calculateTotalSenitherWeight(profile.profile); -} - -module.exports = { getSenitherWeight }; diff --git a/src/discord/CommandHandler.js b/src/discord/CommandHandler.js index c192b17..4768829 100644 --- a/src/discord/CommandHandler.js +++ b/src/discord/CommandHandler.js @@ -24,4 +24,4 @@ class CommandHandler { } } -module.exports = CommandHandler \ No newline at end of file +module.exports = CommandHandler diff --git a/src/discord/commands/embeds/networthEmbed.js b/src/discord/commands/embeds/networthEmbed.js index bd65482..fbf379c 100644 --- a/src/discord/commands/embeds/networthEmbed.js +++ b/src/discord/commands/embeds/networthEmbed.js @@ -20,7 +20,7 @@ const EMOJIS = { PERSONAL_VAULT_ICON: `<:item_2654:1061455349338615859>`, MISC_ICON: `<:wheat:1059664236038590584>`, } -async function networthEmbed(embed_ID, uuid, profileid, username, profilename, networth) { +async function networthEmbed(embed_ID, uuid, username, profilename, networth) { if (embed_ID === `totals_embed`) { return { color: 0xffa600, diff --git a/src/discord/commands/embeds/weightEmbed.js b/src/discord/commands/embeds/weightEmbed.js new file mode 100644 index 0000000..ace9d9f --- /dev/null +++ b/src/discord/commands/embeds/weightEmbed.js @@ -0,0 +1,56 @@ +const config = require(`../../../../config.json`); +const { addNotation, addCommas } = require(`../../../contracts/helperFunctions`); +const messages = config.messages.discord; +const { farmingWeight } = require("../../../functions/get/getWeight") +const EMOJIS = { + PURSE_ICON: `<:Purse:1059997956784279562>`, + BOOSTER_COOKIE_ICON: `<:BOOSTER_COOKIE:1070126116846710865>`, + SOULBOUND_ICON: `<:IRON_INGOT:1070126498616455328>`, + BANK_ICON: `<:Bank:1059664677606531173>`, + SACK_ICON: `<:sacks:1059664698095710388>`, + ARMOR_ICON: `<:DIAMOND_CHESTPLATE:1061454753357377586>`, + EQUIPMENT_ICON: `<:Iron_Chestplate:1061454825839144970>`, + WARDROBE_ICON: `<:ARMOR_STAND:1061454861071298620>`, + INVENTORY_ICON: `<:CHEST:1061454902049656993>`, + ENDER_CHEST_ICON: `<:ENDER_CHEST:1061454947931140106>`, + SWORD_ICON: "<:sword:1060045450897539122>", + STORAGE_ICON: `<:storage:1059664802701656224>`, + MUSEUM_ICON: `<:LEATHER_CHESTPLATE:1134874048048935012>`, + PET_ICON: `<:Spawn_Null:1061455273224577024>`, + BONUS_ICON: "<:carrot:1072129687427498012>", + ACCESSORY_BAG_ICON: `<:HEGEMONY_ARTIFACT:1061455309983461486>`, + PERSONAL_VAULT_ICON: `<:item_2654:1061455349338615859>`, + MISC_ICON: `<:wheat:1059664236038590584>`, + } + +async function farmingWeight_Embed(uuid, username, profilename) { + const weight = await farmingWeight(uuid) + return { + color: 0xffa600, + title: `Farming Weight for ${username} on ${profilename}`, + URL: `https://sky.shiiyu.moe/stats/${uuid}`, + description: `${EMOJIS.SWORD_ICON} Total Weight: **${weight.total_weight}**`, + fields: [ + { + name: `${EMOJIS.MISC_ICON} Crops`, + value: weight.items.crop_weight, + inline: false, + }, + { + name: `${EMOJIS.BONUS_ICON} Bonuses`, + value: weight.items.bonus_weight, + inline: false, + }, + ], + thumbnail: { + url: `https://api.mineatar.io/body/full/${uuid}` + }, + footer: { + text: `${messages.farming_weight}`, + iconURL: `${messages.icon}`, + }, + } + } + + +module.exports = { farmingWeight_Embed }; \ No newline at end of file diff --git a/src/discord/commands/publishCommand.js b/src/discord/commands/publishCommand.js index 185999e..acc597e 100644 --- a/src/discord/commands/publishCommand.js +++ b/src/discord/commands/publishCommand.js @@ -25,7 +25,7 @@ module.exports = { execute: async (interaction, client) => { const oldVersion = packageJson.version; const guild = await client.guilds.fetch('1058272411247714425'); - const changelogValue = interaction.options.getString('changelog'); + const changelogValue = interaction.options.getString('changelog').replaceAll('\\n', '\n'); const versionValue = interaction.options.getString('version'); if (guild.members.cache.get(interaction.user.id)?.roles.cache.has(config.discord.developmentRole)) { diff --git a/src/discord/commands/testCommand.js b/src/discord/commands/testCommand.js index 2171b24..703115d 100644 --- a/src/discord/commands/testCommand.js +++ b/src/discord/commands/testCommand.js @@ -1,30 +1,39 @@ const { ActionRowBuilder, StringSelectMenuBuilder, ButtonBuilder, ButtonStyle } = require('discord.js'); - +const { handleError } = require("../../functions/handle/handleError"); +const { farmingWeight } = require("../../functions/get/getWeight") +const { senitherWeight } = require("../../functions/get/getWeight") +const { farmingWeight_Embed } = require('./embeds/weightEmbed') +const { calculateTotalSenitherWeight } = require('../../functions/constants/senitherWeight') +const { getPlayer } = require("../../functions/get/getPlayer") module.exports = { name: 'test', description: 'bot credits', options: [ { - name: 'message', + name: 'name', description: 'message to send', type: 3, - required: true + required: false }, ], - execute: async (interaction, client) => { - const message = interaction.options.getString('message').replaceAll('\\n', '\n') - const channel = client.channels.cache.get(`1113587258117861378`); - const embed = { - title: `Wtf`, - color: 0xffa600, - description: (`${message}`), - timestamp: new Date().toISOString(), - }; - await channel.send({ embeds: [ embed ] }) - await interaction.reply({content: "Your report has been shared with the developers, do not delete this message.", ephemeral: false}) + execute: async (interaction, client, InteractionCreate) => { + const id = interaction.user.id; + const { uuid2, username, profilename, profileid, playerData, profileData, profile, error } = await getPlayer( + id, + interaction.options.getString("name") + ); + // console.log(await calculateTotalSenitherWeight(profile)) + console.log(await senitherWeight(profile)) + await interaction.deferReply(); - }, -}; \ No newline at end of file + try { + await interaction.editReply({content: "Success."}) + } catch (error) { + const errorEmbed = handleError(error); + await interaction.editReply({ embeds: [errorEmbed] }); + } + } + } \ No newline at end of file diff --git a/src/discord/commands/weightCommand.js b/src/discord/commands/weightCommand.js index 9a9939a..80cfc13 100644 --- a/src/discord/commands/weightCommand.js +++ b/src/discord/commands/weightCommand.js @@ -1,5 +1,8 @@ const config = require("../../../config.json"); const { handleError } = require("../../functions/handle/handleError"); +const { farmingWeight } = require("../../functions/get/getWeight") +const { farmingWeight_Embed } = require('./embeds/weightEmbed') +const { getPlayer } = require("../../functions/get/getPlayer") const messages = config.messages.discord module.exports = { @@ -7,16 +10,22 @@ module.exports = { description: 'Shows a players weight', options: [ { - name: "notes", + name: "player", description: "meow", type: 3, required: false, }, ], execute: async (interaction, client, InteractionCreate) => { + const id = interaction.user.id; + const { uuid2, username, profilename, profileid, error } = await getPlayer( + id, + interaction.options.getString("name") + ); + const farming_weight_embed = await farmingWeight_Embed(uuid2, username, profilename) await interaction.deferReply(); try { - await interaction.editReply({ content: `dont test me :anger:` }) + await interaction.editReply({ embeds: [farming_weight_embed ] }) } catch (error) { const errorEmbed = handleError(error); await interaction.editReply({ embeds: [errorEmbed] }); diff --git a/src/functions/constants/senitherWeight.js b/src/functions/constants/senitherWeight.js index 5e19288..636d915 100644 --- a/src/functions/constants/senitherWeight.js +++ b/src/functions/constants/senitherWeight.js @@ -107,13 +107,12 @@ async function calculateTotalSenitherWeight(profile) { }, dungeons: { catacombs: await calculateSenitherWeight('catacombs', (calcSkill('dungeoneering', profile.dungeons?.dungeon_types?.catacombs?.experience || 0)).levelWithProgress, profile.dungeons?.dungeon_types?.catacombs?.experience || 0), - classes: { - healer: await calculateSenitherWeight('healer', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.healer?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.healer?.experience || 0), - mage: await calculateSenitherWeight('mage', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.mage?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.mage?.experience || 0), - berserk: await calculateSenitherWeight('berserk', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.berserk?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.berserk?.experience || 0), - archer: await calculateSenitherWeight('archer', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.archer?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.archer?.experience || 0), - tank: await calculateSenitherWeight('tank', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.tank?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.tank?.experience || 0), - } + healer: await calculateSenitherWeight('healer', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.healer?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.healer?.experience || 0), + mage: await calculateSenitherWeight('mage', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.mage?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.mage?.experience || 0), + berserk: await calculateSenitherWeight('berserk', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.berserk?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.berserk?.experience || 0), + archer: await calculateSenitherWeight('archer', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.archer?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.archer?.experience || 0), + tank: await calculateSenitherWeight('tank', (calcSkill('dungeoneering', profile.dungeons?.player_classes?.tank?.experience || 0)).levelWithProgress, profile.dungeons?.player_classes?.tank?.experience || 0), + } } return weight diff --git a/src/functions/get/getWeight.js b/src/functions/get/getWeight.js new file mode 100644 index 0000000..fa7f9ec --- /dev/null +++ b/src/functions/get/getWeight.js @@ -0,0 +1,98 @@ +const axios = require('axios'); +require("dotenv").config(); +const apiKey = process.env.KEY; +const fs = require('fs'); +const { addCommas, addNotation } = require("../../contracts/helperFunctions"); +const { calculateTotalSenitherWeight } = require('../../functions/constants/senitherWeight') + +async function farmingWeight(uuid) { +const response = await axios.get(`https://api.elitebot.dev/Weight/${uuid}/selected`); +function sanitizeCropWeight(obj) { + let sanitized = ''; + let crops = []; + for (let crop in obj.cropWeight) { + let weight = obj.cropWeight[crop]; + weight = weight.toFixed(1); + crops.push({ name: crop, weight: weight }); + } + crops.sort((a, b) => b.weight - a.weight); + for (let crop of crops) { + sanitized += `→ ${crop.name}: **${addCommas(crop.weight)}**\n`; + } + return sanitized; +} +function sanitizeBonusWeight(obj) { + let sanitized = ''; + + for (let crop in obj.bonusWeight) { + let weight = obj.bonusWeight[crop]; + weight = weight.toFixed(1); + sanitized += `→ ${crop}: **${addCommas(weight)}**\n`; + } + + return sanitized; +} + return { + total_weight: addCommas(response.data.totalWeight.toFixed(1)), + items: { + crop_weight: sanitizeCropWeight(response.data), + bonus_weight: sanitizeBonusWeight(response.data), + } + } +} + +async function senitherWeight(profile) { + const weight = await calculateTotalSenitherWeight(profile); + function sanitizeData(obj) { + let totalWeight = 0; + let totalOverflow = 0; + let skills = obj.skills; + let slayers = obj.slayer; + let dungeons = obj.dungeons; + // Extract and sum skill, slayer, and dungeon weights and overflows + for (let skill in skills) { + totalWeight += skills[skill].weight; + totalOverflow += skills[skill].weight_overflow; + } + + for (let slayer in slayers) { + totalWeight += slayers[slayer].weight; + totalOverflow += slayers[slayer].weight_overflow; + } + + for (let dungeon in dungeons) { + totalWeight += dungeons[dungeon].weight; + totalOverflow += dungeons[dungeon].weight_overflow; + } + + // Sanitize data + let sanitizedObj = { + totalWeight: totalWeight.toFixed(1), + totalOverflow: totalOverflow.toFixed(1), + skills: formatData(skills), + slayers: formatData(slayers), + dungeons: formatData(dungeons) + }; + return sanitizedObj; + } + function formatData(data) { + let formattedData = ''; + for (let key in data) { + if (data[key].weight !== undefined && data[key].weight_overflow !== undefined) { + let weight = data[key].weight.toFixed(1); + let overflow = data[key].weight_overflow.toFixed(1); + if (overflow !== '0.0') { + formattedData += `→ ${key}: **${addCommas(weight)}** (+${addCommas(overflow)})\n`; + } else { + formattedData += `→ ${key}: **${addCommas(weight)}**\n`; + } + } + } + return formattedData; + } +const data = sanitizeData(weight) + + return data; +} + +module.exports = { farmingWeight, senitherWeight } \ No newline at end of file diff --git a/src/functions/handle/handleDatabase.js b/src/functions/handle/handleDatabase.js index 5866fa5..79ee1d4 100644 --- a/src/functions/handle/handleDatabase.js +++ b/src/functions/handle/handleDatabase.js @@ -56,4 +56,4 @@ module.exports = { connect, getDb, disconnect -}; \ No newline at end of file +};