- Update GameDig from 5.1.0 to 5.1.4

- Errors in parsing GameDig response now throw an error instead of returning to output
- Prevents "Class constructor Players cannot be invoked without 'new'" error
  when Node-RED attempts to clone the server response data (this happens when the gamedig node feeds into a function node for example)
This commit is contained in:
Skylar Sadlier 2024-11-21 11:08:03 -07:00
parent cf94d2a787
commit c0c40910ae
3 changed files with 88 additions and 45 deletions

49
package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "3.0.0",
"license": "MIT",
"dependencies": {
"gamedig": "^5.1.0"
"gamedig": "^5.1.4"
}
},
"node_modules/@sindresorhus/is": {
@ -267,19 +267,18 @@
}
},
"node_modules/gamedig": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/gamedig/-/gamedig-5.1.0.tgz",
"integrity": "sha512-eif4dAvR9hpSPuuLcP8cGrD3d1XjNrgzgI2N9JjuObp6RepGjm31SCJfOF85Q0eQsS5VgTeHdLfTyfG4DS+cRA==",
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/gamedig/-/gamedig-5.1.4.tgz",
"integrity": "sha512-MgSbNVGh5QMdrmRTrZ3W7W6sC5/Mx+dMgTy2uZCKQ9vns9eFXkQj61Pw2Y2FNHNMMp4DXFSUMYAPJWLcR16Wwg==",
"dependencies": {
"cheerio": "^1.0.0-rc.12",
"gbxremote": "^0.2.1",
"got": "^13.0.0",
"iconv-lite": "^0.6.3",
"long": "^5.2.3",
"minimist": "^1.2.8",
"punycode": "^2.3.0",
"seek-bzip": "^2.0.0",
"varint": "^6.0.0"
"cheerio": "1.0.0-rc.12",
"gbxremote": "0.2.1",
"got": "13.0.0",
"iconv-lite": "0.6.3",
"long": "5.2.3",
"minimist": "1.2.8",
"seek-bzip": "2.0.0",
"varint": "6.0.0"
},
"bin": {
"gamedig": "bin/gamedig.js"
@ -473,22 +472,22 @@
}
},
"node_modules/parse5": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
"integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
"dependencies": {
"entities": "^4.4.0"
"entities": "^4.5.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/parse5-htmlparser2-tree-adapter": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
"integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
"integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
"dependencies": {
"domhandler": "^5.0.2",
"domhandler": "^5.0.3",
"parse5": "^7.0.0"
},
"funding": {
@ -500,14 +499,6 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"engines": {
"node": ">=6"
}
},
"node_modules/quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "node-red-contrib-gamedig",
"version": "3.0.0",
"version": "3.0.1",
"description": "Query for the status of any game server using node-red",
"repository": {
"type": "git",
@ -23,6 +23,6 @@
}
},
"dependencies": {
"gamedig": "^5.1.0"
"gamedig": "^5.1.4"
}
}

View File

@ -1,6 +1,44 @@
module.exports = function(RED) {
const { GameDig, games } = require('gamedig');
function deepCloneToPlain(obj) {
// Handle null/undefined
if (!obj) {
return obj;
}
// Handle arrays and array-like objects (including Players collection)
if (Array.isArray(obj) || (typeof obj === 'object' && obj.length >= 0)) {
return Array.from(obj, item => deepCloneToPlain(item));
}
// Handle instances of custom classes (like Player, Results)
if (obj && typeof obj === 'object' && Object.getPrototypeOf(obj) !== Object.prototype) {
// Convert to plain object while preserving enumerable properties
const plainObj = {};
for (const key of Object.keys(obj)) {
plainObj[key] = deepCloneToPlain(obj[key]);
}
return plainObj;
}
// Handle plain objects
if (obj && typeof obj === 'object') {
const result = {};
for (const key of Object.keys(obj)) {
// Skip the Buffer instance
if (key === 'rulesBytes' && Buffer.isBuffer(obj[key])) {
continue;
}
result[key] = deepCloneToPlain(obj[key]);
}
return result;
}
// Return primitive values as-is
return obj;
}
function QueryGameServer(config) {
RED.nodes.createNode(this, config);
let node = this;
@ -53,24 +91,38 @@ module.exports = function(RED) {
GameDig.query(options)
.then(function(state) {
msg.payload = 'online';
msg.data = state;
if (msg.payload === node.halt_if) {
return null;
}
node.status({fill:"green",shape:"dot",text: 'Online ' + msg.data.players.length + ' players' });
node.send(msg);
}).catch(function(error) {
try {
msg.payload = 'online';
// GameDig returns Results, Players, and Player objects that we need to convert
// to standard Array/Object instances so that Node-RED doesn't error
console.log("RESULT", state);
msg.data = deepCloneToPlain(state);
console.log("FORMATTED", msg.data);
if (msg.payload === node.halt_if) {
return null;
}
node.status({ fill: "green", shape: "dot", text: `Online ${state.players.length} players` });
node.send(msg);
} catch(e) {
node.error("Failed returning data: " + e.stack);
}
})
.catch(function(error) {
msg.payload = 'offline';
msg.data = {
'error': error
error,
stack: error.stack,
};
if (msg.payload === node.halt_if) {
return null;
}
node.status({fill:"red", shape:"dot", text: 'Offline'});
node.send(msg);
if (msg.payload === node.halt_if) {
return null;
}
node.status({ fill: "red", shape: "dot", text: "Offline" });
node.send(msg);
node.error(`GameDig Error: \n${error.stack}`);
console.error(error);
});
});
}
RED.nodes.registerType("query-game-server", QueryGameServer);