These are four functions used to extract and parse information from server-related input strings:
getServersResponse
and statusResponse
extract server information, while infoResponse
extracts server information in a simplified format. The function parseConfigStr
parses configuration strings into objects.npm run import -- "quake 3 server responses"
function getServersResponse(m) {
var masters = []
m = m.slice('getserversResponse'.length)
for(var i = 0; i < m.length / 7; i++) {
var ip = i*7+1
if(m[ip-1] !== '\\'.charCodeAt(0)) continue
if(m.slice(ip, ip+3) == 'EOT') continue
var master = {
ip: m[ip] + '.' + m[ip+1] + '.' + m[ip+2] + '.' + m[ip+3],
port: (m[ip+4] << 8) + m[ip+5],
}
masters.push(master)
}
return masters
}
function parseConfigStr(m) {
return m.toString('utf-8')
.trim().split(/\n/ig)[0]
.trim().split(/\\/ig).slice(1)
.reduce((obj, c, i, arr) => {
if(i & 1) {
obj[arr[i-1].toLowerCase()] = c
obj[arr[i-1]] = c
}
return obj
}, {})
}
function statusResponse(m) {
m = m.slice('statusResponse'.length)
var status = parseConfigStr(m)
var players = m.toString('utf-8')
.trim().split(/\n/ig)
.slice(1)
.reduce((obj, c, i, arr) => {
if(c.trim().length == 0)
return obj
var player = {
'i': (i + 1),
'name': (/[0-9]+\s+[0-9]+\s+"(.*)"/ig).exec(c)[1],
'score': (/([0-9]+)\s+/ig).exec(c)[1],
'ping': (/[0-9]+\s+([0-9]+)\s+/ig).exec(c)[1],
}
player.isBot = player.ping == 0
obj.push(player)
return obj
}, [])
return Object.assign(status, {players})
}
function infoResponse(m) {
m = m.slice('infoResponse'.length)
return parseConfigStr(m)
}
module.exports = {
getServersResponse,
statusResponse,
infoResponse,
parseConfigStr,
}
/**
* A module to handle Minecraft server responses.
* @module serverResponses
*/
const { parse } = require('node:util');
/**
* Extracts a list of Minecraft servers from a response string.
* @param {string} m The response string.
* @returns {object[]} A list of server objects.
*/
function getServersResponse(m) {
const sliceLength = 'getserversResponse'.length;
const chunkSize = 7;
const servers = [];
m = m.slice(sliceLength);
for (let i = 0; i < m.length; i += chunkSize) {
const chunk = m.slice(i, i + chunkSize);
if (chunk[0]!== 92 || chunk.slice(0, 3) === 'EOT') continue;
const ip = chunk.slice(1, 5).join('.');
const port = (chunk[5] << 8) + chunk[6];
servers.push({ ip, port });
}
return servers;
}
/**
* Parses a configuration string and returns an object.
* @param {string} m The configuration string.
* @returns {object} A parsed configuration object.
*/
function parseConfigStr(m) {
return parseConfig(m.toString('utf-8').trim().split(/\n/g)[0].trim().split(/\\/g).slice(1).map((chunk, index, arr) => {
return index & 1? { [arr[index - 1].toLowerCase()]: chunk, [arr[index - 1]]: chunk } : {};
}).reduce((obj, config) => Object.assign(obj, config), {}));
}
/**
* Processes a'statusResponse' string and returns an object containing server status and player information.
* @param {string} m The'statusResponse' string.
* @returns {object} An object containing server status and player information.
*/
function statusResponse(m) {
const sliceLength ='statusResponse'.length;
const status = parseConfigStr(m.slice(sliceLength));
const players = m.toString('utf-8').trim().split(/\n/g).slice(1).map((line, index) => {
if (!line.trim()) return null;
const player = {
i: index + 1,
name: line.match(/([0-9]+\s+[0-9]+\s+"(.*)"/g)[0],
score: line.match(/([0-9]+)\s+/g)[0],
ping: line.match(/([0-9]+\s+([0-9]+)\s+/g)[0],
};
player.isBot = player.ping === '0';
return player;
}).filter(Boolean);
return Object.assign(status, { players });
}
/**
* Processes an 'infoResponse' string and returns an object containing server information.
* @param {string} m The 'infoResponse' string.
* @returns {object} An object containing server information.
*/
function infoResponse(m) {
const sliceLength = 'infoResponse'.length;
return parseConfigStr(m.slice(sliceLength));
}
module.exports = {
getServersResponse,
statusResponse,
infoResponse,
parseConfigStr,
};
m
.m
- The input string containing server information.m
.m
in increments of 7, checking for invalid characters.masters
array.m
- The input string containing configuration information.m
.m
- The input string containing server status information.m
.parseConfigStr
.players
array.m
.m
- The input string containing server information.m
.parseConfigStr
.The functions getServersResponse
, statusResponse
, infoResponse
, and parseConfigStr
are exported as a module.