Merge branch 'master' of https://github.com/Cryptkeeper/Minetrack into uplot
This commit is contained in:
commit
9bdc892815
@ -9,10 +9,6 @@
|
|||||||
"pingAll": 3000,
|
"pingAll": 3000,
|
||||||
"connectTimeout": 2500
|
"connectTimeout": 2500
|
||||||
},
|
},
|
||||||
"performance": {
|
|
||||||
"skipUnfurlSrv": false,
|
|
||||||
"unfurlSrvCacheTtl": 120000
|
|
||||||
},
|
|
||||||
"logToDatabase": false,
|
"logToDatabase": false,
|
||||||
"graphDuration": 86400000,
|
"graphDuration": 86400000,
|
||||||
"serverGraphDuration": 180000
|
"serverGraphDuration": 180000
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
**5.5.0** *(May 11 2020)*
|
**5.5.0** *(May 11 2020)*
|
||||||
|
|
||||||
**IMPORTANT**
|
**IMPORTANT**
|
||||||
@ -14,6 +15,14 @@ This update moves ping timestamps to a shared timestamp per round. Meaning that
|
|||||||
- Removes the mobile browser detection/manual historical graph load request. It is now automatically loaded given its smaller size.
|
- Removes the mobile browser detection/manual historical graph load request. It is now automatically loaded given its smaller size.
|
||||||
|
|
||||||
Faster, smaller, more features.
|
Faster, smaller, more features.
|
||||||
|
=======
|
||||||
|
**5.4.3** *(May 14 2020)*
|
||||||
|
- Added support for the optional field `config->skipSrvTimeout` in `config.json`. If a configured server does not return a valid response when unfurling potential SRV records, it will avoid re-unfurling SRV records for this duration in milliseconds. Use a value of `0` to disable this feature altogether.
|
||||||
|
- Removes support for the `config->performance->skipUnfurlSrv` and `config->performance->unfurlSrvCacheTtl` fields in `config.json
|
||||||
|
|
||||||
|
**5.4.2** *(May 13 2020)*
|
||||||
|
- Fixes a typo causing `_minecraft._tcp.*` SRV records to not resolve.
|
||||||
|
>>>>>>> 0e5859a82953b9d67ea759a3235080eaf7dbe74c
|
||||||
|
|
||||||
**5.4.1** *(May 10 2020)*
|
**5.4.1** *(May 10 2020)*
|
||||||
- Adds warnings when the system is pinging more frequently than it is getting replies.
|
- Adds warnings when the system is pinging more frequently than it is getting replies.
|
||||||
|
@ -18,7 +18,7 @@ class Database {
|
|||||||
|
|
||||||
loadGraphPoints (graphDuration, callback) {
|
loadGraphPoints (graphDuration, callback) {
|
||||||
// Query recent pings
|
// Query recent pings
|
||||||
const endTime = new Date().getTime()
|
const endTime = TimeTracker.getEpochMillis()
|
||||||
const startTime = endTime - graphDuration
|
const startTime = endTime - graphDuration
|
||||||
|
|
||||||
this.getRecentPings(startTime, endTime, pingData => {
|
this.getRecentPings(startTime, endTime, pingData => {
|
||||||
|
76
lib/dns.js
Normal file
76
lib/dns.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
const dns = require('dns')
|
||||||
|
|
||||||
|
const logger = require('./logger')
|
||||||
|
|
||||||
|
const { TimeTracker } = require('./time')
|
||||||
|
|
||||||
|
const config = require('../config')
|
||||||
|
|
||||||
|
const SKIP_SRV_TIMEOUT = config.skipSrvTimeout || 60 * 60 * 1000
|
||||||
|
|
||||||
|
class DNSResolver {
|
||||||
|
constructor (ip, port) {
|
||||||
|
this._ip = ip
|
||||||
|
this._port = port
|
||||||
|
}
|
||||||
|
|
||||||
|
_skipSrv () {
|
||||||
|
this._skipSrvUntil = TimeTracker.getEpochMillis() + SKIP_SRV_TIMEOUT
|
||||||
|
}
|
||||||
|
|
||||||
|
_isSkipSrv () {
|
||||||
|
return this._skipSrvUntil && TimeTracker.getEpochMillis() <= this._skipSrvUntil
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve (callback) {
|
||||||
|
if (this._isSkipSrv()) {
|
||||||
|
callback(this._ip, this._port, config.rates.connectTimeout)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const startTime = TimeTracker.getEpochMillis()
|
||||||
|
|
||||||
|
let callbackFired = false
|
||||||
|
|
||||||
|
const fireCallback = (ip, port) => {
|
||||||
|
if (!callbackFired) {
|
||||||
|
callbackFired = true
|
||||||
|
|
||||||
|
// Send currentTime - startTime to provide remaining connectionTime allowance
|
||||||
|
callback(ip || this._ip, port || this._port, TimeTracker.getEpochMillis() - startTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeoutCallback = setTimeout(fireCallback, config.rates.connectTimeout)
|
||||||
|
|
||||||
|
dns.resolveSrv('_minecraft._tcp.' + this._ip, (err, records) => {
|
||||||
|
// Cancel the timeout handler if not already fired
|
||||||
|
if (!callbackFired) {
|
||||||
|
clearTimeout(timeoutCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test if the error indicates a miss, or if the records returned are empty
|
||||||
|
if ((err && (err.code === 'ENOTFOUND' || err.code === 'ENODATA')) || !records || records.length === 0) {
|
||||||
|
// Compare config.skipSrvTimeout directly since SKIP_SRV_TIMEOUT has an or'd value
|
||||||
|
// isValidSkipSrvTimeout == whether the config has a valid skipSrvTimeout value set
|
||||||
|
const isValidSkipSrvTimeout = typeof config.skipSrvTimeout === 'number' && config.skipSrvTimeout > 0
|
||||||
|
|
||||||
|
// Only activate _skipSrv if the skipSrvTimeout value is either NaN or > 0
|
||||||
|
// 0 represents a disabled flag
|
||||||
|
if (!this._isSkipSrv() && isValidSkipSrvTimeout) {
|
||||||
|
this._skipSrv()
|
||||||
|
|
||||||
|
logger.log('warn', 'No SRV records were resolved for %s. Minetrack will skip attempting to resolve %s SRV records for %d minutes.', this._ip, this._ip, SKIP_SRV_TIMEOUT / (60 * 1000))
|
||||||
|
}
|
||||||
|
|
||||||
|
fireCallback()
|
||||||
|
} else {
|
||||||
|
// Only fires if !err && records.length > 0
|
||||||
|
fireCallback(records[0].name, records[0].port)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DNSResolver
|
@ -9,7 +9,7 @@ winston.add(winston.transports.File, {
|
|||||||
winston.add(winston.transports.Console, {
|
winston.add(winston.transports.Console, {
|
||||||
timestamp: () => {
|
timestamp: () => {
|
||||||
const date = new Date()
|
const date = new Date()
|
||||||
return date.toLocaleTimeString() + ' ' + date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear().toString().substring(2, 4)
|
return date.toLocaleTimeString() + ' ' + date.toLocaleDateString()
|
||||||
},
|
},
|
||||||
colorize: true
|
colorize: true
|
||||||
})
|
})
|
||||||
|
@ -12,10 +12,10 @@ const config = require('../config')
|
|||||||
function ping (serverRegistration, timeout, callback, version) {
|
function ping (serverRegistration, timeout, callback, version) {
|
||||||
switch (serverRegistration.data.type) {
|
switch (serverRegistration.data.type) {
|
||||||
case 'PC':
|
case 'PC':
|
||||||
serverRegistration.unfurlSrv((host, port) => {
|
serverRegistration.dnsResolver.unfurlSrv((host, port, remainingTimeout) => {
|
||||||
const server = new minecraftJavaPing.MinecraftServer(host, port || 25565)
|
const server = new minecraftJavaPing.MinecraftServer(host, port || 25565)
|
||||||
|
|
||||||
server.ping(timeout, version, (err, res) => {
|
server.resolve(remainingTimeout, version, (err, res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err)
|
callback(err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const dns = require('dns')
|
|
||||||
|
|
||||||
const { GRAPH_UPDATE_TIME_GAP, TimeTracker } = require('./time')
|
const DNSResolver = require('./dns')
|
||||||
const Server = require('./server')
|
const Server = require('./server')
|
||||||
|
|
||||||
|
const { GRAPH_UPDATE_TIME_GAP, TimeTracker } = require('./time')
|
||||||
const { getPlayerCountOrNull } = require('./util')
|
const { getPlayerCountOrNull } = require('./util')
|
||||||
|
|
||||||
const config = require('../config')
|
const config = require('../config')
|
||||||
@ -21,6 +21,7 @@ class ServerRegistration {
|
|||||||
this.serverId = serverId
|
this.serverId = serverId
|
||||||
this.data = data
|
this.data = data
|
||||||
this._pingHistory = []
|
this._pingHistory = []
|
||||||
|
this.dnsResolver = new DNSResolver(this.data.ip, this.data.port)
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePing (timestamp, resp, err, version, updateHistoryGraph) {
|
handlePing (timestamp, resp, err, version, updateHistoryGraph) {
|
||||||
@ -254,62 +255,6 @@ class ServerRegistration {
|
|||||||
color: this.data.color
|
color: this.data.color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unfurlSrv (callback) {
|
|
||||||
// Skip unfurling SRV, instantly return pre-configured data
|
|
||||||
if (config.performance && config.performance.skipUnfurlSrv) {
|
|
||||||
callback(this.data.ip, this.data.port)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const timestamp = new Date().getTime()
|
|
||||||
|
|
||||||
// If a cached copy exists and is within its TTL, instantly return
|
|
||||||
if (this._lastUnfurlSrv && timestamp - this._lastUnfurlSrv.timestamp <= config.performance.unfurlSrvCacheTtl) {
|
|
||||||
callback(this._lastUnfurlSrv.ip, this._lastUnfurlSrv.port)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Group callbacks into an array
|
|
||||||
// Once resolved, fire callbacks sequentially
|
|
||||||
// This avoids callbacks possibly executing out of order
|
|
||||||
if (!this._unfurlSrvCallbackQueue) {
|
|
||||||
this._unfurlSrvCallbackQueue = []
|
|
||||||
}
|
|
||||||
|
|
||||||
this._unfurlSrvCallbackQueue.push(callback)
|
|
||||||
|
|
||||||
// Prevent multiple #resolveSrv calls per ServerRegistration
|
|
||||||
if (!this._isUnfurlingSrv) {
|
|
||||||
this._isUnfurlingSrv = true
|
|
||||||
|
|
||||||
dns.resolveSrv('_minecraft._tcp' + this.data.ip, (_, records) => {
|
|
||||||
this._lastUnfurlSrv = {
|
|
||||||
timestamp
|
|
||||||
}
|
|
||||||
|
|
||||||
if (records && records.length > 0) {
|
|
||||||
this._lastUnfurlSrv.ip = records[0].name
|
|
||||||
this._lastUnfurlSrv.port = records[0].port
|
|
||||||
} else {
|
|
||||||
// Provide fallback to pre-configured data
|
|
||||||
this._lastUnfurlSrv.ip = this.data.ip
|
|
||||||
this._lastUnfurlSrv.port = this.data.port
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire the waiting callbacks in queue
|
|
||||||
// Release blocking flag to allow new #resolveSrv calls
|
|
||||||
this._isUnfurlingSrv = false
|
|
||||||
|
|
||||||
for (const callback of this._unfurlSrvCallbackQueue) {
|
|
||||||
callback(this._lastUnfurlSrv.ip, this._lastUnfurlSrv.port)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the callback queue
|
|
||||||
this._unfurlSrvCallbackQueue = []
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ServerRegistration
|
module.exports = ServerRegistration
|
||||||
|
@ -10,7 +10,7 @@ class TimeTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
newPointTimestamp () {
|
newPointTimestamp () {
|
||||||
const timestamp = new Date().getTime()
|
const timestamp = TimeTracker.getEpochMillis()
|
||||||
|
|
||||||
TimeTracker.pushAndShift(this._serverGraphPoints, timestamp, TimeTracker.getMaxServerGraphDataLength())
|
TimeTracker.pushAndShift(this._serverGraphPoints, timestamp, TimeTracker.getMaxServerGraphDataLength())
|
||||||
|
|
||||||
@ -53,6 +53,10 @@ class TimeTracker {
|
|||||||
return Math.floor(timestamp / 1000)
|
return Math.floor(timestamp / 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getEpochMillis () {
|
||||||
|
return new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
static getMaxServerGraphDataLength () {
|
static getMaxServerGraphDataLength () {
|
||||||
return Math.ceil(config.serverGraphDuration / config.rates.pingAll)
|
return Math.ceil(config.serverGraphDuration / config.rates.pingAll)
|
||||||
}
|
}
|
||||||
|
9
main.js
9
main.js
@ -30,15 +30,6 @@ if (!config.serverGraphDuration) {
|
|||||||
config.serverGraphDuration = 3 * 60 * 10000
|
config.serverGraphDuration = 3 * 60 * 10000
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.performance && config.performance.skipUnfurlSrv) {
|
|
||||||
logger.log('warn', '"performance.skipUnfurlSrv" is enabled. Any configured hosts using SRV records may not properly resolve.')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.performance || typeof config.performance.unfurlSrvCacheTtl === 'undefined') {
|
|
||||||
logger.log('warn', '"performance.unfurlSrvCacheTtl" is not defined in config.json - defaulting to 120 seconds!')
|
|
||||||
config.performance.unfurlSrvCacheTtl = 2 * 60 * 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.logToDatabase) {
|
if (!config.logToDatabase) {
|
||||||
logger.log('warn', 'Database logging is not enabled. You can enable it by setting "logToDatabase" to true in config.json. This requires sqlite3 to be installed.')
|
logger.log('warn', 'Database logging is not enabled. You can enable it by setting "logToDatabase" to true in config.json. This requires sqlite3 to be installed.')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user