From 798dda8f1254de1fad2349f15c1d2c7bf22774cc Mon Sep 17 00:00:00 2001 From: Cryptkeeper Date: Sat, 6 Feb 2016 18:26:29 -0600 Subject: [PATCH] Fix frontend not updating publicConfig.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes the handshake sequence to use “bootTime” (a unique key based off the time) to make sure the frontend configuration matches the current one. If not, the client pulls the update and validates before requesting the listing. --- app.js | 34 ++++++++++++---------- assets/js/site.js | 74 ++++++++++++++++++++++++++++++++--------------- config.json | 4 +-- lib/server.js | 4 ++- lib/util.js | 14 ++++++++- 5 files changed, 86 insertions(+), 44 deletions(-) diff --git a/app.js b/app.js index 7b235c1..0021a8b 100644 --- a/app.js +++ b/app.js @@ -142,22 +142,9 @@ function startServices() { logger.log('info', '%s connected, total clients: %d', client.request.connection.remoteAddress, connectedClients); - setTimeout(function() { - client.emit('setGraphDuration', config.graphDuration); - - // Send them our previous data, so they have somewhere to start. - client.emit('updateMojangServices', mojang.toMessage()); - - // Remap our associative array into just an array. - var networkHistoryKeys = Object.keys(networkHistory); - - networkHistoryKeys.sort(); - - // Send each individually, this should look cleaner than waiting for one big array to transfer. - for (var i = 0; i < networkHistoryKeys.length; i++) { - client.emit('add', [networkHistory[networkHistoryKeys[i]]]); - } - }, 1); + // We send the boot time (also sent in publicConfig.json) to the frontend to validate they have the same config. + // If so, they'll send back "requestListing" event, otherwise they will pull the new config and retry. + client.emit('bootTime', util.getBootTime()); // Attach our listeners. client.on('disconnect', function() { @@ -172,6 +159,21 @@ function startServices() { client.emit('historyGraph', graphData); } }); + + client.on('requestListing', function() { + // Send them our previous data, so they have somewhere to start. + client.emit('updateMojangServices', mojang.toMessage()); + + // Remap our associative array into just an array. + var networkHistoryKeys = Object.keys(networkHistory); + + networkHistoryKeys.sort(); + + // Send each individually, this should look cleaner than waiting for one big array to transfer. + for (var i = 0; i < networkHistoryKeys.length; i++) { + client.emit('add', [networkHistory[networkHistoryKeys[i]]]); + } + }); }); startMainLoop(); diff --git a/assets/js/site.js b/assets/js/site.js index e8001de..15c55ef 100644 --- a/assets/js/site.js +++ b/assets/js/site.js @@ -1,10 +1,15 @@ -var graphs = {}; -var lastPlayerEntries = {}; +var graphs = []; +var lastPlayerEntries = []; var historyPlot; var displayedGraphData; var hiddenGraphData = []; +var isConnected = false; + +var mojangServicesUpdater; +var sortServersTask; + function updateServerStatus(lastEntry) { var info = lastEntry.info; var div = $('#status_' + safeName(info.name)); @@ -117,6 +122,37 @@ function setAllGraphVisibility(visible) { } } +function validateBootTime(bootTime, socket) { + $('#tagline-text').text('Validating...'); + + console.log('Remote bootTime is ' + bootTime + ', local is ' + publicConfig.bootTime); + + if (bootTime === publicConfig.bootTime) { + $('#tagline-text').text('Loading...'); + + socket.emit('requestListing'); + + if (!isMobileBrowser()) socket.emit('requestHistoryGraph'); + + isConnected = true; + + // Start any special updating tasks. + mojangServicesUpdater = setInterval(updateMojangServices, 1000); + sortServersTask = setInterval(sortServers, 10000); + } else { + $('#tagline-text').text('Updating...'); + + $.getScript('/publicConfig.json', function(data, textStatus, xhr) { + if (xhr.status === 200) { + validateBootTime(publicConfig.bootTime, socket); + } else { + $('#tagline').attr('class', 'status-offline'); + $('#tagline-text').text('Failed to update! Refresh?'); + } + }); + } +} + $(document).ready(function() { var socket = io.connect({ reconnect: true, @@ -124,25 +160,13 @@ $(document).ready(function() { reconnectionAttempts: 10 }); - var mojangServicesUpdater; - var sortServersTask; - - socket.on('connect', function() { - $('#tagline-text').text('Loading...'); - - if (!isMobileBrowser()) { - socket.emit('requestHistoryGraph'); - } - }); + socket.on('bootTime', function(bootTime) { + validateBootTime(bootTime, socket); + }); socket.on('disconnect', function() { - if (mojangServicesUpdater) { - clearInterval(mojangServicesUpdater); - } - - if (sortServersTask) { - clearInterval(sortServersTask); - } + if (mojangServicesUpdater) clearInterval(mojangServicesUpdater); + if (sortServersTask) clearInterval(sortServersTask); $('#tagline').attr('class', 'status-offline'); $('#tagline-text').text('Disconnected! Refresh?'); @@ -157,6 +181,8 @@ $(document).ready(function() { $('#big-graph').html(''); $('#big-graph-checkboxes').html(''); $('#big-graph-controls').css('display', 'none'); + + isConnected = false; }); socket.on('historyGraph', function(rawData) { @@ -333,11 +359,11 @@ $(document).ready(function() { } }); - socket.on('updateMojangServices', updateMojangServices); - - // Start any special updating tasks. - mojangServicesUpdater = setInterval(updateMojangServices, 1000); - sortServersTask = setInterval(sortServers, 10000); + socket.on('updateMojangServices', function(data) { + if (isConnected) { + updateMojangServices(data); + } + }); $(document).on('click', '.graph-control', function(e) { var serverIp = $(this).attr('data-target-network'); diff --git a/config.json b/config.json index 8b20432..41a5237 100644 --- a/config.json +++ b/config.json @@ -4,7 +4,7 @@ "/images/compass.png": "assets/images/compass.png", "/js/site.js": "assets/js/site.js", "/js/util.js": "assets/js/util.js", - "/js/config.js": "assets/js/config.js", + "/js/graph.js": "assets/js/graph.js", "/css/main.css": "assets/css/main.css", "/favicons/hypixelpe.png": "assets/images/favicons/hypixelpe.png", "/favicons/mineplex.png": "assets/images/favicons/mineplex.png", @@ -16,7 +16,7 @@ "Mobcrush Land": "/favicons/mobcrush.png" }, "site": { - "port": 80, + "port": 8080, "ip": "0.0.0.0" }, "rates": { diff --git a/lib/server.js b/lib/server.js index 71b18e8..3d7b46b 100644 --- a/lib/server.js +++ b/lib/server.js @@ -4,6 +4,7 @@ var url = require('url'); var mime = require('mime'); var io = require('socket.io'); +var util = require('./util'); var logger = require('./logger'); var config = require('../config.json'); @@ -65,7 +66,8 @@ function handleRequest(req, res) { var publicConfig = { categories: categories, graphDuration: config.graphDuration, - servers: servers + servers: servers, + bootTime: util.getBootTime() }; res.write('setPublicConfig(' + JSON.stringify(publicConfig) + ');'); diff --git a/lib/util.js b/lib/util.js index de946a1..0844c6f 100644 --- a/lib/util.js +++ b/lib/util.js @@ -3,7 +3,9 @@ var logger = require('./logger'); var config = require('../config.json'); var servers = require('../servers.json'); -var serverNameLookup = {}; +var serverNameLookup = []; + +var bootTime; // Finds a server in servers.json with a matching IP. // If it finds one, it caches the result for faster future lookups. @@ -136,4 +138,14 @@ exports.convertPingsToGraph = function(sqlData) { logger.info('Converted data structure in ' + (exports.getCurrentTimeMs() - startTime) + 'ms'); return graphData; +}; + +exports.getBootTime = function() { + if (!bootTime) { + bootTime = exports.getCurrentTimeMs(); + + logger.info('Selected %d as boot time.', bootTime); + } + + return bootTime; }; \ No newline at end of file