Reputation: 769
I'm working on a Discord bot using node.js. The idea is fairly simple, the bot checks chat messages for certain phrases that trigger it to do various actions. Mostly related to giving info about various game servers.
I've got the bot working and it does the basics of what I wanted it to do.
I'm looking to expand its functionality a bit however.
Basically when people type in a certain term like 'server 1v1' the bot will give the connection info to that server as well as query the current state of the server.
I'm using an npm package called gamedig to do this.
The code is as follows
//Query Minecraft Server
var serverInfo = function(chatTrigger){
//create an array of servers
//Name of the array arrays within the array is the chat trigger, the first value of each chat trigger array is the query mode for gamedir, second value is the IP or server query URL.
var namedServerArrays = {
'1v1' : ["csgo","192.168.1.1",2016],
'10man' : ["csgo","192.168.1.2",27017],
'minecraft' : ["minecraft","192.168.1.3",2018]
}
//Convert named array data based on the chat triggers to a variable.
//This doesn't have to be done but gamedig gets a little pissy sometimes if you feed it straight arrays. No idea why.
var gameType = namedServerArrays[chatTrigger][0];
var gameHost = namedServerArrays[chatTrigger][1];
var gamePort = namedServerArrays[chatTrigger][2];
//Query server based on chatTrigger input.
Gamedig.query({
type: gameType,
host: gameHost,
port: gamePort
},
function(e,state) {
if(e){
console.log("Server is offline");
return "Server connection error.";
}else{
var playersOnline = state.players.length;
var currentMap = state.map;
//Vomit a bunch of error checking.
console.log("The " + chatTrigger + " server is online.");
console.log("Players Online: " + playersOnline);
console.log("Server map: " + currentMap);
console.log("User was given " + chatTrigger +" server connection information.");
return [playersOnline,currentMap];
}
});
//End Query
var queryReturnState = Gamedig.query();}
What my hung up is how do I return the data from the gamedig query function back to the serverInfo function so that it can then be returned by the serverInfo function to whatever is using the serverInfo function?
In its current state the console logs all the relevant data up to date and correctly but will eventually encounter a UnhandledPromiseRejectionWarming.
(node:1479) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot set property 'callback' of undefined
(node:1479) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I'm having a bit of trouble understanding how to handle promises in node.js as well.
Any help towards me getting this to work and understand better is appreciated.
Upvotes: 0
Views: 606
Reputation: 53
This was likely caused by the var queryReturnState = Gamedig.query();
at the bottom of your snippet.
According to the API, Gamedig.query
requires at least one parameter. Since the parameter was missing, it was likely trying to set callback
on that non-existent object.
Upvotes: 0
Reputation: 74630
That looks like a bug in the underlying library or an issue with the use of the library. Try using the the promise API which will at least catch the error, and possibly avoid using callbacks in the underlying gamedig library.
When using a promise API, all you need to do is return
a value or the promise of a value from your functions.
Wherever you call serverInfo()
use a .then
to handle the asynchronous promise result and then send it to the chat, whatever that may be.
serverInfo(blah).then(function(result){
chat.send(result)
})
Promised code
// Query Minecraft Server
var serverInfo = function(chatTrigger){
var namedServerArrays = {
'1v1' : ["csgo","192.168.1.1",2016],
'10man' : ["csgo","192.168.1.2",27017],
'minecraft' : ["minecraft","192.168.1.3",2018]
}
// Convert named array data based on the chat triggers to a variable.
// This doesn't have to be done but gamedig gets a little pissy sometimes if you feed it straight arrays. No idea why.
var gameType = namedServerArrays[chatTrigger][0];
var gameHost = namedServerArrays[chatTrigger][1];
var gamePort = namedServerArrays[chatTrigger][2];
//Query server based on chatTrigger input.
return Gamedig.query({
type: gameType,
host: gameHost,
port: gamePort
})
.then(function(state){
var playersOnline = state.players.length;
var currentMap = state.map;
//Vomit a bunch of error checking.
console.log("The " + chatTrigger + " server is online.");
console.log("Players Online: " + playersOnline);
console.log("Server map: " + currentMap);
console.log("User was given " + chatTrigger +" server connection information.");
return [playersOnline,currentMap];
})
.catch(function(error){
console.error(error);
return 'Server connection error';
});
}
Upvotes: 1