Backend cleanup (#146)

* Add ServerRegistration, begin refactoring to match frontend

* move graphData logic into ServerRegistration

* move ping updates/history into ServerRegistration

* start updating main app entry methods

* fix default rates.updateMojangStatus

* fix record loading delays on freshly booted instances

* move database loading logic to method + callback

* use data in frontend for type lookup instead of ping

* cleanup app.js

* reorganize methods to improve flow

* avoid useless mojang updates, remove legacy fields

* rename legacy fields for consistency

* finish restructure around App model

* ensure versions are sorted by release order

* filter errors sent to frontend to avoid data leaks

* fix version listing behavior on frontend

* 5.1.0
This commit is contained in:
Nick Krecklow
2020-04-21 17:59:53 -05:00
committed by GitHub
parent 9eda8d6bdb
commit 4d13965e6b
19 changed files with 822 additions and 823 deletions

View File

@ -1,47 +1,105 @@
/**
* THIS IS LEGACY, UNMAINTAINED CODE
* IT MAY (AND LIKELY DOES) CONTAIN BUGS
* USAGE IS NOT RECOMMENDED
*/
var util = require('./util');
const sqlite = require('sqlite3')
exports.setup = function() {
var sqlite = require('sqlite3');
class Database {
constructor (app) {
this._app = app
this._sql = new sqlite.Database('database.sql')
}
var db = new sqlite.Database('database.sql');
ensureIndexes () {
this._sql.serialize(() => {
this._sql.run('CREATE TABLE IF NOT EXISTS pings (timestamp BIGINT NOT NULL, ip TINYTEXT, playerCount MEDIUMINT)')
this._sql.run('CREATE INDEX IF NOT EXISTS ip_index ON pings (ip, playerCount)')
this._sql.run('CREATE INDEX IF NOT EXISTS timestamp_index on PINGS (timestamp)')
})
}
db.serialize(function() {
db.run('CREATE TABLE IF NOT EXISTS pings (timestamp BIGINT NOT NULL, ip TINYTEXT, playerCount MEDIUMINT)');
db.run('CREATE INDEX IF NOT EXISTS ip_index ON pings (ip, playerCount)');
db.run('CREATE INDEX IF NOT EXISTS timestamp_index on PINGS (timestamp)');
});
loadGraphPoints (graphDuration, callback) {
// Query recent pings
const endTime = new Date().getTime()
const startTime = endTime - graphDuration
exports.log = function(ip, timestamp, playerCount) {
var insertStatement = db.prepare('INSERT INTO pings (timestamp, ip, playerCount) VALUES (?, ?, ?)');
this.getRecentPings(startTime, endTime, pingData => {
const graphPointsByIp = []
db.serialize(function() {
insertStatement.run(timestamp, ip, playerCount);
});
for (const row of pingData) {
// Avoid loading outdated records
// This shouldn't happen and is mostly a sanity measure
if (startTime - row.timestamp <= graphDuration) {
// Load into temporary array
// This will be culled prior to being pushed to the serverRegistration
let graphPoints = graphPointsByIp[row.ip]
if (!graphPoints) {
graphPoints = graphPointsByIp[row.ip] = []
}
insertStatement.finalize();
};
graphPoints.push([row.timestamp, row.playerCount])
}
}
exports.getTotalRecord = function(ip, callback) {
db.all("SELECT MAX(playerCount), timestamp FROM pings WHERE ip = ?", [
ip
], function(err, data) {
callback(data[0]['MAX(playerCount)'], data[0]['timestamp']);
});
};
Object.keys(graphPointsByIp).forEach(ip => {
// Match IPs to serverRegistration object
for (const serverRegistration of this._app.serverRegistrations) {
if (serverRegistration.data.ip === ip) {
const graphPoints = graphPointsByIp[ip]
exports.queryPings = function(duration, callback) {
var currentTime = util.getCurrentTimeMs();
// Push the data into the instance and cull if needed
serverRegistration.loadGraphPoints(graphPoints)
db.all("SELECT * FROM pings WHERE timestamp >= ? AND timestamp <= ?", [
currentTime - duration,
currentTime
], function(err, data) {
callback(data);
});
};
};
break
}
}
})
callback()
})
}
loadRecords (callback) {
let completedTasks = 0
this._app.serverRegistrations.forEach(serverRegistration => {
// Find graphPeaks
// This pre-computes the values prior to clients connecting
serverRegistration.findNewGraphPeak()
// Query recordData
// When complete increment completeTasks to know when complete
this.getRecord(serverRegistration.data.ip, (playerCount, timestamp) => {
serverRegistration.recordData = {
playerCount: playerCount,
timestamp: timestamp
}
// Check if completedTasks hit the finish value
// Fire callback since #readyDatabase is complete
if (++completedTasks === this._app.serverRegistrations.length) {
callback()
}
})
})
}
getRecentPings (startTime, endTime, callback) {
this._sql.all('SELECT * FROM pings WHERE timestamp >= ? AND timestamp <= ?', [
startTime,
endTime
], (_, data) => callback(data))
}
getRecord (ip, callback) {
this._sql.all('SELECT MAX(playerCount), timestamp FROM pings WHERE ip = ?', [
ip
], (_, data) => callback(data[0]['MAX(playerCount)'], data[0].timestamp))
}
insertPing (ip, timestamp, playerCount) {
const statement = this._sql.prepare('INSERT INTO pings (timestamp, ip, playerCount) VALUES (?, ?, ?)')
this._sql.serialize(() => {
statement.run(timestamp, ip, playerCount)
})
statement.finalize()
}
}
module.exports = Database