diff --git a/package-lock.json b/package-lock.json index e144f34..5051da5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "discord.js": "^14.11.0", "ffmpeg-static": "^5.2.0", "libsodium-wrappers": "^0.7.11", + "mcping-js": "^1.5.0", "yt-dlp-wrap": "^2.3.12" }, "devDependencies": { @@ -1119,6 +1120,11 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/mcping-js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mcping-js/-/mcping-js-1.5.0.tgz", + "integrity": "sha512-CoXbpbSqE4OtJupU2lvzoKFrGerH0AoyY9YoQ98EKUOhtxfLQa+f+DFqWYUaZ451Scru1gJm/+w6d3IKJhMGvQ==" + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", diff --git a/package.json b/package.json index dae5ffd..e07b988 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "discord.js": "^14.11.0", "ffmpeg-static": "^5.2.0", "libsodium-wrappers": "^0.7.11", + "mcping-js": "^1.5.0", "yt-dlp-wrap": "^2.3.12" }, "devDependencies": { diff --git a/src/app.ts b/src/app.ts index d1a2fab..ce15a5f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -29,23 +29,6 @@ client.once(Events.ClientReady, async client => { }); }); -const REPLIES = [ - "https://media.discordapp.net/attachments/709446245516574860/1153875831857352784/gideobn_lala.gif", - "https://media.discordapp.net/attachments/1072009407497515059/1150969108008017960/brett.gif", - "https://images-ext-2.discordapp.net/external/nqpPlVXUTEYQzmBZuYAhWBNyCRaxTVQ_GT8cNjfQaCQ/https/media.tenor.com/GEuUa7wY5JwAAAPo/sad-speech-bubble.mp4", - "https://media.discordapp.net/attachments/709446245516574860/1150672443426484246/maletic.gif", - "https://images-ext-1.discordapp.net/external/zSnVZqNRKx3g9Rc4D1kc7Hl_p2Qs5uomscPH6p9lp2E/https/media.tenor.com/HrUh7_ReprYAAAPo/police-help-speech-bubble.mp4", - "https://media.tenor.com/ESD9F3r4uXIAAAPo/bubble-text-owl-text-bubble.mp4", - "https://media.discordapp.net/attachments/709446245516574860/1151728821150695464/fridge.gif?width=507&height=676" -] - -client.on(Events.MessageCreate, async message => { - if (Math.random() < 0.03) { - await message.reply({ files: [ REPLIES[Math.floor(Math.random() * REPLIES.length)] ]}); - return; - } -}) - client.on(Events.InteractionCreate, async interaction => { if (interaction.isChatInputCommand()) { const command = COMMANDS.find(command => command.data.name === interaction.commandName); @@ -58,4 +41,22 @@ client.on(Events.InteractionCreate, async interaction => { } }); -client.login(TOKEN); \ No newline at end of file +client.login(TOKEN); + +// const REPLIES = [ +// "https://media.discordapp.net/attachments/709446245516574860/1153875831857352784/gideobn_lala.gif", +// "https://media.discordapp.net/attachments/1072009407497515059/1150969108008017960/brett.gif", +// "https://images-ext-2.discordapp.net/external/nqpPlVXUTEYQzmBZuYAhWBNyCRaxTVQ_GT8cNjfQaCQ/https/media.tenor.com/GEuUa7wY5JwAAAPo/sad-speech-bubble.mp4", +// "https://media.discordapp.net/attachments/709446245516574860/1150672443426484246/maletic.gif", +// "https://images-ext-1.discordapp.net/external/zSnVZqNRKx3g9Rc4D1kc7Hl_p2Qs5uomscPH6p9lp2E/https/media.tenor.com/HrUh7_ReprYAAAPo/police-help-speech-bubble.mp4", +// "https://media.tenor.com/ESD9F3r4uXIAAAPo/bubble-text-owl-text-bubble.mp4", +// "https://media.discordapp.net/attachments/709446245516574860/1151728821150695464/fridge.gif?width=507&height=676" +// ] + +// client.on(Events.MessageCreate, async message => { +// if (Math.random() < 0.03) { +// await message.reply({ files: [ REPLIES[Math.floor(Math.random() * REPLIES.length)] ]}); +// return; +// } +// }) + \ No newline at end of file diff --git a/src/commands/index.ts b/src/commands/index.ts index a3fc46a..ed19727 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -8,5 +8,6 @@ import { Meme } from "./meme"; import { Help } from "./help"; import { Poll } from "./poll"; import { Oobinate } from "./oob"; +import { Minecraft } from "./minecraft"; -export const COMMANDS = [ Help, Play, Skip, Queue, Stop, Meme, Oobinate, Poll, Status, Deploy ]; \ No newline at end of file +export const COMMANDS = [ Help, Play, Skip, Queue, Stop, Meme, Oobinate, Poll, Status, Deploy, Minecraft ]; \ No newline at end of file diff --git a/src/commands/minecraft.ts b/src/commands/minecraft.ts new file mode 100644 index 0000000..ea304e7 --- /dev/null +++ b/src/commands/minecraft.ts @@ -0,0 +1,41 @@ +import { SlashCommandBuilder } from "discord.js"; +import { Command } from "../lib/command"; +import { Embeds } from "../lib/utils/embeds"; + +export const Minecraft: Command = { + data: new SlashCommandBuilder() + .setName('minecraft') + .setDescription('Gets the status of a Minecraft server') + .addStringOption(option => option.setName("address").setRequired(true).setDescription("The address of the server")) + .addIntegerOption(option => option.setName("port").setDescription("The port of the server")), + execute: async (client, interaction) => { + let address = interaction.options.getString("address", true); + let port = interaction.options.getNumber("port", false) ?? 25565; + + let status = await MinecraftServer.ping(address, port).catch(_ => null); + if (status) { + let embed = Embeds.create() + .setAuthor({ name: 'Minecraft Server Status' }) + .setTitle(`${address}${port == 25565 ? "" : `:${port}`}`) + .setDescription(status.description.text) + .addFields({ name: 'Players', value: `${status.players.online}/${status.players.max}` }); + if (status.favicon) embed.setThumbnail(status.favicon); + await Embeds.send(interaction, () => embed); + return; + } + + await Embeds.send(interaction, embed => embed + .setTitle(`${address}${port == 25565 ? "" : `:${port}`}`) + .setDescription(`Server did not respond to ping. :sad:`)); + // let embed = Embeds.create() + // .setAuthor({ name: 'Now Playing' }) + // .setTitle(playing.getTitle()) + // .setURL(playing.getUrl()) + // .setDescription(` + // by ${playing.getAuthor()} \n + // ${bar} ${Time.format(connection.resource?.playbackDuration)}/${Time.format(playing.getDuration(), "seconds")} + // `) + // .setThumbnail(playing.getThumbnailUrl()) + // .addFields({ name: '\u200B', value: `Next in the queue (${Text.number(queue.length, "song")}):` }) + }, +} \ No newline at end of file diff --git a/src/lib/utils/server.ts b/src/lib/utils/server.ts new file mode 100644 index 0000000..c9a88d6 --- /dev/null +++ b/src/lib/utils/server.ts @@ -0,0 +1,25 @@ + +namespace MinecraftServer { + + export interface Status { + previewsChat: boolean; + enforcesSecureChat: boolean; + preventsChatReports: boolean; + description: { + text: string; + }; + players: { + max: number; + online: number; + }; + version: { + name: string; + protocol: number; + } + favicon: string; + } + + export const ping = async (host: string, port: number = 25565, timeout: number = 3000, protocolVersion: number = 47): Promise => + new Promise((resolve, reject) => new (require('mcping-js')) + .MinecraftServer(host, port).ping(timeout, protocolVersion, (err: any, res: any) => res ? resolve(res) : reject(err))); +} \ No newline at end of file diff --git a/src/lib/utils/style.ts b/src/lib/utils/style.ts index 32317ea..70c98d6 100644 --- a/src/lib/utils/style.ts +++ b/src/lib/utils/style.ts @@ -9,5 +9,5 @@ export namespace Style { export const NAME = "BarbarianBot"; export const ENGINE_VERSION = "Barbarian v2"; export const VERSION = "2.0"; - export const PROFILE_URL = "https://cdn.discordapp.com/avatars/937850544255545394/5953a93c37c8de47f42058649c45e6ec?size=1024" + export const PROFILE_URL = "https://cdn.discordapp.com/avatars/937850544255545394/dfa825b8b7cb035ef2577d847c22326e?size=1024" // https://i.imgur.com/risXNrf.png }