我正试图编写一个Discord Bot来启动我的Minecraft服务器,以便我的任何朋友都可以在我不在或离线时在其上玩。我正在使用Server Status Bot的编辑脚本 Discord机器人,效果很好。
我的主要问题是最初用来启动服务器的初始服务器启动bot脚本。 Here.
这当然是一个很好的脚本,但是我对此感到不安的是如何确保服务器仅在当前不脱机时才启动,以防止启动命令发送垃圾邮件(这可能会导致巨大的延迟)。 )我决定将其切换为使用另一种方法,该方法将使用JavaScript的获取和响应从JSON中的MCAPI.us中提取主体数据,以准确确定服务器是联机还是脱机(存在一些延迟问题,但影响不大)。
Server Status Bot实际上使用此方法来准确地监视服务器,因此我认为我可以复制并调整程序的该部分以使其正常工作。但这就是问题所在。
主要问题总结如下:
每次我运行代码来启动服务器时,它将始终运行.catch。我已经对响应进行了一些研究,据我所知,这里的问题必须与我在这里使用body
的方式有关。编辑:我觉得我应该详细说明我在这里所做的研究。我尝试过尝试body会响应的关键字(body.status,body.online等),并且只能与body.status一起使用。
(我的代码更改)起始脚本
function startCommand(message) {
fetchStatus()
.then(body => {
if(body.online === 'false') return body;
else throw body.error || 'unknown API error';
})
.then(body => {
// Starting the server requires a special role named "ServerStarter"
if(!message.member.roles.cache.find(r => r.name === "ServerStarter")) return message.reply(commands.start.text.wrongperms)
else {
// Start the server
message.channel.send("Starting server...");
mcserver = spawn(MC_SERVER_START_SCRIPT);
我基于的原始fetch()脚本
client.on('message', message => { // Listen for messages and trigger commands
if(message.content.trim() == commands.status.command) {
statusCommand(message)
} else if(message.content.trim() == commands.ip.command) {
ipCommand(message)
} else if(message.content.trim() == commands.version.command) {
versionCommand(message)
} else if(message.content.trim() == commands.start.command) {
startCommand(message)
}
});
function statusCommand(message) { // Handle status command
if(Date.now() > lastUpdated + cacheTime) { // Cache expired or doesn't exist
fetchStatus()
.then(body => {
if(body.status === 'success') return body;
else throw body.error || 'unknown API error';
})
.then(body => {
data = body;
lastUpdated = body.last_updated * 1000 || Date.now();
lastUpdated = Math.min(lastUpdated, Date.now()); // Last updated time can't be in the future
lastUpdated = Math.max(lastUpdated, Date.now() - cacheTime + 60000); // Wait at least 1 minute
replyStatus(message, data)
})
.catch(err => {
console.error('Error:', err);
return message.reply(commands.status.text.error);
});
} else { // Use cached data
replyStatus(message)
}
}
function replyStatus(message) {
let { text } = commands.status;
let status = text.offline;
if(data.online) {
status = text.online;
status += data.players.now ? text.players : text.noPlayers;
status = status.replace('{online}', data.players.now);
}
message.reply(status);
}
function fetchStatus() {
return fetch(url)
.then(res => {
if(res.ok) return res;
else throw res.statusText;
})
.then(res => res.json())
}