diff --git a/web/index.html b/web/index.html index 77718198..81dba0d0 100644 --- a/web/index.html +++ b/web/index.html @@ -20,7 +20,8 @@ -
+
+
Updating...
on
diff --git a/web/kzedmaps.js b/web/kzedmaps.js index 763bdf6d..5b92fdf6 100644 --- a/web/kzedmaps.js +++ b/web/kzedmaps.js @@ -26,8 +26,10 @@ KzedProjection.prototype = { } }; +KzedMapType.prototype = new DynMapType(); function KzedMapType() {} KzedMapType.prototype = { + constructor: KzedMapType, projection: new KzedProjection(), tileSize: new google.maps.Size(128, 128), minZoom: 0, @@ -96,7 +98,7 @@ KzedMapType.prototype = { } if (tileName) { img = $('') - .attr('src', tileUrl(tileName)) + .attr('src', getTileUrl(tileName)) .error(function() { img.hide(); }) .css({ width: imgSize + 'px', @@ -106,9 +108,9 @@ KzedMapType.prototype = { marginTop: offset.y + 'px' }) .appendTo(tile); - tileDict[tileName] = img; + registerTile(this, tileName, img); } else { - delete tileDict[tileName]; + unregisterTile(this, tileName); } return tile.get(0); }, diff --git a/web/map.js b/web/map.js index c84379fe..eb72a959 100644 --- a/web/map.js +++ b/web/map.js @@ -1,88 +1,90 @@ if (!console) console = { log: function() {} }; -/* generic function for making an XMLHttpRequest - * url: request URL - * func: callback function for success - * type: 'text' by default (callback is called with response text) - * otherwise, callback is called with a parsed XML dom - * fail: callback function for failure - * post: if given, make a POST request instead of GET; post data given - * - * contenttype: if given for a POST, set request content-type header - */ -function makeRequest(url, func, type, fail, post, contenttype) -{ - var http_request = false; - - type = typeof(type) != 'undefined' ? type : 'text'; - fail = typeof(fail) != 'undefined' ? fail : function() { }; - - if(window.XMLHttpRequest) { - http_request = new XMLHttpRequest(); - } else if(window.ActiveXObject) { - http_request = new ActiveXObject("Microsoft.XMLHTTP"); +function DynMapType() { } +DynMapType.prototype = { + onTileUpdated: function(tile, tileName) { + var src = getTileUrl(tileName); + tile.attr('src', src); + tile.show(); } +}; - if(type == 'text') { - http_request.onreadystatechange = function() { - if(http_request.readyState == 4) { - if(http_request.status == 200) { - func(http_request.responseText); - } else { - fail(http_request); - } - } +function MinecraftClock(element) { this.element = element; } +MinecraftClock.prototype = { + element: null, + timeout: null, + time: null, + create: function(element) { + if (!element) element = $('
'); + this.element = element; + return element; + }, + setTime: function(time) { + if (this.timeout != null) { + window.clearTimeout(this.timeout); + this.timeout = null; } - } else { - http_request.onreadystatechange = function() { - if(http_request.readyState == 4) { - if(http_request.status == 200) { func(http_request.responseXML); } else { - fail(http_request); - } - } + this.time = time; + this.element + .addClass(time.day ? 'day' : 'night') + .removeClass(time.night ? 'day' : 'night') + .text(this.formatTime(time)); + + if (this.timeout == null) { + var me = this; + this.timeout = window.setTimeout(function() { + me.timeout = null; + me.setTime(getMinecraftTime(me.time.servertime+(1000/60))); + }, 700 /* should be 600, but since server-resyncing it looks better with 700 */); } + }, + formatTime: function(time) { + var formatDigits = function(n, digits) { + var s = n.toString(); + while (s.length < digits) { + s = '0' + s; + } + return s; + } + return formatDigits(time.hours, 2) + ':' + formatDigits(time.minutes, 2); } +}; - if(typeof(post) != 'undefined') { - http_request.open('POST', url, true); - if(typeof(contenttype) != 'undefined') - http_request.setRequestHeader("Content-Type", contenttype); - http_request.send(post); +var tileDict = new Array(); +var lastSeen = new Array(); + +function getTileUrl(tile, always) { + if(always) { + var now = new Date(); + return config.tileUrl + tile + '.png?' + now.getTime(); + } else if(tile in lastSeen) { + return config.tileUrl + tile + '.png?' + lastSeen[tile]; } else { - http_request.open('GET', url, true); - http_request.send(null); + return config.tileUrl + tile + '.png?0'; } } - var tileDict = new Array(); - var lastSeen = new Array(); +function registerTile(mapType, tileName, tile) { + tileDict[tileName] = { + tileElement: tile, + mapType: mapType + }; +} - function tileUrl(tile, always) { - if(always) { - var now = new Date(); - return config.tileUrl + tile + '.png?' + now.getTime(); - } else if(tile in lastSeen) { - return config.tileUrl + tile + '.png?' + lastSeen[tile]; - } else { - return config.tileUrl + tile + '.png?0'; - } - } +function unregisterTile(mapType, tileName) { + delete tileDict[tileName]; +} - function onTileUpdated(tileName, f) { - - } +function onTileUpdated(tileName) { + lastSeen[tileName] = lasttimestamp; - function imgSubst(tileName) { - if(!(tileName in tileDict)) - return; - - var src = tileUrl(tileName); - var t = tileDict[tileName]; - t.attr('src', src); - t.show(); + var tile = tileDict[tileName]; + if (tile) { + tile.mapType.onTileUpdated(tile.tileElement, tileName); } +} - +var clock = null; var markers = new Array(); var lasttimestamp = '0'; var followPlayer = ''; @@ -90,8 +92,6 @@ function makeRequest(url, func, type, fail, post, contenttype) var lst; var plistbtn; var lstopen = true; - var oldplayerlst = '[Connecting]'; - var servertime = 0; function updateMarker(mi) { if(mi.id in markers) { @@ -173,90 +173,75 @@ function makeRequest(url, func, type, fail, post, contenttype) function mapUpdate() { - makeRequest(config.updateUrl + lasttimestamp, function(res) { - var typeVisibleMap = { - 'warp': document.getElementById('showWarps').checked, - 'sign': document.getElementById('showSigns').checked, - 'home': document.getElementById('showHomes').checked, - 'spawn': document.getElementById('showSpawn').checked - }; - - var typeCount = {}; - - var rows = res.split('\n'); - var loggedin = new Array(); - var firstRow = rows[0].split(' '); - lasttimestamp = firstRow[0]; - servertime = firstRow[1]; - delete rows[0]; - - for(var line in rows) { - var p = rows[line].split(' '); - - if (p[0] == '') continue; + $.ajax({ + url: config.updateUrl + lasttimestamp, + success: function(res) { + $('#alert') + .hide(); + var typeVisibleMap = { + 'warp': document.getElementById('showWarps').checked, + 'sign': document.getElementById('showSigns').checked, + 'home': document.getElementById('showHomes').checked, + 'spawn': document.getElementById('showSpawn').checked + }; - ({ tile: function() { - var tileName = p[1]; - lastSeen[tileName] = lasttimestamp; - imgSubst(tileName); - } - }[p[0]] || function() { - var mi = { - id: p[0] + '_' + p[1], - text: p[1], - type: p[0], - position: map.getProjection().fromWorldToLatLng(p[2], p[3], p[4]), - visible: ((p[0] in typeVisibleMap) ? typeVisibleMap[p[0]] : true) - }; - - updateMarker(mi); - loggedin[mi.id] = 1; - if (!mi.type in typeCount) typeCount[mi.type] = 0; - typeCount[mi.type]++; - })(); - } - - var time = { - // Assuming it is day at 8:00 - hours: (parseInt(servertime / 1000)+8) % 24, - minutes: parseInt(((servertime / 1000) % 1) * 60), - seconds: parseInt(((((servertime / 1000) % 1) * 60) % 1) * 60) - }; - - - $('#clock') - .addClass(servertime > 12000 ? 'night' : 'day') - .removeClass(servertime > 12000 ? 'day' : 'night') - .text(formatTime(time)); - - for(var m in markers) { - if(!(m in loggedin)) { - markers[m].remove(null); - if (markers[m].playerRow) { - markers[m].playerRow.remove(); - } - delete markers[m]; + var typeCount = {}; + + var rows = res.split('\n'); + var loggedin = new Array(); + var firstRow = rows[0].split(' '); + lasttimestamp = firstRow[0]; + delete rows[0]; + + var servertime = firstRow[1]; + clock.setTime(getMinecraftTime(servertime)); + + for(var line in rows) { + var p = rows[line].split(' '); + + if (p[0] == '') continue; + + ({ tile: function() { + onTileUpdated(p[1]); + } + }[p[0]] || function() { + var mi = { + id: p[0] + '_' + p[1], + text: p[1], + type: p[0], + position: map.getProjection().fromWorldToLatLng(p[2], p[3], p[4]), + visible: ((p[0] in typeVisibleMap) ? typeVisibleMap[p[0]] : true) + }; + + updateMarker(mi); + loggedin[mi.id] = 1; + if (!mi.type in typeCount) typeCount[mi.type] = 0; + typeCount[mi.type]++; + })(); } + + for(var m in markers) { + if(!(m in loggedin)) { + markers[m].remove(null); + if (markers[m].playerRow) { + markers[m].playerRow.remove(); + } + delete markers[m]; + } + } + setTimeout(mapUpdate, config.updateRate); + document.getElementById('warpsDiv').style.display = (typeCount['warps'] == 0)?'none':''; + document.getElementById('signsDiv').style.display = (typeCount['signs'] == 0)?'none':''; + document.getElementById('homesDiv').style.display = (typeCount['homes'] == 0)?'none':''; + document.getElementById('spawnsDiv').style.display = (typeCount['spawns'] == 0)?'none':''; + }, + error: function(request, statusText, ex) { + $('#alert') + .text('Could not update map') + .show(); + setTimeout(mapUpdate, config.updateRate); } - setTimeout(mapUpdate, config.updateRate); - document.getElementById('warpsDiv').style.display = (typeCount['warps'] == 0)?'none':''; - document.getElementById('signsDiv').style.display = (typeCount['signs'] == 0)?'none':''; - document.getElementById('homesDiv').style.display = (typeCount['homes'] == 0)?'none':''; - document.getElementById('spawnsDiv').style.display = (typeCount['spawns'] == 0)?'none':''; - }, 'text', function() { alert('failed to get update data'); } ); - } - - function formatTime(time) { - //return formatDigits(time.hours, 2) + ':' + formatDigits(time.minutes, 2) + ':' + formatDigits(time.seconds, 2); - return formatDigits(time.hours, 2) + ':' + formatDigits(time.minutes, 2); - } - - function formatDigits(n, digits) { - var s = n.toString(); - while (s.length < digits) { - s = '0' + s; - } - return s; + }); } window.onload = function initialize() { @@ -317,6 +302,8 @@ function makeRequest(url, func, type, fail, post, contenttype) map.setMapTypeId(config.defaultMap); + clock = new MinecraftClock($('#clock')); + setTimeout(mapUpdate, config.updateRate); } diff --git a/web/minecraft.js b/web/minecraft.js index 4a1a8eff..0951be4e 100644 --- a/web/minecraft.js +++ b/web/minecraft.js @@ -68,3 +68,19 @@ function getMinecraftHead(player,size,completed) { completed(resizeImage(head,size)); } } + +function getMinecraftTime(servertime) { + servertime = parseInt(servertime); + return { + servertime: servertime, + days: parseInt((servertime+8000) / 24000), + + // Assuming it is day at 8:00 + hours: (parseInt(servertime / 1000)+8) % 24, + minutes: parseInt(((servertime / 1000) % 1) * 60), + seconds: parseInt(((((servertime / 1000) % 1) * 60) % 1) * 60), + + day: servertime > 12000, + night: servertime <= 12000 + }; +} diff --git a/web/style.css b/web/style.css index f7661352..ea53131d 100644 --- a/web/style.css +++ b/web/style.css @@ -87,6 +87,21 @@ a, a:visited, label { #clock.night { background-image: url(clock_night.png); } #clock.day { background-image: url(clock_day.png); } +#alert { + padding: 5px; + position: fixed; + margin: auto; + top: 0; + left: 0; + right: 0; + width: 25em; + text-align: center; + font: 14px/16px sans-serif; + box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.3); + background-color: InfoBackground; + border-radius: 0 0 3px 3px; +} + .playerIcon { }