diff --git a/TODO b/TODO index 68c590d..d649a36 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,5 @@ Fix icons not updating when a network that was offline comes online. -Show offline server messages on frontend. Add auto-reconnect to frontend. -Add sorting. Finish design. -Deploy to actual website. \ No newline at end of file +Deploy to actual website. +Add new API. \ No newline at end of file diff --git a/assets/css/main.css b/assets/css/main.css index c7924c1..f125c09 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -34,6 +34,19 @@ body { border-bottom: 1px dashed transparent; } +#header > .slogan { + letter-spacing: 2px; + font-size: 20px; +} + +#header > .info { + font-size: 17px; +} + +#header > h1 { + font-size: 42px; +} + /* Tagline */ #tagline { padding: 10px 0; @@ -66,7 +79,7 @@ body { /* Server listing */ #server-container { width: 800px; - margin: 10px auto; + margin: 10px auto 20px auto; } #server-container .server:nth-child(2n) { @@ -77,6 +90,7 @@ body { .server { overflow: auto; padding: 10px; + margin: 5px; } .server > .column > img { @@ -116,7 +130,7 @@ h3 { } .color-red { - color: #c0392b; + color: #e74c3c; } .text-uppercase { diff --git a/assets/html/index.html b/assets/html/index.html index 9d43117..05c7243 100644 --- a/assets/html/index.html +++ b/assets/html/index.html @@ -17,9 +17,8 @@ diff --git a/assets/images/favicons/hypixelpe.png b/assets/images/favicons/hypixelpe.png index 040d629..64b89d0 100644 Binary files a/assets/images/favicons/hypixelpe.png and b/assets/images/favicons/hypixelpe.png differ diff --git a/assets/js/site.js b/assets/js/site.js index 80009bf..139f103 100644 --- a/assets/js/site.js +++ b/assets/js/site.js @@ -11,7 +11,7 @@ var smallChartOptions = { show: false }, yaxis: { - minTickSize: 100, + minTickSize: 75, tickDecimals: 0, show: true, tickLength: 10, @@ -25,7 +25,7 @@ var smallChartOptions = { }, grid: { hoverable: true, - color: "#C4C4C4" + color: "#696969" }, colors: [ "#E9E581" @@ -38,6 +38,10 @@ var lastPlayerEntries = {}; // Generate (and set) the HTML that displays Mojang status. function updateMojangServices() { + if (!lastMojangServiceUpdate) { + return; + } + var keys = Object.keys(lastMojangServiceUpdate); var newStatus = 'Mojang Services: '; var serviceCountByType = { @@ -75,18 +79,28 @@ function updateMojangServices() { $('#tagline-text').text(newStatus); } +function findErrorMessage(error) { + if (error.description) { + return error.description; + } else if (error.errno) { + return error.errno; + } +} + function updateServerStatus(lastEntry) { var info = lastEntry.info; var div = $('#status_' + safeName(info.name)); if (lastEntry.result) { var result = lastEntry.result; - var newStatus = formatNumber(result.players.online) + '/' + formatNumber(result.players.max); + var newStatus = 'Players: ' + formatNumber(result.players.online); - if (lastPlayerEntries[info.name]) { + var listing = graphs[lastEntry.info.name].listing; + + if (listing.length > 0) { newStatus += ' ('; - var playerDifference = lastPlayerEntries[info.name] - result.players.online; + var playerDifference = listing[listing.length - 1][1] - listing[0][1]; if (playerDifference >= 0) { newStatus += '+'; @@ -111,6 +125,31 @@ function updateServerStatus(lastEntry) { lastLatencyEntries[info.name] = result.latency; div.html(newStatus); + } else { + var newStatus = 'Failed to ping!'; + + if (findErrorMessage(lastEntry.error)) { + newStatus += '
' + findErrorMessage(lastEntry.error); + } + + div.html(newStatus + '
'); + } +} + +function sortServers() { + var keys = Object.keys(lastPlayerEntries); + var nameList = []; + + keys.sort(function(a, b) { + return lastPlayerEntries[b] - lastPlayerEntries[a]; + }); + + keys.reverse(); + + for (var i = 0; i < keys.length; i++) { + $('#' + safeName(keys[i])).prependTo('#server-container'); + + $('#ranking_' + safeName(keys[i])).text('#' + (keys.length - i)); } } @@ -131,8 +170,8 @@ $(document).ready(function() { clearInterval(mojangServicesUpdater); } - $('#tagline').attr('class', 'status-connecting'); - $('#tagline-text').text('Attempting reconnnect...'); + $('#tagline').attr('class', 'status-offline'); + $('#tagline-text').text('Disconnected! Refresh?'); lastPlayerEntries = {}; lastLatencyEntries = {}; @@ -159,11 +198,21 @@ $(document).ready(function() { var lastEntry = history[history.length - 1]; var info = lastEntry.info; + if (lastEntry.error) { + lastPlayerEntries[info.name] = 0; + lastLatencyEntries[info.name] = 0; + } else if (lastEntry.result) { + lastPlayerEntries[info.name] = lastEntry.result.players.online; + lastLatencyEntries[info.name] = lastEntry.result.latency; + } + $('
', { id: safeName(info.name), class: 'server', html: '
\ \ +
\ + \
\

