var graphs = []; var lastPlayerEntries = []; var historyPlot; var displayedGraphData; var hiddenGraphData = []; var isConnected = false; var mojangServicesUpdater; var sortServersTask; var currentServerHover; var faviconSize = 64; function updateServerStatus(lastEntry) { var info = lastEntry.info; var div = $('#status_' + safeName(info.name)); var versionDiv = $('#version_' + safeName(info.name)); if (lastEntry.versions) { var versions = ''; for (var i = 0; i < lastEntry.versions.length; i++) { if (!lastEntry.versions[i]) continue; versions += '' + publicConfig.minecraftVersions[lastEntry.info.type][lastEntry.versions[i]] + ' '; } versionDiv.html(versions); } else { versionDiv.html(''); } if (lastEntry.result) { var result = lastEntry.result; var newStatus = 'Players: ' + formatNumber(result.players.online) + ''; var listing = graphs[lastEntry.info.name].listing; if (listing.length > 0) { newStatus += ' ('; var playerDifference = listing[listing.length - 1][1] - listing[0][1]; if (playerDifference >= 0) { newStatus += '+'; } newStatus += playerDifference + ')'; } lastPlayerEntries[info.name] = result.players.online; div.html(newStatus); } else { var newStatus = ''; if (findErrorMessage(lastEntry.error)) { newStatus += findErrorMessage(lastEntry.error); } else { newStatus += 'Failed to ping!'; } div.html(newStatus + ''); } 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)); if (lastEntry.record) { $('#record_' + safeName(info.name)).html('Record: ' + formatNumber(lastEntry.record)); } updatePercentageBar(); } function sortServers() { var serverNames = []; var keys = Object.keys(lastPlayerEntries); for (var i = 0; i < keys.length; i++) { serverNames.push(keys[i]); } serverNames.sort(function(a, b) { return (lastPlayerEntries[b] || 0) - (lastPlayerEntries[a] || 0); }); for (var i = 0; i < serverNames.length; i++) { $('#container_' + safeName(serverNames[i])).appendTo('#server-container-list'); $('#ranking_' + safeName(serverNames[i])).text('#' + (i + 1)); } } function updatePercentageBar() { var keys = Object.keys(lastPlayerEntries); keys.sort(function(a, b) { return lastPlayerEntries[a] - lastPlayerEntries[b]; }); var totalPlayers = getCurrentTotalPlayers(); var parent = $('#perc-bar'); var leftPadding = 0; for (var i = 0; i < keys.length; i++) { (function(pos, server, length) { var safeNameCopy = safeName(server); var playerCount = lastPlayerEntries[server]; var div = $('#perc_bar_part_' + safeNameCopy); // Setup the base if (!div.length) { $('
', { id: 'perc_bar_part_' + safeNameCopy, class: 'perc-bar-part', html: '', style: 'background: ' + getServerColor(server) + ';' }).appendTo(parent); div = $('#perc_bar_part_' + safeNameCopy); div.mouseover(function(e) { currentServerHover = server; }); div.mouseout(function(e) { hideTooltip(); currentServerHover = undefined; }); } // Update our position/width var width = (playerCount / totalPlayers) * parent.width(); div.css({ width: width + 'px', left: leftPadding + 'px' }); leftPadding += width; })(i, keys[i], keys.length); } } function getCurrentTotalPlayers() { var totalPlayers = 0; var keys = Object.keys(lastPlayerEntries); for (var i = 0; i < keys.length; i++) totalPlayers += lastPlayerEntries[keys[i]] return totalPlayers; } 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(); // Update our localStorage if (visible) { resetGraphControls(); } else { saveGraphControls(Object.keys(displayedGraphData)); } } 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 { showCaption('Failed to update! Refresh?'); } }); } } function printPort(port) { if(port == undefined || port == 25565) { return ""; } else { return ":" + port; } } function updateServerPeak(name, time, playerCount) { var safeNameCopy = safeName(name); // hack: strip the AM/PM suffix // Javascript doesn't have a nice way to format Dates with AM/PM, so we'll append it manually var timestamp = getTimestamp(time / 1000).split(':'); var end = timestamp.pop().split(' ')[1]; timestamp = timestamp.join(':'); // end may be undefined for other timezones/24 hour times if (end) { timestamp += ' ' + end; } var timeLabel = msToTime(publicConfig.graphDuration); $('#peak_' + safeNameCopy).html(timeLabel + ' Peak: ' + formatNumber(playerCount) + ' @ ' + timestamp); } $(document).ready(function() { var socket = io.connect({ reconnect: true, reconnectDelay: 1000, reconnectionAttempts: 10 }); socket.on('bootTime', function(bootTime) { validateBootTime(bootTime, socket); }); socket.on('disconnect', function() { if (mojangServicesUpdater) clearInterval(mojangServicesUpdater); if (sortServersTask) clearInterval(sortServersTask); lastMojangServiceUpdate = undefined; showCaption('Disconnected! Refresh?'); lastPlayerEntries = {}; graphs = {}; $('#server-container-list').html(''); $('#big-graph').html(''); $('#big-graph-checkboxes').html(''); $('#big-graph-controls').css('display', 'none'); $('#perc-bar').html(''); $('.mojang-status').css('background', 'transparent'); $('.mojang-status-text').text('...'); $("#stat_totalPlayers").text(0); $("#stat_networks").text(0); isConnected = false; }); socket.on('historyGraph', function(rawData) { var shownServers = loadGraphControls(); if (shownServers) { var keys = Object.keys(rawData); hiddenGraphData = []; displayedGraphData = []; 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; } $('#big-graph').css('height', '400px'); historyPlot = $.plot('#big-graph', convertGraphData(displayedGraphData), bigChartOptions); $('#big-graph').bind('plothover', handlePlotHover); var keys = Object.keys(rawData); var sinceBreak = 0; var html = '' + keys[i] + ' | '; if (sinceBreak >= 7) { sinceBreak = 0; html += '