Add server history autocomplete

This commit is contained in:
Christopher Cookman 2024-06-27 01:10:07 -06:00
parent 2afb0656a0
commit 1c6ab2a0bf
Signed by: ChrisChrome
GPG key ID: A023A26E42C33A42
3 changed files with 106 additions and 61 deletions

1
.gitignore vendored
View file

@ -128,3 +128,4 @@ dist
.yarn/build-state.yml .yarn/build-state.yml
.yarn/install-state.gz .yarn/install-state.gz
.pnp.* .pnp.*
history.json

View file

@ -7,7 +7,10 @@ const checkSrv = (hostname) => {
hostname = `_minecraft._tcp.${hostname}`; hostname = `_minecraft._tcp.${hostname}`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
dns.resolveSrv(hostname, (err, addresses) => { dns.resolveSrv(hostname, (err, addresses) => {
if (err) reject(err); if (err) {
return reject(err);
}
if (!addresses || addresses.length <= 0) return reject("No SRV record found.");
resolve(addresses[0]); resolve(addresses[0]);
}); });
}); });

161
index.js
View file

@ -2,6 +2,7 @@ const findMc = require("./findMc");
const colors = require("colors"); const colors = require("colors");
require("dotenv").config(); require("dotenv").config();
const Discord = require("discord.js"); const Discord = require("discord.js");
const fs = require("fs");
const client = new Discord.Client({ intents: ["Guilds"] }); const client = new Discord.Client({ intents: ["Guilds"] });
unavailEmote = "<:unreachable:1255354739382816798>" unavailEmote = "<:unreachable:1255354739382816798>"
@ -27,7 +28,8 @@ const commands = [{
name: "address", name: "address",
description: "The address of the server", description: "The address of the server",
type: 3, type: 3,
required: true required: true,
autocomplete: true
}], }],
integration_types: [0, 1], integration_types: [0, 1],
contexts: [0, 1, 2] contexts: [0, 1, 2]
@ -65,67 +67,106 @@ client.on('ready', () => {
})(); })();
}) })
// 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 => { client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return; if (interaction.isCommand()) {
console.log(`${colors.cyan("[INFO]")} Command ${colors.green(interaction.commandName)} executed by ${colors.green(interaction.user.displayName)}`); switch (interaction.commandName) {
switch (interaction.commandName) { case "check":
case "check": await interaction.deferReply();
await interaction.deferReply(); const address = interaction.options.getString("address");
const address = interaction.options.getString("address"); doAddressHistory(interaction.user.id, address);
findMc(address, 5000).then((data) => { findMc(address, 5000).then((data) => {
data.description = filterMOTD(data.description); data.description = filterMOTD(data.description);
msgData = { msgData = {
embeds: [{ embeds: [{
title: `Server Info for ${address}`, title: `Server Info for ${address}`,
description: `Ping: ${pingEmote(data.ping)} ${data.ping}ms`, description: `Ping: ${pingEmote(data.ping)} ${data.ping}ms`,
fields: [ fields: [
{ {
name: "Server Version", name: "Server Version",
value: data.version.name, value: data.version.name,
inline: true inline: true
}, },
{ {
name: "Players", name: "Players",
value: `${data.players?.online}/${data.players?.max}`, value: `${data.players?.online}/${data.players?.max}`,
inline: true inline: true
}, },
{ {
name: "MOTD", name: "MOTD",
value: `\`${data.description?.split("\n")[0]}\`\n\`${data.description?.split("\n")[1]}\`` value: `\`${data.description?.split("\n")[0]}\`\n\`${data.description?.split("\n")[1]}\``
}, },
data.players.sample?.length > 0 ? { data.players.sample?.length > 0 ? {
name: "Players", name: "Players",
value: `\`\`\`\n${data.players.sample.map(player => player.name).join("\n")}\n\`\`\`` value: `\`\`\`\n${data.players.sample.map(player => player.name).join("\n")}\n\`\`\``
} : { } : {
name: "Players", name: "Players",
value: "No players online." 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"
} }
} // if data.favicon is not null, decode the base64 as a buffer, and make the json object for the attachment
interaction.editReply(msgData); if (data.favicon) {
}).catch((err) => { const buffer = Buffer.from(data.favicon.split(",")[1], "base64");
if (err.toString().startsWith("Error: The client timed out")) { msgData.files = [{
return interaction.editReply({ content: `${unavailEmote} The server did not respond or is offline.`, ephemeral: true }); attachment: buffer,
} name: "favicon.png"
if (err.toString().startsWith("Error: Invalid hostname")) { }]
return interaction.editReply({ content: "Invalid hostname.", ephemeral: true }); msgData.embeds[0].thumbnail = {
} url: "attachment://favicon.png"
console.log(err) }
return interaction.editReply({ content: "An error occurred while trying to ping the server.", ephemeral: true }); }
}) interaction.editReply(msgData);
break; }).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
}
}));
} }
}); });