您是否曾经拥有自己的Minecraft服务器,并觉得自己想:“如果我能够展示有关我的服务器的有用信息,或者在Discord中跟踪其延迟,那不是很棒吗?”
好吧,你很幸运!本教程将引导您完成整个过程,从头开始,因此您可以实现所有这些。
我们将使用discord.js
和koude1库,该库是一个现代,小型,性能,零依赖项打字库,我写的不扰乱服务器的响应。
让我们开始吧!
步骤1:设置Discord.js
这很简单。运行npm install discord.js
,导入discord.js,声明客户端,并且意图是登录机器人并在客户端准备就绪后记录消息。
import { Client, Events, EmbedBuilder, REST, SlashCommandBuilder, Routes, GatewayIntentBits, AttachmentBuilder } from 'discord.js';
import mc from "minecraftstatuspinger"
const client = new Client({intents: [GatewayIntentBits.Guilds]});
client.once("ready", c => {
console.log(`Ready! Logged in as ${c.user.tag}`);
});
// Log in to Discord with your client's token
client.login(process.env.token);
步骤2:做一个斜杠命令。
在此步骤中,我们将制作一个"ping"
斜杠命令。我们将首先宣布REST,该REST用于更新Slash命令。我们将其设置为“令牌环境变量”。我们在命令-hostname
和port
中添加两个选项。我们将Slash命令发送并注册到Discord,提供您的应用程序ID
const rest = new REST({ version: "10" }).setToken(process.env.token)
let commands = [
new SlashCommandBuilder().setName("ping").setDescription("Pings a Minecraft server.")
.addStringOption(option =>
option.setName("ip")
.setDescription("IP of server.")
.setRequired(true)
)
.addIntegerOption(option =>
option.setName("port")
.setDescription("Port of server.")
.setRequired(false)
.setMinValue(0)
.setMaxValue(65535)
)
].map(command => command.toJSON())
await rest.put(Routes.applicationCommands("app ID"), { body: commands })
步骤3:处理斜线命令。
订阅交互作用事件。收到一个人时,我们检查是否是斜线命令交互。是吗?答对了。完成此操作后,我们会检查其名称,如果正确,我们将调用getMcStatus
函数,我们在下一步中创建的函数
client.on(Events.InteractionCreate, (interaction: Interaction) => {
if (!interaction.isChatInputCommand()) return;
const { commandName } = interaction;
if (commandName === 'ping') return getMcStatus(interaction);
});
步骤4:设置MinecraftStatuspinger
如前所述,我们将使用MinecraftStatusPinger库。
运行此命令以从NPM:npm install minecraftstatuspinger
安装它。这样可以确保它在您的计算机上,并且您可以导入并使用它。
然后,像这样导入:
let mc = require("minecraftstatuspinger")
设置比Discord.js容易!只需安装它,导入并上路即可。没有其他设置,也没有创建pinger对象,它只是从开箱即用的。
步骤5:Ping Minecraft服务器
我们最终创建了getMcStatus
函数。我们需要两个选项-IP和端口。如果端口为null,则默认情况下将自动切换为25565。一旦获得这些,我们就可以用options调用.lookup()。这使得库直接将Ping请求直接发送给Minecraft服务器,而无需与任何中介API联系。
async function getMcStatus(interaction){
let IP = interaction.options.getString("ip")
let port = interaction.options.getInteger("port") || 25565
let result = await mc.lookup({ hostname: IP, port: port })
}
现在在status
内,有一个与这三个孩子的物体-status
,statusRaw
,latency
。
status
是包含播放器,版本,favicon和motd的对象!我们将在下一步中使用所有这些。
statusRaw
就像status
一样
latency
是一个数字,它表示服务器的延迟。它是通过将任意数据包发送到服务器并等待响应来实现的,因此它比普通Ping更准确。
步骤6:创建Favicon的附件
Minecraft服务器返回它的favicon作为数据URL BLOB。我们需要删除使用替换功能和REGEX完成的前缀,该函数替换所有Filetypes(例如data:image/png;base64,
或data:image/jpeg;base64,
)。然后,它将其变成一个缓冲区,即Discord.js可以用于图像附件。我们将其设置为icon.png
。
async function getMcStatus(interaction){
let IP = interaction.options.getString("ip")
let port = interaction.options.getInteger("port") || 25565
let result = await mc.lookup({ hostname: IP, port: port })
let buf = Buffer.from(result.status.favicon.replace(/data:image\/[^;]+;base64,/, ""), "base64")
let attach = await new AttachmentBuilder(buf)
.setName("icon.png")
}
步骤7:嵌入并发送
我们做了一个新的嵌入,我们给出了IP和MOTD的标题。 MOTD在版本中各不相同,对于hyvermyshypixel使用result.status.description
,现代服务器应使用result.status.description.text
。我们添加了播放器计数,添加了一个版本字段,该字段显示您可以从哪个版本加入服务器。最后,我们添加一个缩略图,即先前定义的附件。然后,我们回复互动,我们完成了!
async function getMcStatus(interaction){
let IP = interaction.options.getString("ip")
let port = interaction.options.getInteger("port") || 25565
let result = await mc.lookup({ hostname: IP, port: port })
let buf = Buffer.from(result.status.favicon.replace(/data:image\/[^;]+;base64,/, ""), "base64")
let attach = await new AttachmentBuilder(buf)
.setName("icon.png")
let motdEmbed = new EmbedBuilder()
.setTitle(`Status of ${IP}`)
.setDescription(result.status.description?.text || result.status.description) // MOTD
.addFields(
{name: "Players:", value: `${result.status.players.online}/${result.status.players.max}`},
{name: "Version:", value: result.status.version.name}
.setThumbnail("attachment://icon.png")
.setColor("DarkGreen")
)
interaction.reply({ embeds: [ motdEmbed ], files: [ attach ] })
}
最终代码
,我们完成了!不是那么艰难吗?这就是代码应该看起来:
import { Client, Events, EmbedBuilder, REST, SlashCommandBuilder, Routes, GatewayIntentBits, AttachmentBuilder } from 'discord.js';
import mc from "minecraftstatuspinger"
const client = new Client({intents: [GatewayIntentBits.Guilds]});
client.once("ready", c => {
console.log(`Ready! Logged in as ${c.user.tag}`);
});
client.on(Events.InteractionCreate, (interaction) => {
if (!interaction.isChatInputCommand()) return;
const { commandName } = interaction;
if (commandName === 'ping') return getMcStatus(interaction);
});
async function getMcStatus(interaction){
let IP = interaction.options.getString("ip")
let port = interaction.options.getInteger("port") || 25565
let result = await mc.lookup({hostname: IP, port: port})
let buf = Buffer.from(result.status.favicon.replace(/data:image\/[^;]+;base64,/, ""), "base64")
let attach = await new AttachmentBuilder(buf)
.setName("icon.png")
let motdEmbed = new EmbedBuilder()
.setTitle(`Status of ${IP}`)
.setDescription(result.status.description?.text || result.status.description) // MOTD
.addFields(
{name: "Players:", value: `${result.status.players.online}/${result.status.players.max}`},
{name: "Version:", value: result.status.version.name})
.setThumbnail("attachment://icon.png")
.setColor("DarkGreen")
interaction.reply({ embeds: [ motdEmbed ], files: [ attach ] })
}
const rest = new REST({ version: "10" }).setToken(process.env.token)
let commands = [
new SlashCommandBuilder().setName("ping").setDescription("Pings a Minecraft server.")
.addStringOption(option =>
option.setName("ip")
.setDescription("Sex")
.setRequired(true)
)
.addIntegerOption(option =>
option.setName("port")
.setDescription("Sex")
.setRequired(false)
.setMinValue(0)
.setMaxValue(65535)
)
].map(command => command.toJSON())
rest.put(Routes.applicationCommands("Application ID"), { body: commands })
// Log in to Discord with your client's token
client.login(process.env.token);
感谢您遵循本教程,我希望一切顺利!