Merge pull request #2 from skylord123/dev

update version to 2.1.1
This commit is contained in:
Skylar Sadlier 2021-09-04 23:01:58 -06:00 committed by GitHub
commit f6078118c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1441 additions and 69 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
# ide
.idea
# Logs
logs
*.log

View File

@ -1,6 +1,6 @@
# node-red-contrib-gamedig
Query for the status of any game server using Node-RED.
Query for the status of most game/voice servers using Node-RED.
This package adds the node "Query Game Server" that uses the NPM package [GameDig](https://www.npmjs.com/package/gamedig) to query if a server is online or not and if so returns the data of the server.
@ -12,6 +12,10 @@ You can pass the server type, host, and port on the input message or define them
I created a post on my website about how to use this node to query gameservers and store the results in InfluxDB. I then give a dashboard in Grafana that can be used to display the data. Check it out here:
https://skylar.tech/tracking-game-server-statistics-using-node-red-influxdb-and-grafana/
### Other Packages
- [node-red-contrib-matrix-chat](https://www.npmjs.com/package/node-red-contrib-gamedig) - Matrix chat server client for Node-RED
### Developers
So far me (skylord123) is the only person that has contributed towards this package. Feel free to do any pull-requests to get your name here!

1275
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "node-red-contrib-gamedig",
"version": "2.0.1",
"version": "2.1.1",
"description": "Query for the status of any game server using node-red",
"repository": {
"type": "git",
@ -12,13 +12,17 @@
"url": "https://github.com/skylord123/node-red-contrib-gamedig/issues"
},
"homepage": "https://github.com/skylord123/node-red-contrib-gamedig#readme",
"keywords": [ "node-red", "gamedig", "query game server" ],
"keywords": [
"node-red",
"gamedig",
"query game server"
],
"node-red": {
"nodes": {
"query-game-server": "query-game-server.js"
}
},
"dependencies": {
"gamedig": "^2.0.0"
"gamedig": "^3.0.0"
}
}

View File

@ -4,8 +4,8 @@
color: '#a6bbcf',
defaults: {
name: { value: '' },
server_type: { value: '', required: true },
host: { value: '', required: true },
server_type: { value: '' },
host: { value: '' },
port: { value: '' },
halt_if: { value: '' },
max_attempts: { value: '' },
@ -15,6 +15,7 @@
inputs:1,
outputs:1,
icon: "icons/server.png",
paletteLabel: "Query Game Server",
label: function() {
if(this.name){
return this.name;
@ -25,11 +26,36 @@
}
return 'Query Game Server';
},
oneditprepare: function() {
$.getJSON('/gamedig/types', function(data) {
let html = '<table>' +
'<thead id="query-game-server-types-table"><tr><td><strong>Type</strong></td><td><strong>Name</strong></td></tr></thead>' +
'<tbody id="query-game-server-type-rows">';
for(var type in data) {
html += "<tr class=\"query-game-server-type-row\">" +
"<td>"+type+"</td>" +
"<td>"+data[type]+"</td>" +
"</tr>";
}
html += '</tbody>' +
'</table>';
$("#query-game-server-types").html(html);
});
}
});
</script>
<script type="text/x-red" data-template-name="query-game-server">
<script type="text/html" data-template-name="query-game-server">
<style>
#query-game-server-types table, #query-game-server-types th, #query-game-server-types td {
border: 1px solid black;
border-collapse: collapse;
}
#query-game-server-types td {
padding: 3px;
}
</style>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
@ -39,27 +65,26 @@
<label for="node-input-server_type"><i class="fa fa-cube"></i> Server Type</label>
<input type="text" id="node-input-server_type">
</div>
<div class="form-row">
<label>&nbsp;</label>
<span>Check <a href="https://github.com/sonicsnes/node-gamedig#games-list" style="color:#0000EE;" target="_blank">here</a> for a list of supported server types.</span>
<div style="margin-left: 105px;width: 50%;margin-bottom: 10px;margin-top: -10px;">
View server types <a href="#gamdig-types" style="color:#0000EE;text-decoration: underline;">below</a>.
</div>
<div class="form-row">
<label for="node-input-host"><i class="fa fa-server"></i> Host</label>
<input type="text" id="node-input-host" />
<input type="text" id="node-input-host" placeholder="msg.host" />
</div>
<div class="form-row">
<label>&nbsp;</label>
<span>Host without port</span>
<div style="margin-left: 105px;width: 50%;margin-bottom: 10px;margin-top: -10px;">
Host without port. Uses <code>msg.host</code> if left blank.
</div>
<div class="form-row">
<label for="node-input-port"><i class="fa fa-server"></i> Port</label>
<input type="text" id="node-input-port" />
<label for="node-input-port"><i class="fa fa-ethernet"></i> Port</label>
<input type="text" id="node-input-port" placeholder="msg.host" />
</div>
<div class="form-row">
<label>&nbsp;</label>
<span>Query port for the server (not always the same as the join port). If this is left blank it will use the default port for the server type specified.</span>
<div style="margin-left: 105px;width: 50%;margin-bottom: 10px;margin-top: -10px;">
Query port for the server (join and query port may differ).
If this is left blank it will use the default port for the server type specified.
Uses <code>msg.port</code> if left blank.
</div>
<div class="form-row">
@ -70,112 +95,145 @@
<option value="offline">Offline</option>
</select>
</div>
<div class="form-row">
<label>&nbsp;</label>
<span>Enter "online" or "offline" (without quotes) to filter out the state you don't want.</span>
<div style="margin-left: 105px;width: 50%;margin-bottom: 10px;margin-top: -10px;">
Filter messages based on server status
</div>
<div class="form-row">
<label for="node-input-max_attempts"><i class="fa fa-server"></i> Max Attempts</label>
<label for="node-input-max_attempts"><i class="fa fa-cogs"></i> Max Attempts</label>
<input type="text" id="node-input-max_attempts" placeholder="1" />
</div>
<div class="form-row">
<label>&nbsp;</label>
<span>Number of attempts to query server in case of failure.</span>
<div style="margin-left: 105px;width: 50%;margin-bottom: 10px;margin-top: -10px;">
Number of attempts to query server in case of failure.
</div>
<div class="form-row">
<label for="node-input-socket_timeout"><i class="fa fa-server"></i> Socket Timeout</label>
<label for="node-input-socket_timeout"><i class="fa fa-cogs"></i> Socket Timeout</label>
<input type="text" id="node-input-socket_timeout" placeholder="2000" />
</div>
<div class="form-row">
<label>&nbsp;</label>
<span>Milliseconds to wait for a single packet. Beware that increasing this will cause many queries to take longer even if the server is online.</span>
<div style="margin-left: 105px;width: 50%;margin-bottom: 10px;margin-top: -10px;">
Milliseconds to wait for a single packet. Beware that increasing this will cause many queries to take longer even if the server is online.
</div>
<div class="form-row">
<label for="node-input-attempt_timeout"><i class="fa fa-server"></i> Attempt Timeout</label>
<label for="node-input-attempt_timeout"><i class="fas fa-cogs"></i> Attempt Timeout</label>
<input type="text" id="node-input-attempt_timeout" placeholder="10000" />
</div>
<div class="form-row">
<label>&nbsp;</label>
<span>Milliseconds allowed for an entire query attempt. This timeout is not commonly hit, as the socketTimeout typically fires first.</span>
<div style="margin-left: 105px;width: 50%;margin-bottom: 10px;margin-top: -10px;">
Milliseconds allowed for an entire query attempt. This timeout is not commonly hit, as the socketTimeout typically fires first.
</div>
<h3 id="gamdig-types">Server Types</h3>
<p>
Search available types below.<br>
You can also view the list <a href="https://github.com/gamedig/node-gamedig#games-list" target="_blank" style="color:#0000EE;text-decoration: underline;">here</a>.
</p>
<div class="row">
<input type="text" id="query-game-server-types-search" placeholder="Search types.." style="margin-bottom: 10px;" />
</div>
<div id="query-game-server-types"></div>
<script type="text/javascript">
$("#query-game-server-types-search").on("input", function(e) {
let value = $(this).val();
if(value.length) {
$(".query-game-server-type-row").each(function(i, elem){
console.log('yay', $(elem).text(), value, $(elem).text().indexOf(value));
if($(elem).text().toLowerCase().indexOf(value.toLowerCase()) > -1) {
$(elem).show();
} else {
$(elem).hide();
}
});
return;
}
$(".query-game-server-type-row").show();
});
</script>
</script>
<script type="text/x-red" data-help-name="query-game-server">
<p>Query a Game Server</p>
<h3>Config</h3>
<dl class="message-properties">
<dt>Server Type <span class="property-type">string</span></dt>
<dt>Host <span class="property-type">string</span></dt>
<dt>Port <span class="property-type">integer</span></dt>
<dt>Halt If <span class="property-type">string</span></dt>
</dl>
<script type="text/html" data-help-name="query-game-server">
<p>Query most Game/Voice server's using the <a href="https://github.com/gamedig/node-gamedig" target="_blank">GameDig</a> library.</p>
<h3>Inputs</h3>
<dl class="message-properties">
<dt class="optional">
msg.server_type <span class="property-type">string</span>
msg.server_type <span class="property-type">string | null</span>
</dt>
<dd>Server type to query. Check <a href="https://github.com/sonicsnes/node-gamedig#games-list" style="color:#0000EE;" target="_blank">here</a> for a list of supported server types</dd>
<dd>Server type to query. View available types either at the bottom of the node editor or <a href="https://github.com/sonicsnes/node-gamedig#games-list" style="color:#0000EE;" target="_blank">click here</a>. Ignored if configured on the node.</dd>
<dt class="optional">
msg.host <span class="property-type">string</span>
msg.host <span class="property-type">string | null</span>
</dt>
<dd>Server IP/Hostname</dd>
<dd>Server IP/Hostname. Ignored if configured on the node.</dd>
<dt class="optional">
msg.port <span class="property-type">integer</span>
msg.port <span class="property-type">integer | null</span>
</dt>
<dd>Query port of the server</dd>
<dd>Query port of the server. Ignored if configured on the node. Uses default query port for the server type if left empty.</dd>
<dt class="optional">
msg.max_attempts <span class="property-type">integer</span>
msg.max_attempts <span class="property-type">integer | null</span>
</dt>
<dd>Number of attempts to query server in case of failure.</dd>
<dd>Number of attempts to query server in case of failure. Ignored if configured on the node.</dd>
<dt class="optional">
msg.socket_timeout <span class="property-type">integer</span>
msg.socket_timeout <span class="property-type">integer | null</span>
</dt>
<dd>Milliseconds to wait for a single packet. Beware that increasing this will cause many queries to take longer even if the server is online.</dd>
<dd>Milliseconds to wait for a single packet. Beware that increasing this will cause many queries to take longer even if the server is online. Ignored if configured on the node.</dd>
<dt class="optional">
msg.attempt_timeout <span class="property-type">integer</span>
msg.attempt_timeout <span class="property-type">integer | null</span>
</dt>
<dd>Milliseconds allowed for an entire query attempt. This timeout is not commonly hit, as the socketTimeout typically fires first.</dd>
<dd>Milliseconds allowed for an entire query attempt. This timeout is not commonly hit, as the socketTimeout typically fires first. Ignored if configured on the node.</dd>
</dl>
<h3>Outputs</h3>
<dl class="message-properties">
<dt>
msg.payload <span class="property-type">string</span>
</dt>
<dd>Returns either <code>online</code> or <code>offline</code> depending on if we successfully query the server or not.</dd>
<dd>Returns either <code>online</code> or <code>offline</code>.</dd>
<dt>
msg.data <span class="property-type">object</span>
</dt>
<dd>Returns back the data we got from GameDig. Click <a href="https://github.com/sonicsnes/node-gamedig#return-value" style="color:#0000EE;">here</a> for more information on what this contains.</dd>
<dd>Returns back the results we got from GameDig. Click <a href="https://github.com/sonicsnes/node-gamedig#return-value" target="_blank" style="color:#0000EE;">here</a> for more information on what this contains.</dd>
<dt>
msg.data.error <span class="property-type">string</span>
</dt>
<dd>Reason the server failed to query. Only returns if <code>msg.payload</code> is <code>offline</code>.</dd>
<dt>
msg.server_type <span class="property-type">string</span>
</dt>
<dt>
msg.server_type <span class="property-type">string</span>
</dt>
<dd>Server type to query. View available types either at the bottom of the node editor or <a href="https://github.com/sonicsnes/node-gamedig#games-list" style="color:#0000EE;" target="_blank">click here</a>. Ignored if configured on the node.</dd>
<dt>
msg.host <span class="property-type">string</span>
</dt>
<dd>Server IP/Hostname. Ignored if configured on the node.</dd>
<dt>
msg.port <span class="property-type">integer</span>
</dt>
<dt>
msg.halt_if <span class="property-type">string</span>
</dt>
<dd>Query port of the server. Ignored if configured on the node.</dd>
<dt>
msg.max_attempts <span class="property-type">integer</span>
</dt>
<dd>Number of attempts to query server in case of failure. Ignored if configured on the node.</dd>
<dt>
msg.socket_timeout <span class="property-type">integer</span>
</dt>
<dd>Milliseconds to wait for a single packet. Beware that increasing this will cause many queries to take longer even if the server is online. Ignored if configured on the node.</dd>
<dt>
msg.attempt_timeout <span class="property-type">integer</span>
</dt>
<dd>Milliseconds allowed for an entire query attempt. This timeout is not commonly hit, as the socketTimeout typically fires first. Ignored if configured on the node.</dd>
</dl>
</script>

