prettyify code
This commit is contained in:
221
lib/ping.js
221
lib/ping.js
@ -1,159 +1,212 @@
|
||||
const minecraftJavaPing = require('mcping-js')
|
||||
const minecraftBedrockPing = require('mcpe-ping-fixed')
|
||||
const minecraftJavaPing = require("mcping-js");
|
||||
const minecraftBedrockPing = require("mcpe-ping-fixed");
|
||||
|
||||
const logger = require('./logger')
|
||||
const MessageOf = require('./message')
|
||||
const { TimeTracker } = require('./time')
|
||||
const logger = require("./logger");
|
||||
const MessageOf = require("./message");
|
||||
const { TimeTracker } = require("./time");
|
||||
|
||||
const { getPlayerCountOrNull } = require('./util')
|
||||
const { getPlayerCountOrNull } = require("./util");
|
||||
|
||||
const config = require('../config')
|
||||
const config = require("../config");
|
||||
|
||||
function ping (serverRegistration, timeout, callback, version) {
|
||||
function ping(serverRegistration, timeout, callback, version) {
|
||||
switch (serverRegistration.data.type) {
|
||||
case 'PC':
|
||||
case "PC":
|
||||
serverRegistration.dnsResolver.resolve((host, port, remainingTimeout) => {
|
||||
const server = new minecraftJavaPing.MinecraftServer(host, port || 25565)
|
||||
const server = new minecraftJavaPing.MinecraftServer(
|
||||
host,
|
||||
port || 25565
|
||||
);
|
||||
|
||||
server.ping(remainingTimeout, version, (err, res) => {
|
||||
if (err) {
|
||||
callback(err)
|
||||
callback(err);
|
||||
} else {
|
||||
const payload = {
|
||||
players: {
|
||||
online: capPlayerCount(serverRegistration.data.ip, parseInt(res.players.online))
|
||||
online: capPlayerCount(
|
||||
serverRegistration.data.ip,
|
||||
parseInt(res.players.online)
|
||||
),
|
||||
},
|
||||
version: parseInt(res.version.protocol)
|
||||
}
|
||||
version: parseInt(res.version.protocol),
|
||||
};
|
||||
|
||||
// Ensure the returned favicon is a data URI
|
||||
if (res.favicon && res.favicon.startsWith('data:image/')) {
|
||||
payload.favicon = res.favicon
|
||||
if (res.favicon && res.favicon.startsWith("data:image/")) {
|
||||
payload.favicon = res.favicon;
|
||||
}
|
||||
|
||||
callback(null, payload)
|
||||
callback(null, payload);
|
||||
}
|
||||
})
|
||||
})
|
||||
break
|
||||
});
|
||||
});
|
||||
break;
|
||||
|
||||
case 'PE':
|
||||
minecraftBedrockPing(serverRegistration.data.ip, serverRegistration.data.port || 19132, (err, res) => {
|
||||
if (err) {
|
||||
callback(err)
|
||||
} else {
|
||||
callback(null, {
|
||||
players: {
|
||||
online: capPlayerCount(serverRegistration.data.ip, parseInt(res.currentPlayers))
|
||||
}
|
||||
})
|
||||
}
|
||||
}, timeout)
|
||||
break
|
||||
case "PE":
|
||||
minecraftBedrockPing(
|
||||
serverRegistration.data.ip,
|
||||
serverRegistration.data.port || 19132,
|
||||
(err, res) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
callback(null, {
|
||||
players: {
|
||||
online: capPlayerCount(
|
||||
serverRegistration.data.ip,
|
||||
parseInt(res.currentPlayers)
|
||||
),
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
timeout
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error('Unsupported type: ' + serverRegistration.data.type)
|
||||
throw new Error("Unsupported type: " + serverRegistration.data.type);
|
||||
}
|
||||
}
|
||||
|
||||
// player count can be up to 1^32-1, which is a massive scale and destroys browser performance when rendering graphs
|
||||
// Artificially cap and warn to prevent propogating garbage
|
||||
function capPlayerCount (host, playerCount) {
|
||||
const maxPlayerCount = 250000
|
||||
function capPlayerCount(host, playerCount) {
|
||||
const maxPlayerCount = 250000;
|
||||
|
||||
if (playerCount !== Math.min(playerCount, maxPlayerCount)) {
|
||||
logger.log('warn', '%s returned a player count of %d, Minetrack has capped it to %d to prevent browser performance issues with graph rendering. If this is in error, please edit maxPlayerCount in ping.js!', host, playerCount, maxPlayerCount)
|
||||
logger.log(
|
||||
"warn",
|
||||
"%s returned a player count of %d, Minetrack has capped it to %d to prevent browser performance issues with graph rendering. If this is in error, please edit maxPlayerCount in ping.js!",
|
||||
host,
|
||||
playerCount,
|
||||
maxPlayerCount
|
||||
);
|
||||
|
||||
return maxPlayerCount
|
||||
return maxPlayerCount;
|
||||
} else if (playerCount !== Math.max(playerCount, 0)) {
|
||||
logger.log('warn', '%s returned an invalid player count of %d, setting to 0.', host, playerCount)
|
||||
logger.log(
|
||||
"warn",
|
||||
"%s returned an invalid player count of %d, setting to 0.",
|
||||
host,
|
||||
playerCount
|
||||
);
|
||||
|
||||
return 0
|
||||
return 0;
|
||||
}
|
||||
return playerCount
|
||||
return playerCount;
|
||||
}
|
||||
|
||||
class PingController {
|
||||
constructor (app) {
|
||||
this._app = app
|
||||
this._isRunningTasks = false
|
||||
constructor(app) {
|
||||
this._app = app;
|
||||
this._isRunningTasks = false;
|
||||
}
|
||||
|
||||
schedule () {
|
||||
setInterval(this.pingAll, config.rates.pingAll)
|
||||
schedule() {
|
||||
setInterval(this.pingAll, config.rates.pingAll);
|
||||
|
||||
this.pingAll()
|
||||
this.pingAll();
|
||||
}
|
||||
|
||||
pingAll = () => {
|
||||
const { timestamp, updateHistoryGraph } = this._app.timeTracker.newPointTimestamp()
|
||||
const { timestamp, updateHistoryGraph } =
|
||||
this._app.timeTracker.newPointTimestamp();
|
||||
|
||||
this.startPingTasks(results => {
|
||||
const updates = []
|
||||
this.startPingTasks((results) => {
|
||||
const updates = [];
|
||||
|
||||
for (const serverRegistration of this._app.serverRegistrations) {
|
||||
const result = results[serverRegistration.serverId]
|
||||
const result = results[serverRegistration.serverId];
|
||||
|
||||
// Log to database if enabled
|
||||
// Use null to represent a failed ping
|
||||
if (config.logToDatabase) {
|
||||
const unsafePlayerCount = getPlayerCountOrNull(result.resp)
|
||||
const unsafePlayerCount = getPlayerCountOrNull(result.resp);
|
||||
|
||||
this._app.database.insertPing(serverRegistration.data.ip, timestamp, unsafePlayerCount)
|
||||
this._app.database.insertPing(
|
||||
serverRegistration.data.ip,
|
||||
timestamp,
|
||||
unsafePlayerCount
|
||||
);
|
||||
}
|
||||
|
||||
// Generate a combined update payload
|
||||
// This includes any modified fields and flags used by the frontend
|
||||
// This will not be cached and can contain live metadata
|
||||
const update = serverRegistration.handlePing(timestamp, result.resp, result.err, result.version, updateHistoryGraph)
|
||||
const update = serverRegistration.handlePing(
|
||||
timestamp,
|
||||
result.resp,
|
||||
result.err,
|
||||
result.version,
|
||||
updateHistoryGraph
|
||||
);
|
||||
|
||||
updates[serverRegistration.serverId] = update
|
||||
updates[serverRegistration.serverId] = update;
|
||||
}
|
||||
|
||||
// Send object since updates uses serverIds as keys
|
||||
// Send a single timestamp entry since it is shared
|
||||
this._app.server.broadcast(MessageOf('updateServers', {
|
||||
timestamp: TimeTracker.toSeconds(timestamp),
|
||||
updateHistoryGraph,
|
||||
updates
|
||||
}))
|
||||
})
|
||||
}
|
||||
this._app.server.broadcast(
|
||||
MessageOf("updateServers", {
|
||||
timestamp: TimeTracker.toSeconds(timestamp),
|
||||
updateHistoryGraph,
|
||||
updates,
|
||||
})
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
startPingTasks = (callback) => {
|
||||
if (this._isRunningTasks) {
|
||||
logger.log('warn', 'Started re-pinging servers before the last loop has finished! You may need to increase "rates.pingAll" in config.json')
|
||||
logger.log(
|
||||
"warn",
|
||||
'Started re-pinging servers before the last loop has finished! You may need to increase "rates.pingAll" in config.json'
|
||||
);
|
||||
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
this._isRunningTasks = true
|
||||
this._isRunningTasks = true;
|
||||
|
||||
const results = []
|
||||
const results = [];
|
||||
|
||||
for (const serverRegistration of this._app.serverRegistrations) {
|
||||
const version = serverRegistration.getNextProtocolVersion()
|
||||
const version = serverRegistration.getNextProtocolVersion();
|
||||
|
||||
ping(serverRegistration, config.rates.connectTimeout, (err, resp) => {
|
||||
if (err && config.logFailedPings !== false) {
|
||||
logger.log('error', 'Failed to ping %s: %s', serverRegistration.data.ip, err.message)
|
||||
}
|
||||
ping(
|
||||
serverRegistration,
|
||||
config.rates.connectTimeout,
|
||||
(err, resp) => {
|
||||
if (err && config.logFailedPings !== false) {
|
||||
logger.log(
|
||||
"error",
|
||||
"Failed to ping %s: %s",
|
||||
serverRegistration.data.ip,
|
||||
err.message
|
||||
);
|
||||
}
|
||||
|
||||
results[serverRegistration.serverId] = {
|
||||
resp,
|
||||
err,
|
||||
version
|
||||
}
|
||||
results[serverRegistration.serverId] = {
|
||||
resp,
|
||||
err,
|
||||
version,
|
||||
};
|
||||
|
||||
if (Object.keys(results).length === this._app.serverRegistrations.length) {
|
||||
// Loop has completed, release the locking flag
|
||||
this._isRunningTasks = false
|
||||
if (
|
||||
Object.keys(results).length === this._app.serverRegistrations.length
|
||||
) {
|
||||
// Loop has completed, release the locking flag
|
||||
this._isRunningTasks = false;
|
||||
|
||||
callback(results)
|
||||
}
|
||||
}, version.protocolId)
|
||||
callback(results);
|
||||
}
|
||||
},
|
||||
version.protocolId
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = PingController
|
||||
module.exports = PingController;
|
||||
|
Reference in New Issue
Block a user