ping-minecraft-server
Version:
Ping a Minecraft Server
75 lines (74 loc) • 2.71 kB
JavaScript
;
const net_1 = require("net");
function itob(n, length) {
const result = [];
while (n > 0 || result.length < length) {
const digit = n & 0xff;
result.unshift(digit);
n >>= 8;
}
return result;
}
class PingError extends Error {
constructor(message, host, port) {
super(message);
this.host = host;
this.port = port;
}
}
function ping(host, port, options = {}) {
const socket = new net_1.Socket();
const PacketID = Buffer.from([0]);
const ProtocolVersion = Buffer.from([242, 3]);
const ServerAddressContent = Buffer.from(host, 'ascii');
const ServerAddressLength = Buffer.from(itob(ServerAddressContent.length, 1));
const ServerAddress = Buffer.concat([ServerAddressLength, ServerAddressContent]);
const ServerPort = Buffer.from(itob(port, 2));
const NextState = Buffer.from([1]);
const HandshakePacketContent = Buffer.concat([PacketID, ProtocolVersion, ServerAddress, ServerPort, NextState]);
const HandshakePacketLength = Buffer.from(itob(HandshakePacketContent.length, 1));
const HandshakePacket = Buffer.concat([HandshakePacketLength, HandshakePacketContent]);
const RequestPacket = Buffer.from([1, 0]);
const { timeout = 5000 } = options;
return new Promise((resolve, reject) => {
let response = '';
let bytes = 0;
let length = -1;
socket.on('data', (data) => {
let offset = 0;
if (length < 0) {
const lowerByte = data[3];
const higherByte = data[4];
length = ((higherByte & 0x7f) << 7) | (lowerByte & 0x7f);
offset = 5;
}
response += data.slice(offset).toString();
bytes += data.slice(offset).length;
if (bytes >= length) {
try {
resolve(JSON.parse(response));
}
catch (error) {
reject(new PingError('parse-error', host, port));
}
}
});
socket.setTimeout(timeout, () => {
socket.end();
if (!response)
reject(new PingError('connect-timeout', host, port));
});
socket.on('error', () => {
socket.destroy();
reject(new PingError('connect-error', host, port));
});
socket.connect(port, host, () => {
socket.write(HandshakePacket);
socket.write(RequestPacket);
});
});
}
(function (ping) {
ping.Error = PingError;
})(ping || (ping = {}));
module.exports = ping;