diff --git a/.eslintrc b/.eslintrc index 14958224..d79c1601 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,7 +12,8 @@ "globals": { "bot": true, "client": true, - "guild": true + "guild": true, + "imgurUrl": true }, "rules": { "curly": ["warn", "multi-line", "consistent"], diff --git a/src/discord/DiscordManager.js b/src/discord/DiscordManager.js index e25413c8..c246c787 100644 --- a/src/discord/DiscordManager.js +++ b/src/discord/DiscordManager.js @@ -22,6 +22,7 @@ class DiscordManager extends CommunicationBridge { } connect() { + global.imgurUrl = ""; global.client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent], }); @@ -108,6 +109,10 @@ class DiscordManager extends CommunicationBridge { Logger.errorMessage(`Channel ${chat} not found!`); return; } + if (username === bot.username && message.endsWith("Check Discord Bridge for image.")) { + channel.send(imgurUrl); + imgurUrl = ""; + } switch (mode) { case "bot": diff --git a/src/discord/commands/blacklistCommand.js b/src/discord/commands/blacklistCommand.js index 3e6854b1..ccae4366 100644 --- a/src/discord/commands/blacklistCommand.js +++ b/src/discord/commands/blacklistCommand.js @@ -3,7 +3,7 @@ const { SuccessEmbed } = require("../../contracts/embedHandler.js"); module.exports = { name: "blacklist", - description: "Demotes the given user by one guild rank.", + description: "Ignore add or remove the given user.", moderatorOnly: true, requiresBot: true, options: [ diff --git a/src/discord/commands/updateCommand.js b/src/discord/commands/updateCommand.js index 6957bcc9..4745aeff 100644 --- a/src/discord/commands/updateCommand.js +++ b/src/discord/commands/updateCommand.js @@ -27,6 +27,7 @@ module.exports = { if (user !== undefined) { interaction.user = user; + interaction.member = await guild.members.fetch(interaction.user.id); } if (!interaction.member) { @@ -47,7 +48,7 @@ module.exports = { } if (interaction.member.roles.cache.has(role)) { - interaction.member.roles.remove(role, "Updated Roles"); + await interaction.member.roles.remove(role, "Updated Roles"); } } @@ -57,7 +58,7 @@ module.exports = { } if (!interaction.member.roles.cache.has(config.verification.verifiedRole)) { - interaction.member.roles.add(config.verification.verifiedRole, "Updated Roles"); + await interaction.member.roles.add(config.verification.verifiedRole, "Updated Roles"); } const [hypixelGuild, player] = await Promise.all([ @@ -71,29 +72,29 @@ module.exports = { const guildMember = hypixelGuild.members.find((m) => m.uuid === uuid); if (guildMember) { - interaction.member.roles.add(config.verification.guildMemberRole, "Updated Roles"); + await interaction.member.roles.add(config.verification.guildMemberRole, "Updated Roles"); if (config.verification.ranks.length > 0 && guildMember.rank) { const rank = config.verification.ranks.find((r) => r.name.toLowerCase() == guildMember.rank.toLowerCase()); if (rank) { for (const role of config.verification.ranks) { if (interaction.member.roles.cache.has(role.role)) { - interaction.member.roles.remove(role.role, "Updated Roles"); + await interaction.member.roles.remove(role.role, "Updated Roles"); } } - interaction.member.roles.add(rank.role, "Updated Roles"); + await interaction.member.roles.add(rank.role, "Updated Roles"); } } } else { if (interaction.member.roles.cache.has(config.verification.guildMemberRole)) { - interaction.member.roles.remove(config.verification.guildMemberRole, "Updated Roles"); + await interaction.member.roles.remove(config.verification.guildMemberRole, "Updated Roles"); } if (config.verification.ranks.length > 0) { for (const role of config.verification.ranks) { if (interaction.member.roles.cache.has(role.role)) { - interaction.member.roles.remove(role.role, "Updated Roles"); + await interaction.member.roles.remove(role.role, "Updated Roles"); } } } @@ -130,14 +131,14 @@ module.exports = { skywarsWLRatio: player.stats.skywars.WLRatio, skywarsPlayedGames: player.stats.skywars.playedGames, - duelsTitle: player.stats.duels.division, - duelsKills: player.stats.duels.kills, - duelsDeaths: player.stats.duels.deaths, - duelsKDRatio: player.stats.duels.KDRatio, - duelsWins: player.stats.duels.wins, - duelsLosses: player.stats.duels.losses, - duelsWLRatio: player.stats.duels.WLRatio, - duelsPlayedGames: player.stats.duels.playedGames, + duelsTitle: player.stats?.duels?.division || 0, + duelsKills: player.stats?.duels?.kills || 0, + duelsDeaths: player.stats?.duels?.deaths || 0, + duelsKDRatio: player.stats?.duels?.KDRatio || 0, + duelsWins: player.stats?.duels?.wins || 0, + duelsLosses: player.stats?.duels?.losses || 0, + duelsWLRatio: player.stats?.duels?.WLRatio || 0, + duelsPlayedGames: player.stats?.duels?.playedGames || 0, level: player.level, rank: player.rank, diff --git a/src/discord/commands/verifyCommand.js b/src/discord/commands/verifyCommand.js index ae4113b0..f4f0e575 100644 --- a/src/discord/commands/verifyCommand.js +++ b/src/discord/commands/verifyCommand.js @@ -63,7 +63,7 @@ module.exports = { throw new HypixelDiscordChatBridgeError("This player does not have a Discord linked."); } - if (discordUsername !== interaction.user.username && bypassChecks !== true) { + if (discordUsername?.toLowerCase() != interaction.user.username && bypassChecks !== true) { throw new HypixelDiscordChatBridgeError( `The player '${nickname}' has linked their Discord account to a different account ('${discordUsername}').`, ); @@ -93,7 +93,7 @@ module.exports = { throw new HypixelDiscordChatBridgeError("The update command does not exist. Please contact an administrator."); } - await updateRolesCommand.execute(interaction); + await updateRolesCommand.execute(interaction, user); } catch (error) { errorMessage(error); // eslint-disable-next-line no-ex-assign diff --git a/src/minecraft/commands/auctionHouseCommand.js b/src/minecraft/commands/auctionHouseCommand.js index 036be1ac..31a48b3d 100644 --- a/src/minecraft/commands/auctionHouseCommand.js +++ b/src/minecraft/commands/auctionHouseCommand.js @@ -91,7 +91,8 @@ class AuctionHouseCommand extends minecraftCommand { string += string === "" ? upload.data.link : " | " + upload.data.link; } - this.send(`/gc ${`${username}'s Active Auctions: ${string}`}`); + imgurUrl = string; + this.send(`/gc $${username}'s Active Auctions: Check Discord Bridge for image.`); } catch (error) { errorMessage(error); this.send(`/gc [ERROR] ${error}`); diff --git a/src/minecraft/commands/chickenCommand.js b/src/minecraft/commands/chickenCommand.js index 39c9f49e..433f6843 100644 --- a/src/minecraft/commands/chickenCommand.js +++ b/src/minecraft/commands/chickenCommand.js @@ -25,7 +25,8 @@ class ChickenCommand extends minecraftCommand { throw "An error occured while fetching the image. Please try again later."; } - this.send(`/gc Funny Chicken: ${data.url}`); + imgurUrl = data.url; + this.send('/gc Funny Chicken: Check Discord Bridge for image.'); } catch (error) { this.send(`/gc [ERROR] ${error ?? "Something went wrong.."}`); } diff --git a/src/minecraft/commands/dinosaurCommand.js b/src/minecraft/commands/dinosaurCommand.js index b21507a9..0da5106c 100644 --- a/src/minecraft/commands/dinosaurCommand.js +++ b/src/minecraft/commands/dinosaurCommand.js @@ -25,7 +25,8 @@ class DinosaurCommand extends minecraftCommand { throw "An error occured while fetching the image. Please try again later."; } - this.send(`/gc Funny dino: ${data.url}`); + imgurUrl = data.url; + this.send("/gc Funny dino: Check Discord Bridge for image."); } catch (error) { this.send(`/gc [ERROR] ${error ?? "Something went wrong.."}`); } diff --git a/src/minecraft/commands/duckCommand.js b/src/minecraft/commands/duckCommand.js index 27fc8f6d..c6ec3360 100644 --- a/src/minecraft/commands/duckCommand.js +++ b/src/minecraft/commands/duckCommand.js @@ -24,8 +24,8 @@ class DuckCommand extends minecraftCommand { // eslint-disable-next-line no-throw-literal throw "An error occured while fetching the image. Please try again later."; } - - this.send(`/gc Funny Duck: ${data.url}`); + imgurUrl = data.url; + this.send("/gc Funny Duck: Check Discord Bridge for image."); } catch (error) { this.send(`/gc [ERROR] ${error ?? "Something went wrong.."}`); } diff --git a/src/minecraft/commands/kittyCommand.js b/src/minecraft/commands/kittyCommand.js index ef555e0f..e8ce290d 100644 --- a/src/minecraft/commands/kittyCommand.js +++ b/src/minecraft/commands/kittyCommand.js @@ -24,7 +24,8 @@ class KittyCommand extends minecraftCommand { const link = data[0].url; const upload = await uploadImage(link); - this.send(`/gc Cute Cat: ${upload.data.link}`); + imgurUrl = upload.data.link; + this.send(`/gc Cute Cat: Check Discord Bridge for image.`); } catch (error) { this.send(`/gc [ERROR] ${error ?? "Something went wrong.."}`); } diff --git a/src/minecraft/commands/mayorCommand.js b/src/minecraft/commands/mayorCommand.js index 72141835..046e8cf8 100644 --- a/src/minecraft/commands/mayorCommand.js +++ b/src/minecraft/commands/mayorCommand.js @@ -1,4 +1,5 @@ const minecraftCommand = require("../../contracts/minecraftCommand.js"); +const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const axios = require("axios"); class MayorCommand extends minecraftCommand { @@ -21,19 +22,18 @@ class MayorCommand extends minecraftCommand { throw "Request to Hypixel API failed. Please try again!"; } - if (data.current.candidates.length === 0) { - this.send( - `/gc [MAYOR] ${data.mayor.name} is the current mayor of Skyblock! Perks: ${data.mayor.perks - .map((perk) => perk.name) - .join(", ")}`, - ); - } else { - const currentLeader = data.current.candidates.sort((a, b) => b.votes - a.votes)[0]; - this.send( - `/gc [MAYOR] ${data.mayor.name} is the current mayor of Skyblock! Perks: ${data.mayor.perks - .map((perk) => perk.name) - .join(", ")} | Current Election: ${currentLeader.name}`, - ); + this.send( + `/gc [MAYOR] ${data.mayor.name} is the current mayor of Skyblock! Perks: ${data.mayor.perks + .map((perk) => perk.name) + .join(", ")}, Minister Perk: ${data.mayor.minister.perk.name}`, + ); + await delay(500); + if (data.mayor.election.candidates.length > 0) { + const currentLeader = data.mayor.election.candidates.sort((a, b) => (b.votes || 0) - (a.votes || 0))[0]; + if (!currentLeader) return; + const totalVotes = data.mayor.election.candidates.reduce((total, candidate) => total + (candidate.votes || 0), 0); + const percentage = ((currentLeader.votes || 0) / totalVotes) * 100; + this.send(`/gc [MAYOR] Current Election: ${currentLeader.name} has ${percentage.toFixed(2)}% of the votes.`); } } catch (error) { this.send(`/gc [ERROR] ${error}`); diff --git a/src/minecraft/commands/picketCommand.js b/src/minecraft/commands/picketCommand.js index 960d4612..c912bbe0 100644 --- a/src/minecraft/commands/picketCommand.js +++ b/src/minecraft/commands/picketCommand.js @@ -25,7 +25,8 @@ class PicketCommand extends minecraftCommand { throw "An error occured while fetching the image. Please try again later."; } - this.send(`/gc PICKET!! ${data.url}`); + imgurUrl = data.url; + this.send("/gc PICKET!! Check Discord Bridge for image."); } catch (error) { this.send(`/gc [ERROR] ${error ?? "Something went wrong.."}`); } diff --git a/src/minecraft/commands/rabbitCommand.js b/src/minecraft/commands/rabbitCommand.js index 5514d90c..b12cd6e5 100644 --- a/src/minecraft/commands/rabbitCommand.js +++ b/src/minecraft/commands/rabbitCommand.js @@ -24,8 +24,8 @@ class RabbitCommand extends minecraftCommand { // eslint-disable-next-line no-throw-literal throw "An error occured while fetching the image. Please try again later."; } - - this.send(`/gc Funny rabbit: ${data.url}`); + imgurUrl = data.url; + this.send("/gc Funny rabbit: Check Discord Bridge for image."); } catch (error) { this.send(`/gc [ERROR] ${error ?? "Something went wrong.."}`); } diff --git a/src/minecraft/commands/raccoonCommand.js b/src/minecraft/commands/raccoonCommand.js index 143849ba..c000c8e4 100644 --- a/src/minecraft/commands/raccoonCommand.js +++ b/src/minecraft/commands/raccoonCommand.js @@ -25,7 +25,8 @@ class RaccoonCommand extends minecraftCommand { throw "An error occured while fetching the image. Please try again later."; } - this.send(`/gc Funny Raccoon: ${data.url}`); + imgurUrl = data.url; + this.send("/gc Funny Raccoon: Check Discord Bridge for image."); } catch (error) { this.send(`/gc [ERROR] ${error ?? "Something went wrong.."}`); } diff --git a/src/minecraft/commands/renderArmorCommand.js b/src/minecraft/commands/renderArmorCommand.js index d76a8739..bcc6d35f 100644 --- a/src/minecraft/commands/renderArmorCommand.js +++ b/src/minecraft/commands/renderArmorCommand.js @@ -59,7 +59,8 @@ class ArmorCommand extends minecraftCommand { response += response.split(" | ").length == 4 ? link : `${link} | `; } - this.send(`/gc ${username}'s Armor: ${response}`); + imgurUrl = response; + this.send(`/gc ${username}'s Armor: Check Discord Bridge for image.`); } catch (error) { this.send(`/gc [ERROR] ${error}`); } diff --git a/src/minecraft/commands/renderEquipmentCommand.js b/src/minecraft/commands/renderEquipmentCommand.js index 7186186d..d5e9ad35 100644 --- a/src/minecraft/commands/renderEquipmentCommand.js +++ b/src/minecraft/commands/renderEquipmentCommand.js @@ -54,7 +54,8 @@ class EquipmentCommand extends minecraftCommand { response += response.split(" | ").length == 4 ? link : `${link} | `; } - this.send(`/gc ${username}'s Equipment: ${response}`); + imgurUrl = response; + this.send(`/gc ${username}'s Equipment: Check Discord Bridge for image.`); } catch (error) { this.send(`/gc [ERROR] ${error}`); } diff --git a/src/minecraft/commands/renderItemsCommand.js b/src/minecraft/commands/renderItemsCommand.js index 5d99d366..ab157d42 100644 --- a/src/minecraft/commands/renderItemsCommand.js +++ b/src/minecraft/commands/renderItemsCommand.js @@ -73,7 +73,8 @@ class RenderCommand extends minecraftCommand { const upload = await uploadImage(renderedItem); - this.send(`/gc ${username}'s item at slot ${itemNumber}: ${upload.data.link}`); + imgurUrl = upload.data.link; + this.send(`/gc ${username}'s item at slot ${itemNumber}: Check Discord Bridge for image.`); } catch (error) { errorMessage(error); this.send(`/gc [ERROR] ${error}`); diff --git a/src/minecraft/commands/renderPetCommand.js b/src/minecraft/commands/renderPetCommand.js index cbe67486..54412380 100644 --- a/src/minecraft/commands/renderPetCommand.js +++ b/src/minecraft/commands/renderPetCommand.js @@ -47,7 +47,8 @@ class RenderCommand extends minecraftCommand { const upload = await uploadImage(renderedItem); - return this.send(`/gc ${username}'s Active Pet: ${upload.data.link ?? "Something went Wrong.."}`); + imgurUrl = upload.data.link ?? "Something went Wrong.."; + return this.send(`/gc ${username}'s Active Pet: Check Discord Bridge for image.`); } catch (error) { errorMessage(error); this.send(`/gc [ERROR] ${error}`); diff --git a/src/minecraft/commands/warpoutCommand.js b/src/minecraft/commands/warpoutCommand.js index 022596a6..db1c7ec0 100644 --- a/src/minecraft/commands/warpoutCommand.js +++ b/src/minecraft/commands/warpoutCommand.js @@ -33,24 +33,20 @@ class warpoutCommand extends minecraftCommand { if (message.includes("You cannot invite that player since they're not online.")) { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; - - this.send(`/gc ${user} is not online!`); + this.send(`/gc ${user} is offline!`); } else if (message.includes("You cannot invite that player!")) { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; - this.send(`/gc ${user} has party requests disabled!`); } else if (message.includes("invited") && message.includes("to the party! They have 60 seconds to accept.")) { - this.send(`/gc Succesfully invited ${user} to the party!`); + this.send(`/gc Partying ${user}...`); } else if (message.includes(" joined the party.")) { - this.send(`/gc ${user} joined the party! Warping them out of the game..`); this.send("/p warp"); } else if (message.includes("warped to your server")) { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; - this.send(`/gc ${user} warped out of the game! Disbanding party..`); + this.send(`/gc Successfully warped ${user}!`); this.send("/p disband"); - await delay(1500); this.send("\u00a7"); } else if (message.includes(" cannot warp from Limbo")) { @@ -62,7 +58,6 @@ class warpoutCommand extends minecraftCommand { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; this.send(`/gc ${user} is not allowed on my server! Disbanding party..`); - this.send("/p leave"); await delay(1500); this.send("\u00a7"); @@ -70,7 +65,6 @@ class warpoutCommand extends minecraftCommand { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; this.send(`/gc Somehow I'm not allowed to invite players? Disbanding party..`); - this.send("/p disband"); await delay(1500); this.send("\u00a7"); @@ -78,7 +72,6 @@ class warpoutCommand extends minecraftCommand { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; this.send(`/gc Somehow I'm not allowed to disband this party? Leaving party..`); - this.send("/p leave"); await delay(1500); this.send("\u00a7"); @@ -90,18 +83,15 @@ class warpoutCommand extends minecraftCommand { } else if (message.includes("Couldn't find a player with that name!")) { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; - this.send(`/gc Couldn't find a player with that name!`); this.send("/p disband"); } else if (message.includes("You cannot party yourself!")) { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; - - this.send(`/gc I cannot party yourself!`); + this.send(`/gc I cannot party myself!`); } else if (message.includes("didn't warp correctly!")) { bot.removeListener("message", warpoutListener); this.isOnCooldown = false; - this.send(`/gc ${user} didn't warp correctly! Please try again..`); this.send("/p disband"); } @@ -113,7 +103,7 @@ class warpoutCommand extends minecraftCommand { bot.removeListener("message", warpoutListener); if (this.isOnCooldown === true) { - this.send("/gc Party timed out"); + this.send("/gc Party expired."); this.send("/p disband"); this.send("\u00a7"); diff --git a/src/minecraft/handlers/ChatHandler.js b/src/minecraft/handlers/ChatHandler.js index 6f373ea5..1af4668f 100644 --- a/src/minecraft/handlers/ChatHandler.js +++ b/src/minecraft/handlers/ChatHandler.js @@ -3,15 +3,15 @@ const { getLatestProfile } = require("../../../API/functions/getLatestProfile.js const updateRolesCommand = require("../../discord/commands/updateCommand.js"); const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const hypixel = require("../../contracts/API/HypixelRebornAPI.js"); -const { getUUID, getUsername } = require("../../contracts/API/mowojangAPI.js"); +const { getUUID } = require("../../contracts/API/mowojangAPI.js"); const eventHandler = require("../../contracts/EventHandler.js"); const getWeight = require("../../../API/stats/weight.js"); +const { isUuid } = require("../../../API/utils/uuid.js"); const messages = require("../../../messages.json"); const { EmbedBuilder } = require("discord.js"); const config = require("../../../config.json"); const Logger = require("../../Logger.js"); const { readFileSync } = require("fs"); -const { isUuid } = require("../../../API/utils/uuid.js"); class StateHandler extends eventHandler { constructor(minecraft, command, discord) { @@ -1066,7 +1066,7 @@ class StateHandler extends eventHandler { async updateUser(player) { try { if (isUuid(player) === false) { - player = await getUsername(player); + player = await getUUID(player); } if (config.verification.enabled === false) { @@ -1082,12 +1082,12 @@ class StateHandler extends eventHandler { return; } - const linkedUser = linked.find((user) => user.uuid === player); + const linkedUser = Object.values(linked).find((u) => player) if (linkedUser === undefined) { return; } - const user = await guild.members.fetch(linkedUser.id); + const user = await guild.members.fetch(linkedUser); await updateRolesCommand.execute(null, user); } catch { //