const findMc = require("./findMc"); const colors = require("colors"); require("dotenv").config(); const Discord = require("discord.js"); const fs = require("fs"); const client = new Discord.Client({ intents: ["Guilds"] }); unavailEmote = "<:unreachable:1255354739382816798>" pingEmotes = [ "<:ping_1:1255354721145978950>", "<:ping_2:1255354720281821205>", "<:ping_3:1255354719409279056>", "<:ping_4:1255354718150987828>", "<:ping_5:1255354717660250172>" ] const { REST, Routes } = require('discord.js'); const rest = new REST({ version: "10" }).setToken(process.env.TOKEN); const commands = [{ name: "check", description: "Find a Minecraft server", options: [{ name: "address", description: "The address of the server", type: 3, required: true, autocomplete: true }], integration_types: [0, 1], contexts: [0, 1, 2] }]; const pingEmote = (ping) => { // If ping is less than 100, use the last emote, go from there for between 100 and 199, 200, 299 and 300+ if (ping < 100) return pingEmotes[4]; if (ping < 200) return pingEmotes[3]; if (ping < 300) return pingEmotes[2]; if (ping < 400) return pingEmotes[1]; return pingEmotes[0]; } const filterMOTD = (motd) => { lines = motd.split("\n"); lines.forEach((line, index) => { lines[index] = line.replace(/ยง./g, "").trim(); }); return lines.join("\n"); } client.on('ready', () => { console.log(`${colors.cyan("[INFO]")} Logged in as ${colors.green(client.user.tag)}`); (async () => { try { console.log(`${colors.cyan("[INFO]")} Registering Commands...`) let start = Date.now() //Global await rest.put(Routes.applicationCommands(client.user.id), { body: commands }) console.log(`${colors.cyan("[INFO]")} Successfully registered commands. Took ${colors.green((Date.now() - start) / 1000)} seconds.`); } catch (error) { console.error(error); } })(); }) // Try reading the history file, if it doesnt exist or is invalid, set addressHistory to an empty object. let addressHistory = {}; try { addressHistory = JSON.parse(fs.readFileSync("./history.json")); } catch (err) { addressHistory = {}; } // addressHistory[userid] = [address1, address2, address3, address4, address5]. Addresses never repeat, move them to the front of the array when they are used. Max of 10 addresses per user. const doAddressHistory = (userid, address) => { if (!addressHistory[userid]) { addressHistory[userid] = [address]; fs.writeFileSync("./history.json", JSON.stringify(addressHistory)); return; } if (addressHistory[userid].length >= 10) { addressHistory[userid].pop(); } // Check if the address is already in the array, if it is, remove it. if (addressHistory[userid].includes(address)) { addressHistory[userid].splice(addressHistory[userid].indexOf(address), 1); } addressHistory[userid].unshift(address); // Save history to file for future use fs.writeFileSync("./history.json", JSON.stringify(addressHistory)); } client.on('interactionCreate', async interaction => { if (interaction.isCommand()) { switch (interaction.commandName) { case "check": await interaction.deferReply(); const address = interaction.options.getString("address"); doAddressHistory(interaction.user.id, address); findMc(address, 5000).then((data) => { data.description = filterMOTD(data.description); msgData = { embeds: [{ title: `Server Info for ${address}`, description: `Ping: ${pingEmote(data.ping)} ${data.ping}ms`, fields: [ { name: "Server Version", value: data.version.name, inline: true }, { name: "Players", value: `${data.players?.online}/${data.players?.max}`, inline: true }, { name: "MOTD", value: `\`${`\`${data.description?.split("\n")[0]}\`` || ""}\`\n${`\`${data.description?.split("\n")[1]}\`` || ""}` }, data.players.sample?.length > 0 ? { name: "Players", value: `\`\`\`\n${data.players.sample.map(player => player.name).join("\n")}\n\`\`\`` } : { name: "Players", value: "No players online." } ] }] } // if data.favicon is not null, decode the base64 as a buffer, and make the json object for the attachment if (data.favicon) { const buffer = Buffer.from(data.favicon.split(",")[1], "base64"); msgData.files = [{ attachment: buffer, name: "favicon.png" }] msgData.embeds[0].thumbnail = { url: "attachment://favicon.png" } } interaction.editReply(msgData); }).catch((err) => { if (err.toString().startsWith("Error: The client timed out")) { return interaction.editReply({ content: `${unavailEmote} The server did not respond or is offline.`, ephemeral: true }); } if (err.toString().startsWith("Error: Invalid hostname")) { return interaction.editReply({ content: "Invalid hostname.", ephemeral: true }); } console.log(err) return interaction.editReply({ content: "An error occurred while trying to ping the server.", ephemeral: true }); }) break; } } if(interaction.isAutocomplete()) { // Send their history as options const history = addressHistory[interaction.user.id] || []; // Map the history to options interaction.respond(history.map((address) => { return { name: address, value: address } })); } }); client.login(process.env.TOKEN);