' + info.name + '

\ ' + info.ip + '\ @@ -183,13 +232,13 @@ $(document).ready(function() { $('#favicon_' + safeName(info.name)).attr('src', favicon); - updateServerStatus(lastEntry); - graphs[lastEntry.info.name] = { listing: listing, plot: $.plot('#chart_' + safeName(info.name), [listing], smallChartOptions) }; + updateServerStatus(lastEntry); + $('#chart_' + safeName(info.name)).bind('plothover', function(event, pos, item) { if (item) { renderTooltip(item.pageX + 5, item.pageY + 5, getTimestamp(item.datapoint[0] / 1000) + '\ @@ -200,9 +249,21 @@ $(document).ready(function() { } }); } + + sortServers(); }); socket.on('update', function(update) { + // Prevent weird race conditions. + if (!graphs[update.info.name]) { + return; + } + + // We have a new favicon, update the old one. + if (update.result && update.result.favicon) { + $('#favicon_' + safeName(update.info.name)).attr('src', update.result.favicon); + } + var graph = graphs[update.info.name]; updateServerStatus(update); @@ -230,4 +291,8 @@ $(document).ready(function() { mojangServicesUpdater = setInterval(function() { updateMojangServices(); }, 1000); + + setInterval(function() { + sortServers(); + }, 30 * 1000); }); \ No newline at end of file diff --git a/config.json b/config.json index cc7dc53..f8ac76b 100644 --- a/config.json +++ b/config.json @@ -86,9 +86,19 @@ "type": "PC" }, { - "name": "Shock", + "name": "Shock Network", "ip": "play.snw.io", "type": "PC" + }, + { + "name": "MCBrawl", + "ip": "mcbrawl.com", + "type": "PC" + }, + { + "name": "SaicoPvP", + "ip": "saicopvp.com", + "type": "PC" } ], "routes": { diff --git a/lib/server.js b/lib/server.js index 19e8c4e..35cf1e6 100644 --- a/lib/server.js +++ b/lib/server.js @@ -25,7 +25,15 @@ exports.start = function(callback) { logger.log('info', '%s requested: %s', req.connection.remoteAddress, requestUrl); - if (requestUrl in urlMapping) { + if (requestUrl === '/status.json') { + res.setHeader('Content-Type', 'text/plain'); + res.write(JSON.stringify({ + error: true, + message: 'API deprecated.' + })); + + res.end(); + } else if (requestUrl in urlMapping) { var file = urlMapping[requestUrl]; res.setHeader('Content-Type', mime.lookup(file));