From 320fae806137c20cb4e9e9f5f8f9fab181e35a13 Mon Sep 17 00:00:00 2001 From: Maurits Wilke Date: Tue, 1 Feb 2022 18:20:22 +0100 Subject: [PATCH] Overwrites properly working in all modes, added setkey, not having an api does not break the application, added proper default settings to the application, hypixel.js now supports setkey, help now works for specific commands, added all parameter to onHover and onClick for Message class, nicks now give warnings --- .gitignore | 3 +- package.json | 8 ++- src/commands/help.js | 20 ++++++- src/commands/setkey.js | 40 +++++++++++++ src/index.js | 11 ++-- src/overwrites/bedwars.js | 90 +++++++++++++++++------------ src/utils/api/hypixel.js | 24 ++++---- src/utils/api/json/starColours.json | 33 +++++++++++ src/utils/classes/message.js | 4 +- src/utils/classes/proxy.js | 77 ++++++++++++------------ src/utils/settings.json | 13 ++++- 11 files changed, 224 insertions(+), 99 deletions(-) create mode 100644 src/commands/setkey.js create mode 100644 src/utils/api/json/starColours.json diff --git a/.gitignore b/.gitignore index ea167a4..668d0d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ node_modules/ inStream.txt HyProxyConfig.json -dist/ -oldSRC/ \ No newline at end of file +dist/ \ No newline at end of file diff --git a/package.json b/package.json index 2d20123..dbb548c 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,13 @@ "@types/node": "^17.0.13" }, "scripts": { - "build": "pkg src/index.js -c package.json --debug" + "build": "pkg src/index.js -c package.json" }, "pkg": { - "scripts": "./src/**/*.js", + "scripts": [ + "./src/**/**/*.js" + ], "assets": "./src/**/*", "outputPath": "dist" } -} +} \ No newline at end of file diff --git a/src/commands/help.js b/src/commands/help.js index 4be16e1..d6a5317 100644 --- a/src/commands/help.js +++ b/src/commands/help.js @@ -32,10 +32,28 @@ module.exports = class extends Command { .addText(`${capitalName}: `, { bold: true }) .addText(command.description, { bold: false }) .onHover(helpCard, 3) - .onClick("suggest_command", `${user.prefix}help ${command.name}`, 3) + .onClick("run_command", `${user.prefix}help ${command.name}`, 3) } msg.newLine().addText("-".repeat(45)); return client.write("chat", { message: msg.stringify() }) + } else { + const command = user.commands.get(args[0]) || + user.commands.get([...user.commands].find(command => command[1]?.aliases?.includes(args[0]))?.[0]) + if (!command) { + const msg = new Message(`That command doesn't exist! Run /help to see a list of all commands`, { color: design.colours.failed }) + .stringify(); + client.write("chat", { message: msg }) + return; + } + const helpMsg = new Message(`-`.repeat(53), { color: design.colours.default }) + .addText(`Name: `, { bold: true }).addText(command.name).newLine() + .addText(`Description: `, { bold: true }).addText(command?.description ?? "none?").newLine() + .addText(`Example: `, { bold: true }).addText(command?.example ?? "none?").newLine() + .addText(`Aliases: `, { bold: true }).addText(command?.aliases.join() || "none").newLine() + .addText(`-`.repeat(53), { color: design.colours.default }) + .onClick("suggest_command", `${user.prefix}${command.name}`, "all") + .stringify(); + client.write("chat", { message: helpMsg }) } } } \ No newline at end of file diff --git a/src/commands/setkey.js b/src/commands/setkey.js new file mode 100644 index 0000000..67a9aa4 --- /dev/null +++ b/src/commands/setkey.js @@ -0,0 +1,40 @@ +const Command = require('../utils/classes/command') +const { Message } = require("../utils/classes/message") +const { writeFileSync } = require("fs") +const { join } = require("path") +const config = require(join(process.cwd(), "HyProxyConfig.json")) +const { keyInfo, setKey } = require("../utils/api/hypixel") +const design = config.config + +module.exports = class extends Command { + constructor() { + super({ + name: "setkey", + description: "Set the API key for HyProxy", + example: "setkey abcdefgh-ijkl-mnop-qrst-uvwxyz123456", + aliases: [ + "rq" + ] + }) + } + + async run(client, message, args, server, user) { + if (!args[0]) { + const msg = new Message("Please provide an API key, generate one using /api new", { color: design.colours.failed }).stringify(); + client.write("chat", { message: msg }) + } else { + try { + const info = await keyInfo(args[0]); + config.apiKey = info.key; + setKey(info.key) + writeFileSync(join(process.cwd(), "HyProxyConfig.json"), JSON.stringify(config, null, 4)) + const msg = new Message("Successfully set API key!", { color: design.colours.success }).stringify(); + client.write("chat", { message: msg }) + } catch (e) { + console.log(e) + const msg = new Message("Invalid API key! Generate a new one using /api new", { color: design.colours.failed }).stringify(); + client.write("chat", { message: msg }) + } + } + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 5e77a78..82a1459 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,13 @@ +const chalk = require("chalk") const { readdirSync, writeFileSync, existsSync, appendFileSync } = require("fs") const { resolve, join } = require('path'); -const Proxy = require("./utils/classes/proxy"); -const chalk = require("chalk") -const { name } = require("./utils/settings.json") -const configFile = join(process.cwd(), "./HyProxyConfig.json") -if (!existsSync(configFile)) appendFileSync(configFile, JSON.stringify({ prefix: "/" }, null, 4), (err) => { if (err) return }) +const { name, configTemplate } = require("./utils/settings.json") +const configFile = join(process.cwd(), "HyProxyConfig.json") +if (!existsSync(configFile)) appendFileSync(configFile, JSON.stringify(configTemplate, null, 4), (err) => { if (err) return }) const config = require(configFile) +const Proxy = require("./utils/classes/proxy"); + process.stdout.write("\033]0;" + name + "\007"); if (!config.username || !config.password || !config.auth) login(); diff --git a/src/overwrites/bedwars.js b/src/overwrites/bedwars.js index c3ff786..c655a1d 100644 --- a/src/overwrites/bedwars.js +++ b/src/overwrites/bedwars.js @@ -1,6 +1,7 @@ const Overwrite = require("../utils/classes/overwrite"); const { Message, Card } = require("../utils/classes/message"); const { playerStats } = require("../utils/api/hypixel") +const starColours = require("../utils/api/json//starColours.json") const { join } = require("path") const config = require(join(process.cwd(), "HyProxyConfig.json")) const design = config.config @@ -12,44 +13,61 @@ module.exports = class extends Overwrite { }) } - async overwrite(client, parsed, classic, clean, username) { - const player = await playerStats(username, "Bedwars"); - const FKDR = Math.round((player.final_kills_bedwars / player.final_deaths_bedwars) * 100) / 100 || 0; - const soloFKDR = Math.round((player.eight_one_final_kills_bedwars / player.eight_one_final_deaths_bedwars) * 100) / 100 || 0; - const doublesFKDR = Math.round((player.eight_two_final_kills_bedwars / player.eight_two_final_deaths_bedwars) * 100) / 100 || 0; - const threesFKDR = Math.round((player.four_three_final_kills_bedwars / player.four_three_final_deaths_bedwars) * 100) / 100 || 0; - const foursFKDR = Math.round((player.four_four_final_kills_bedwars / player.four_four_final_deaths_bedwars) * 100) / 100 || 0; - const fkdrCard = new Card(`${username} - FKDR`) - .addField("Overall: ", FKDR) - .addField("Solo: ", soloFKDR) - .addField("Doubles: ", doublesFKDR) - .addField("Threes: ", threesFKDR) - .addField("Fours: ", foursFKDR) - .classic(); + async overwrite(client, parsed, classic, clean, username, styledUsername) { + // const styledUsername = classic.replace(/ has joined.*/, "") + try { + const player = await playerStats(username); + const star = player.achievements.bedwars_level + const FKDR = Math.round((player.stats.Bedwars.final_kills_bedwars / player.stats.Bedwars.final_deaths_bedwars) * 100) / 100 || 0; + const soloFKDR = Math.round((player.stats.Bedwars.eight_one_final_kills_bedwars / player.stats.Bedwars.eight_one_final_deaths_bedwars) * 100) / 100 || 0; + const doublesFKDR = Math.round((player.stats.Bedwars.eight_two_final_kills_bedwars / player.stats.Bedwars.eight_two_final_deaths_bedwars) * 100) / 100 || 0; + const threesFKDR = Math.round((player.stats.Bedwars.four_three_final_kills_bedwars / player.stats.Bedwars.four_three_final_deaths_bedwars) * 100) / 100 || 0; + const foursFKDR = Math.round((player.stats.Bedwars.four_four_final_kills_bedwars / player.stats.Bedwars.four_four_final_deaths_bedwars) * 100) / 100 || 0; + const fkdrCard = new Card(`${username} - FKDR`) + .addField("Overall: ", FKDR) + .addField("Solo: ", soloFKDR) + .addField("Doubles: ", doublesFKDR) + .addField("Threes: ", threesFKDR) + .addField("Fours: ", foursFKDR) + .classic(); - const winstreak = player.winstreak || 0; - const soloWinstreak = player.eight_one_winstreak || 0; - const doublesWinstreak = player.eight_two_winstreak || 0; - const threesWinstreak = player.four_three_winstreak || 0; - const foursWinstreak = player.four_four_winstreak || 0; - const winstreakCard = new Card(`${username} - Winstreaks`) - .addField("Overall: ", winstreak) - .addField("Solo: ", soloWinstreak) - .addField("Doubles: ", doublesWinstreak) - .addField("Threes: ", threesWinstreak) - .addField("Fours: ", foursWinstreak) - .classic(); + const winstreak = player.stats.Bedwars?.winstreak ?? "disabled"; + const soloWinstreak = player.stats?.Bedwars.eight_one_winstreak ?? "disabled"; + const doublesWinstreak = player.stats?.Bedwars.eight_two_winstreak ?? "disabled"; + const threesWinstreak = player.stats?.Bedwars.four_three_winstreak ?? "disabled"; + const foursWinstreak = player.stats?.Bedwars.four_four_winstreak ?? "disabled"; + const winstreakCard = new Card(`${username} - Winstreaks`) + .addField("Overall: ", winstreak) + .addField("Solo: ", soloWinstreak) + .addField("Doubles: ", doublesWinstreak) + .addField("Threes: ", threesWinstreak) + .addField("Fours: ", foursWinstreak) + .classic(); - const styledUsername = classic.replace(/ has joined.*/, "") - const msg = new Message(` ${design.joinIcon} ${styledUsername} `, { color: "yellow" }) - .addText("fkdr: ", { color: "red" }) - .addText(`${FKDR} `, { color: "red" }) - .onHover(fkdrCard, 2) - .addText("ws: ", { color: "red" }) - .addText(`${winstreak} `, { color: "red" }) - .onHover(winstreakCard, 2) - .addText(clean.match(/\(\d\/\d\)/)[0]) + const msg = new Message(` ${design.joinIcon} `, { color: "yellow" }) + .addText(`[${star}✫] `, { color: starColours[Math.floor(star / 100)] }) + .addText(`${styledUsername} `) + .addText("fkdr: ", { color: "red" }) + .addText(`${FKDR} `, { color: "red" }) + .onHover(fkdrCard, 2) + .addText("ws: ", { color: "red" }) + .addText(`${winstreak} `, { color: "red" }) + .onHover(winstreakCard, 2) + .addText(clean.match(/\(\d{1,2}\/\d{1,2}\)/)?.[0] || "") - client.write("chat", { message: msg.stringify() }) + client.write("chat", { message: msg.stringify() }) + } catch (e) { + if (String(e).match("does not exist")) { + const msg = new Message(` ${design.joinIcon} `, { color: "dark_red" }) + .addText(styledUsername) + .addText(" is nicked!") + .stringify() + client.write("chat", { message: msg }) + } else { + console.log(e) + const msg = new Message(`Overwrite failed, please check application and report the bug!`, { color: "dark_red" }) + client.write("chat", { message: msg.stringify() }) + } + } } } \ No newline at end of file diff --git a/src/utils/api/hypixel.js b/src/utils/api/hypixel.js index fd57525..2ae0602 100644 --- a/src/utils/api/hypixel.js +++ b/src/utils/api/hypixel.js @@ -1,7 +1,7 @@ const fetch = require('node-fetch'); const { getUUID, getUsername } = require('./mojang.js'); const { join } = require("path") -const { apiKey } = require(join(process.cwd(), "./HyProxyConfig.json")) +let { apiKey } = require(join(process.cwd(), "./HyProxyConfig.json")) const Cache = require("./cache") const BASE_KEY = "https://api.hypixel.net" @@ -21,11 +21,16 @@ module.exports = { getActiveBoosters, playerCounts, getPunishments, - clearCache + clearCache, + setKey } -async function keyInfo() { - const response = await fetch(`${BASE_KEY}/key?&key=${apiKey}`); +function setKey(key) { + apiKey = key; +} + +async function keyInfo(key) { + const response = await fetch(`${BASE_KEY}/key?&key=${key || apiKey}`); if (!response.ok) return Promise.reject(`${response.status} ${response.statusText}`); const r = await response.json(); return r.record; @@ -33,12 +38,11 @@ async function keyInfo() { async function playerStats(player, gamemode) { if (!player) return Promise.reject(`This function requires an input`); - const UUID = player.length < 16 ? uuidCache.get(player) || uuidCache.set(player, await getUUID(player)).value : player; + const UUID = player.length <= 16 ? uuidCache.get(player) || await getUUID(player).then(r => uuidCache.set(player, r).value) : player; const response = await fetch(`${BASE_KEY}/player?uuid=${UUID}&key=${apiKey}`); if (!response.ok) return Promise.reject(`${response.status} ${response.statusText}`); const json = await response.json(); return gamemode ? json.player.stats[gamemode] : json.player; - } async function friendList(player) { @@ -49,7 +53,7 @@ async function friendList(player) { async function recentGames(player) { if (!player) return Promise.reject(`This function requires an input`); - const UUID = player.length < 16 ? uuidCache.get(player) || uuidCache.set(player, await getUUID(player)).value : player; + const UUID = player.length <= 16 ? uuidCache.get(player) || await getUUID(player).then(r => uuidCache.set(player, r).value) : player; const response = await fetch(`${BASE_KEY}/recentgames?uuid=${UUID}&key=${apiKey}`); const r = await response.json(); return r.games; @@ -57,7 +61,7 @@ async function recentGames(player) { async function playerStatus(player) { if (!player) return Promise.reject(`This function requires an input`); - const UUID = player.length < 16 ? uuidCache.get(player) || uuidCache.set(player, await getUUID(player)).value : player; + const UUID = player.length <= 16 ? uuidCache.get(player) || await getUUID(player).then(r => uuidCache.set(player, r).value) : player; const response = await fetch(`${BASE_KEY}/status?uuid=${UUID}&key=${apiKey}`); if (!response.ok) return Promise.reject(`${response.status} ${response.statusText}`); const json = await response.json(); @@ -120,7 +124,7 @@ async function clearCache() { async function getFriendList(player) { let friendList = new Map() - const UUID = player.length < 16 ? uuidCache.get(player) || uuidCache.set(player, await getUUID(player)).value : player; + const UUID = player.length <= 16 ? uuidCache.get(player) || await getUUID(player).then(r => uuidCache.set(player, r).value) : player; const response = await fetch(`${BASE_KEY}/friends?uuid=${UUID}&key=${apiKey}`); if (!response.ok) return Promise.reject(`${response.status} ${response.statusText}`); const { records } = await response.json(); @@ -133,7 +137,7 @@ async function getFriendList(player) { } async function getPlayerGuild(player) { - const UUID = player.length < 16 ? uuidCache.get(player) || uuidCache.set(player, await getUUID(player)).value : player; + const UUID = player.length <= 16 ? uuidCache.get(player) || await getUUID(player).then(r => uuidCache.set(player, r).value) : player; const response = await fetch(`${BASE_KEY}/guild?player=${UUID}&key=${apiKey}`); if (!response.ok) return Promise.reject(`${response.status} ${response.statusText}`); const json = await response.json(); diff --git a/src/utils/api/json/starColours.json b/src/utils/api/json/starColours.json new file mode 100644 index 0000000..1b623c5 --- /dev/null +++ b/src/utils/api/json/starColours.json @@ -0,0 +1,33 @@ +{ + "0": "gray", + "1": "white", + "2": "gold", + "3": "aqua", + "4": "dark_green", + "5": "dark_aqua", + "6": "dark_red", + "7": "light_purple", + "8": "blue", + "9": "dark_purple", + "10": "yellow", + "11": "white", + "12": "gold", + "13": "aqua", + "14": "dark_green", + "15": "dark_aqua", + "16": "dark_red", + "17": "light_purple", + "18": "blue", + "19": "dark_purple", + "20": "dark_gray", + "21": "yellow", + "22": "yellow", + "23": "yellow", + "24": "yellow", + "25": "yellow", + "26": "yellow", + "27": "yellow", + "28": "yellow", + "29": "yellow", + "30": "yellow" +} \ No newline at end of file diff --git a/src/utils/classes/message.js b/src/utils/classes/message.js index c479bcc..123c7f4 100644 --- a/src/utils/classes/message.js +++ b/src/utils/classes/message.js @@ -115,7 +115,7 @@ class Message { } onHover(text, amount = 1) { - if (amount > this.message.extra.length) amount = this.message.extra.length + if (amount > this.message.extra.length || amount === "all") amount = this.message.extra.length while (amount) { this.message.extra[this.message.extra.length - amount].hoverEvent = { "action": "show_text", @@ -127,7 +127,7 @@ class Message { } onClick(type, value, amount = 1) { - if (amount > this.message.extra.length) amount = this.message.extra.length + if (amount > this.message.extra.length || amount === "all") amount = this.message.extra.length while (amount) { if (!["open_url", "run_command", "suggest_command", "copy_to_clipboard"].includes(type)) throw new Error("Invalid type") this.message.extra[this.message.extra.length - amount].clickEvent = { action: type, value: value } diff --git a/src/utils/classes/proxy.js b/src/utils/classes/proxy.js index 3f2ef84..75f0478 100644 --- a/src/utils/classes/proxy.js +++ b/src/utils/classes/proxy.js @@ -3,7 +3,8 @@ const chalk = require("chalk"); const EventEmitter = require("events"); const { join } = require("path"); const { deepParse } = require("../util") -const { toFormatting, Message } = require("./message") +const { toFormatting, Message, Card } = require("./message") +const settings = require("../settings.json") const configPath = join(process.cwd(), "HyProxyConfig.json") const config = require(configPath) const design = config.config; @@ -45,6 +46,7 @@ class Proxy extends EventEmitter { let endedClient = false; let endedTargetClient = false; + let warnedOverwrite = false; ["end", "error"].forEach(event => { client.on(event, () => { @@ -74,7 +76,7 @@ class Proxy extends EventEmitter { [ `-`.repeat(53), ` Welcome, ${client.username}`, - ` Connected to Hypixel through ${config.name}`, + ` Connected to Hypixel through ${settings.name}`, ` Run ${config.prefix}help to see the commands`, `-`.repeat(53), ].forEach(msg => { @@ -83,39 +85,6 @@ class Proxy extends EventEmitter { }) }, 2000) - //#region - // setTimeout(() => { - // if (!config?.apiKey) { - // const msg = new Message(`No API key found`, { color: design.colours.failed }) - // .newLine() - // .addText("Please set one by running ") - // .addText("/setkey ") - // .onClick("suggest_command", "/setkey") - // .onHover(new Message("/setkey", { color: design.colours.default }).classic()) - // .newLine() - // .addText('') - // .onClick("suggest_command", "/api new") - // .onHover( - // new Message("Hypixel API key", {}) - // ) - - // } - - - // const text = new MessageComponent(`${templates.failed}No api key found!\n${templates.failed}Please set one by running `) - // const hoverComp = new MessageComponent(`${templates.failed}/setkey `) - // .onClick("suggest_command", "/setkey") - // .onHover("§c/setkey") - // const apiComp = new MessageComponent(`${templates.failed}`) - // .onClick("suggest_command", "/api new") - // .onHover(`§aHypixel API key`, [`§aThis key is used to request from the Hypixel API`, `§aGenerate a new one by running /api new`]) - // const msg = new Message({ components: [text, hoverComp, apiComp] }).stringify(); - // if (!apiKey) { - // client.write("chat", { message: msg, position: 0 }) - // } - // }, 5000) - //#endregion - setInterval(() => { hypixel.write("chat", { message: `/locraw` }) }, 5000) @@ -152,11 +121,41 @@ class Proxy extends EventEmitter { const classicStyle = toFormatting(parsed); const flatClean = classicStyle.replace(/§./g, ""); - const overwrite = this.user.overwrites.get(this.user.gametype); - if (overwrite && flatClean.match(/ has joined \(\d\/\d\)!/)) { - const ign = flatClean.replace(/ has joined \(\d\/\d\)!/, ""); - return overwrite.overwrite(client, parsed, classicStyle, flatClean, ign) + + if (overwrite && flatClean.match(/ has joined \(\d{1,2}\/\d{1,2}\)!/)) { + if (config.apiKey) { + const ign = flatClean.replace(/ has joined \(\d{1,2}\/\d{1,2}\)!/, ""); + const styledIGN = classicStyle.replace(/ has joined.*/, "") + return overwrite.overwrite(client, parsed, classicStyle, flatClean, ign, styledIGN) + } else if (!warnedOverwrite) { + warnedOverwrite = true; + const apiKeyCard = new Card("Hypixel API key") + .addLine("This API key is used to fetch data from the Hypixel API") + .addLine("You can (re)generate one by running /api new") + .addLine("Warning: regenerating your key will void the old one", { color: "dark_red" }) + .classic(); + + const msg = new Message(`Overwrites don't work without an API key!`, { color: design.colours.failed }) + .newLine() + .addText("Please set one by running ") + .addText("/setkey ") + .onClick("suggest_command", "/setkey") + .addText('') + .onClick("suggest_command", "/api new") + .onHover(apiKeyCard) + .stringify(); + client.write("chat", { message: msg }) + } + } + + if (overwrite && flatClean.match("ONLINE")) { + const players = classicStyle.replace("§l§bONLINE: ", "").split(", ") + players.forEach(player => { + const ign = player.replace(/§./g, ""); + overwrite.overwrite(client, parsed, classicStyle, flatClean, ign, player) + }) + return } } diff --git a/src/utils/settings.json b/src/utils/settings.json index 1040bfd..41de1b0 100644 --- a/src/utils/settings.json +++ b/src/utils/settings.json @@ -1,4 +1,15 @@ { "_comment": "These settings are hardcoded and shouldn't be change-able in the config file", - "name": "HyProxy" + "name": "HyProxy", + "configTemplate": { + "prefix": "/", + "config": { + "colours": { + "default": "aqua", + "success": "green", + "failed": "red" + }, + "joinIcon": "»" + } + } } \ No newline at end of file