Minetrack/assets/js/site.js

509 lines
14 KiB
JavaScript
Raw Normal View History

2015-11-08 18:34:17 -06:00
var smallChartOptions = {
series: {
shadowSize: 0
},
xaxis: {
font: {
color: "#E3E3E3"
},
show: false
},
yaxis: {
2015-11-09 01:03:03 -06:00
minTickSize: 75,
2015-11-08 18:34:17 -06:00
tickDecimals: 0,
show: true,
tickLength: 10,
tickFormatter: function(value) {
return formatNumber(value);
},
font: {
color: "#E3E3E3"
},
2016-01-06 15:42:50 -06:00
labelWidth: -10
2015-11-08 18:34:17 -06:00
},
grid: {
hoverable: true,
2015-11-09 01:03:03 -06:00
color: "#696969"
2015-11-08 18:34:17 -06:00
},
colors: [
"#E9E581"
]
};
2015-12-18 01:45:38 -06:00
var bigChartOptions = {
series: {
shadowSize: 0
},
xaxis: {
font: {
color: "#E3E3E3"
},
show: false
},
yaxis: {
show: true,
2015-12-18 18:10:58 -06:00
tickSize: 2000,
2015-12-18 01:45:38 -06:00
tickLength: 10,
tickFormatter: function(value) {
return formatNumber(value);
},
font: {
color: "#E3E3E3"
},
labelWidth: -5,
min: 0
2015-12-18 01:45:38 -06:00
},
grid: {
hoverable: true,
color: "#696969"
},
legend: {
show: false
}
};
var lastMojangServiceUpdate;
2015-11-08 18:34:17 -06:00
var graphs = {};
var lastPlayerEntries = {};
2015-12-18 18:33:43 -06:00
var historyPlot;
var displayedGraphData;
var hiddenGraphData = [];
2015-11-08 18:34:17 -06:00
// Generate (and set) the HTML that displays Mojang status.
function updateMojangServices() {
2015-11-09 01:03:03 -06:00
if (!lastMojangServiceUpdate) {
return;
}
2015-11-08 18:34:17 -06:00
var keys = Object.keys(lastMojangServiceUpdate);
var newStatus = 'Mojang Services: ';
var serviceCountByType = {
Online: 0,
Unstable: 0,
Offline: 0
};
for (var i = 0; i < keys.length; i++) {
var entry = lastMojangServiceUpdate[keys[i]];
serviceCountByType[entry.title] += 1;
}
if (serviceCountByType['Online'] === keys.length) {
$('#tagline').attr('class', 'status-online');
2015-11-08 18:34:17 -06:00
newStatus += 'All systems operational.';
} else {
if (serviceCountByType['Unstable'] > serviceCountByType['Offline']) {
$('#tagline').attr('class', 'status-unstable');
} else {
$('#tagline').attr('class', 'status-offline');
}
for (var i = 0; i < keys.length; i++) {
var entry = lastMojangServiceUpdate[keys[i]];
if (entry.startTime) {
2015-12-14 18:17:34 -05:00
newStatus += entry.name + ' ' + entry.title.toLowerCase() + ' for ' + msToTime((new Date()).getTime() - entry.startTime + ' ');
2015-11-08 18:34:17 -06:00
}
}
}
$('#tagline-text').text(newStatus);
}
2015-11-09 01:03:03 -06:00
function findErrorMessage(error) {
if (error.description) {
return error.description;
} else if (error.errno) {
return error.errno;
}
}
2015-11-08 18:34:17 -06:00
function updateServerStatus(lastEntry) {
var info = lastEntry.info;
var div = $('#status_' + safeName(info.name));
if (lastEntry.result) {
var result = lastEntry.result;
2015-11-09 01:38:18 -06:00
var newStatus = '<br />Players: ' + formatNumber(result.players.online);
2015-11-09 01:03:03 -06:00
var listing = graphs[lastEntry.info.name].listing;
2015-11-08 18:34:17 -06:00
2015-11-09 01:03:03 -06:00
if (listing.length > 0) {
2015-11-08 18:34:17 -06:00
newStatus += '<span class="color-gray"> (';
2015-11-09 01:03:03 -06:00
var playerDifference = listing[listing.length - 1][1] - listing[0][1];
2015-11-08 18:34:17 -06:00
if (playerDifference >= 0) {
newStatus += '+';
}
newStatus += playerDifference + ')</span>';
}
lastPlayerEntries[info.name] = result.players.online;
div.html(newStatus);
2015-11-09 01:03:03 -06:00
} else {
var newStatus = '<br /><span class="color-red">';
2015-11-09 01:03:03 -06:00
if (findErrorMessage(lastEntry.error)) {
newStatus += findErrorMessage(lastEntry.error);
} else {
newStatus += 'Failed to ping!';
2015-11-09 01:03:03 -06:00
}
div.html(newStatus + '</span>');
}
2015-11-30 14:00:47 -06:00
var keys = Object.keys(lastPlayerEntries);
var totalPlayers = 0;
for (var i = 0; i < keys.length; i++) {
totalPlayers += lastPlayerEntries[keys[i]];
}
$("#stat_totalPlayers").text(formatNumber(totalPlayers));
$("#stat_networks").text(formatNumber(keys.length));
2015-11-09 01:03:03 -06:00
}
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));
2015-11-08 18:34:17 -06:00
}
}
2015-12-18 18:33:43 -06:00
function setAllGraphVisibility(visible) {
if (visible) {
var keys = Object.keys(hiddenGraphData);
for (var i = 0; i < keys.length; i++) {
displayedGraphData[keys[i]] = hiddenGraphData[keys[i]];
}
hiddenGraphData = [];
} else {
var keys = Object.keys(displayedGraphData);
for (var i = 0; i < keys.length; i++) {
hiddenGraphData[keys[i]] = displayedGraphData[keys[i]];
}
displayedGraphData = [];
}
$('.graph-control').each(function(index, item) {
item.checked = visible;
});
historyPlot.setData(convertGraphData(displayedGraphData));
historyPlot.setupGrid();
historyPlot.draw();
2016-02-01 05:21:46 -06:00
// Update our localStorage
2016-02-01 05:23:42 -06:00
if (visible) {
resetGraphControls();
} else {
saveGraphControls(Object.keys(displayedGraphData));
}
2015-12-18 18:33:43 -06:00
}
2015-12-18 18:49:18 -06:00
function toggleControlsDrawer() {
var div = $('#big-graph-controls-drawer');
div.css('display', div.css('display') !== 'none' ? 'none' : 'block');
}
$(document).ready(function() {
var socket = io.connect({
2015-11-30 18:12:26 -06:00
reconnect: true,
reconnectDelay: 1000,
reconnectionAttempts: 10
});
2015-11-08 18:34:17 -06:00
var mojangServicesUpdater;
var sortServersTask;
2015-12-18 21:23:24 -06:00
var graphDuration;
socket.on('connect', function() {
2015-11-08 18:34:17 -06:00
$('#tagline-text').text('Loading...');
2015-12-18 19:00:57 -06:00
if (!isMobileBrowser()) {
socket.emit('requestHistoryGraph');
}
});
2015-11-01 23:46:24 -06:00
2015-11-08 18:34:17 -06:00
socket.on('disconnect', function() {
if (mojangServicesUpdater) {
clearInterval(mojangServicesUpdater);
}
if (sortServersTask) {
clearInterval(sortServersTask);
}
2015-11-09 01:03:03 -06:00
$('#tagline').attr('class', 'status-offline');
$('#tagline-text').text('Disconnected! Refresh?');
2015-11-08 18:34:17 -06:00
lastPlayerEntries = {};
graphs = {};
$('#server-container').html('');
$('#quick-jump-container').html('');
2015-12-18 18:49:18 -06:00
2015-12-18 02:47:35 -06:00
$('#big-graph').html('');
2015-12-18 18:33:43 -06:00
$('#big-graph-checkboxes').html('');
2015-12-18 18:49:18 -06:00
$('#big-graph-controls').css('display', 'none');
2015-11-08 18:34:17 -06:00
});
2015-12-18 21:23:24 -06:00
socket.on('setGraphDuration', function(value) {
graphDuration = value;
});
2015-12-18 01:45:38 -06:00
socket.on('historyGraph', function(rawData) {
2016-02-01 05:29:09 -06:00
var shownServers = loadGraphControls();
if (shownServers) {
var keys = Object.keys(rawData);
2016-02-01 05:31:00 -06:00
hiddenGraphData = [];
displayedGraphData = [];
2016-02-01 05:29:09 -06:00
for (var i = 0; i < keys.length; i++) {
var name = keys[i];
if (shownServers.indexOf(name) !== -1) {
displayedGraphData[name] = rawData[name];
} else {
hiddenGraphData[name] = rawData[name];
}
}
} else {
displayedGraphData = rawData;
}
2015-12-18 01:45:38 -06:00
2015-12-23 14:25:05 -06:00
$('#big-graph').css('height', '400px');
2015-12-18 19:05:43 -06:00
2016-02-01 05:29:09 -06:00
historyPlot = $.plot('#big-graph', convertGraphData(displayedGraphData), bigChartOptions);
2015-12-18 01:45:38 -06:00
$('#big-graph').bind('plothover', handlePlotHover);
2015-12-18 18:10:58 -06:00
var keys = Object.keys(rawData);
var sinceBreak = 0;
var html = '<table><tr>';
keys.sort();
2015-12-18 18:10:58 -06:00
for (var i = 0; i < keys.length; i++) {
2016-02-01 05:29:09 -06:00
var checkedString = '';
if (displayedGraphData[keys[i]]) {
checkedString = 'checked=checked';
}
html += '<td><input type="checkbox" class="graph-control" id="graph-controls" data-target-network="' + keys[i] + '" ' + checkedString + '> ' + keys[i] + '</input></td>';
2015-12-18 21:39:08 -06:00
if (sinceBreak >= 7) {
sinceBreak = 0;
html += '</tr><tr>';
} else {
sinceBreak++;
}
2015-12-18 18:10:58 -06:00
}
2015-12-18 18:33:43 -06:00
$('#big-graph-checkboxes').append(html + '</tr></table>');
2015-12-18 18:49:18 -06:00
$('#big-graph-controls').css('display', 'block');
2015-12-18 01:45:38 -06:00
});
socket.on('updateHistoryGraph', function(rawData) {
2015-12-18 21:23:24 -06:00
// Prevent race conditions.
2016-02-01 05:32:00 -06:00
if (!graphDuration || !displayedGraphData || !hiddenGraphData) {
2015-12-18 21:23:24 -06:00
return;
2015-12-18 01:45:38 -06:00
}
2015-12-18 21:23:24 -06:00
// If it's not in our display group, use the hidden group instead.
2016-02-01 04:58:05 -06:00
var targetGraphData = displayedGraphData[rawData.name] ? displayedGraphData : hiddenGraphData;
2015-12-18 21:23:24 -06:00
trimOldPings(targetGraphData, graphDuration);
2015-12-18 01:45:38 -06:00
2016-02-01 04:58:05 -06:00
targetGraphData[rawData.name].push([rawData.timestamp, rawData.players]);
2015-12-18 18:10:58 -06:00
2015-12-18 21:23:24 -06:00
// Redraw if we need to.
2016-02-01 04:58:05 -06:00
if (displayedGraphData[rawData.name]) {
2015-12-18 21:23:24 -06:00
historyPlot.setData(convertGraphData(displayedGraphData));
historyPlot.setupGrid();
2015-12-18 01:45:38 -06:00
2015-12-18 21:23:24 -06:00
historyPlot.draw();
}
2015-12-18 01:45:38 -06:00
});
2015-11-01 23:46:24 -06:00
socket.on('add', function(servers) {
2015-11-08 18:34:17 -06:00
for (var i = 0; i < servers.length; i++) {
var history = servers[i];
var listing = [];
for (var x = 0; x < history.length; x++) {
var point = history[x];
if (point.result) {
listing.push([point.timestamp, point.result.players.online]);
} else if (point.error) {
listing.push([point.timestamp, 0]);
}
}
var lastEntry = history[history.length - 1];
var info = lastEntry.info;
2015-11-09 01:03:03 -06:00
if (lastEntry.error) {
lastPlayerEntries[info.name] = 0;
} else if (lastEntry.result) {
lastPlayerEntries[info.name] = lastEntry.result.players.online;
}
2015-11-08 18:34:17 -06:00
$('<div/>', {
id: safeName(info.name),
class: 'server',
html: '<div id="server-' + safeName(info.name) + '" class="column" style="width: 80px;">\
2015-12-04 16:26:07 -06:00
<img id="favicon_' + safeName(info.name) + '">\
2015-11-09 01:03:03 -06:00
<br />\
2015-12-04 16:26:07 -06:00
<p class="text-center-align rank" id="ranking_' + safeName(info.name) + '"></p>\
2015-11-08 18:34:17 -06:00
</div>\
2015-12-18 21:39:08 -06:00
<div class="column" style="width: 220px;">\
2015-11-25 19:32:39 -06:00
<h3>' + info.name + '&nbsp;<span class="type">' + info.type + '</span></h3>\
2015-11-08 18:34:17 -06:00
<span class="color-gray">' + info.ip + '</span>\
<br />\
<span id="status_' + safeName(info.name) + '">Waiting</span>\
</div>\
<div class="column" style="float: right;">\
<div class="chart" id="chart_' + safeName(info.name) + '"></div>\
</div>'
}).appendTo("#server-container");
2015-11-08 18:45:18 -06:00
var favicon = MISSING_FAVICON_BASE64;
2015-11-08 18:34:17 -06:00
if (lastEntry.result && lastEntry.result.favicon) {
2015-11-08 18:45:18 -06:00
favicon = lastEntry.result.favicon;
2015-11-08 18:34:17 -06:00
}
2015-11-01 23:46:24 -06:00
2015-11-08 18:45:18 -06:00
$('#favicon_' + safeName(info.name)).attr('src', favicon);
2015-11-25 19:36:41 -06:00
$('#quick-jump-container').append('<img id="quick-jump-' + safeName(info.name) + '" data-target-network="' + safeName(info.name) + '" title="' + info.name + '" alt="' + info.name + '" class="quick-jump-icon" src="' + favicon + '">');
2015-11-08 18:34:17 -06:00
graphs[lastEntry.info.name] = {
listing: listing,
plot: $.plot('#chart_' + safeName(info.name), [listing], smallChartOptions)
};
2015-11-09 01:03:03 -06:00
updateServerStatus(lastEntry);
2015-12-18 01:45:38 -06:00
$('#chart_' + safeName(info.name)).bind('plothover', handlePlotHover);
2015-11-08 18:34:17 -06:00
}
2015-11-09 01:03:03 -06:00
sortServers();
2015-11-08 18:34:17 -06:00
});
socket.on('update', function(update) {
2015-11-09 01:03:03 -06:00
// 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);
$('#quick-jump-' + safeName(update.info.name)).attr('src', update.result.favicon);
2015-11-09 01:03:03 -06:00
}
2015-11-08 18:34:17 -06:00
var graph = graphs[update.info.name];
updateServerStatus(update);
2015-11-09 16:33:56 -06:00
if (update.result) {
graph.listing.push([update.info.timestamp, update.result ? update.result.players.online : 0]);
2015-11-08 18:34:17 -06:00
2015-11-09 16:33:56 -06:00
if (graph.listing.length > 72) {
graph.listing.shift();
}
2015-11-08 18:34:17 -06:00
2015-11-09 16:33:56 -06:00
graph.plot.setData([graph.listing]);
graph.plot.setupGrid();
2015-11-08 18:34:17 -06:00
2015-11-09 16:33:56 -06:00
graph.plot.draw();
}
2015-11-01 23:46:24 -06:00
});
2015-11-08 18:34:17 -06:00
socket.on('updateMojangServices', function(data) {
// Store the update and force an update.
lastMojangServiceUpdate = data;
2015-11-01 23:46:24 -06:00
2015-11-08 18:34:17 -06:00
updateMojangServices();
2015-11-01 23:46:24 -06:00
});
2015-11-08 18:34:17 -06:00
// Start any special updating tasks.
mojangServicesUpdater = setInterval(function() {
updateMojangServices();
}, 1000);
2015-11-09 01:03:03 -06:00
sortServersTask = setInterval(function() {
2015-11-09 01:03:03 -06:00
sortServers();
2015-12-18 01:45:38 -06:00
}, 10 * 1000);
// Our super fancy scrolly thing!
$(document).on('click', '.quick-jump-icon', function(e) {
var serverName = $(this).attr('data-target-network');
var target = $('#server-' + serverName);
$('html, body').animate({
scrollTop: target.offset().top
}, 100);
});
2015-12-18 18:10:58 -06:00
$(document).on('click', '.graph-control', function(e) {
var serverIp = $(this).attr('data-target-network');
var checked = $(this).attr('checked');
// Restore it, or delete it - either works.
if (!this.checked) {
hiddenGraphData[serverIp] = displayedGraphData[serverIp];
delete displayedGraphData[serverIp];
} else {
displayedGraphData[serverIp] = hiddenGraphData[serverIp];
delete hiddenGraphData[serverIp];
}
2016-02-01 05:20:25 -06:00
// Redraw the graph
2015-12-18 18:10:58 -06:00
historyPlot.setData(convertGraphData(displayedGraphData));
historyPlot.setupGrid();
historyPlot.draw();
2016-02-01 05:20:25 -06:00
// Update our localStorage
2016-02-01 05:23:42 -06:00
if (Object.keys(hiddenGraphData).length === 0) {
resetGraphControls();
} else {
saveGraphControls(Object.keys(displayedGraphData));
}
2015-12-18 18:10:58 -06:00
});
});