View File

@ -1,8 +1,10 @@
var Gamedig = require('gamedig');
module.exports = function(RED) {
const gamedig = require('gamedig');
const fs = require('fs');
function QueryGameServer(config) {
RED.nodes.createNode(this, config);
var node = this;
this.server_type = config.server_type;
this.host = config.host;
this.port = config.port;
@ -10,9 +12,7 @@ module.exports = function(RED) {
this.max_attempts = config.max_attempts || 1;
this.socket_timeout = config.socket_timeout || 2000;
this.attempt_timeout = config.attempt_timeout || 10000;
var node = this;
node.on('input', function(msg) {
if(node.server_type) {
msg.server_type = node.server_type;
}
@ -20,6 +20,10 @@ module.exports = function(RED) {
if(node.host) {
msg.host = node.host;
}
if(!msg.host) {
node.error("msg.host missing from input.");
return;
}
if(node.port) {
msg.port = node.port;
@ -41,7 +45,7 @@ module.exports = function(RED) {
msg.attempt_timeout = node.attempt_timeout;
}
Gamedig.query({
gamedig.query({
'type': msg.server_type,
'host': msg.host,
'port': msg.port,
@ -66,9 +70,33 @@ module.exports = function(RED) {
return null;
}
node.status({fill:"red", shape:"dot", text: 'Offline'});
node.send(msg);
node.send(msg);
});
});
}
RED.nodes.registerType("query-game-server", QueryGameServer);
RED.httpAdmin.get(
"/gamedig/types",
RED.auth.needsPermission('gamedig.types'),
function(req, res) {
// gamedig has no way of listing available server types
// so we just use regex to parse the info from the README
// this could break so we also reference the gamedig repo
let availableTypes = fs.readFileSync(require.resolve("gamedig/README.md"))
.toString()
.matchAll(/^\| `(.*)` * \| ([a-zA-Z: (0-9)\-'.]*)/gm),
results = {};
for (const match of availableTypes) {
if(match[1].indexOf("`<br>`") >= 0) {
let names = match[1].split("`<br>`");
results[names[0]] = match[2];
results[names[1]] = match[2];
} else {
results[match[1]] = match[2];
}
}
res.json(results);
});
};