diff --git a/web/map.js b/web/map.js
index a2324b3d..847f89ce 100644
--- a/web/map.js
+++ b/web/map.js
@@ -1,726 +1,726 @@
-var setup = {
- //Web based path to your tiles. Example: tileUrl: 'http://mydomain.com/myminecraftmap/',
- tileUrl: 'http://gorfyhome.com/minecraft/',
- //Web based path to your updates. Example: updateUrl: 'http://mydomain.com/myminecraftmap/up/',
- updateUrl: 'http:/gorfyhome.com/minecraft/up/',
- //Seconds the map should poll for updates. (Seconds) * 1000. The default is 2000 (every 2 seconds).
+var setup = {
+ //Web based path to your tiles. Example: tileUrl: 'http://mydomain.com/myminecraftmap/',
+ tileUrl: 'http://gorfyhome.com/minecraft/',
+ //Web based path to your updates. Example: updateUrl: 'http://mydomain.com/myminecraftmap/up/',
+ updateUrl: 'http:/gorfyhome.com/minecraft/up/',
+ //Seconds the map should poll for updates. (Seconds) * 1000. The default is 2000 (every 2 seconds).
updateRate: 2000
-};
+};
-/* THERE SHOULD BE NO NEED FOR MANUAL CONFIGURATION BEYOND THIS POINT */
-
-/**
- * This constructor creates a label and associates it with a marker.
- * It is for the private use of the MarkerWithLabel class.
- * @constructor
- * @param {Marker} marker The marker with which the label is to be associated.
- * @private
- */
-function MarkerLabel_(marker) {
- this.marker_ = marker;
-
- this.labelDiv_ = document.createElement("div");
- this.labelDiv_.style.cssText = "position: absolute; overflow: hidden;";
-
- // Set up the DIV for handling mouse events in the label. This DIV forms a transparent veil
- // in the "overlayMouseTarget" pane, a veil that covers just the label. This is done so that
- // events can be captured even if the label is in the shadow of a google.maps.InfoWindow.
- // Code is included here to ensure the veil is always exactly the same size as the label.
- this.eventDiv_ = document.createElement("div");
- this.eventDiv_.style.cssText = this.labelDiv_.style.cssText;
-}
-
-// MarkerLabel_ inherits from OverlayView:
-MarkerLabel_.prototype = new google.maps.OverlayView();
-
-/**
- * Adds the DIV representing the label to the DOM. This method is called
- * automatically when the marker's setMap method is called.
- * @private
- */
-MarkerLabel_.prototype.onAdd = function () {
- var me = this;
- var cMouseIsDown = false;
- var cDraggingInProgress = false;
- var cSavedPosition;
- var cSavedZIndex;
- var cLatOffset, cLngOffset;
- var cIgnoreClick;
-
- // Stops all processing of an event.
- //
- var cAbortEvent = function (e) {
- if (e.preventDefault) {
- e.preventDefault();
- }
- e.cancelBubble = true;
- if (e.stopPropagation) {
- e.stopPropagation();
- }
- };
-
- this.getPanes().overlayImage.appendChild(this.labelDiv_);
- this.getPanes().overlayMouseTarget.appendChild(this.eventDiv_);
-
- this.listeners_ = [
- google.maps.event.addDomListener(document, "mouseup", function (mEvent) {
- if (cDraggingInProgress) {
- mEvent.latLng = cSavedPosition;
- cIgnoreClick = true; // Set flag to ignore the click event reported after a label drag
- google.maps.event.trigger(me.marker_, "dragend", mEvent);
- }
- cMouseIsDown = false;
- google.maps.event.trigger(me.marker_, "mouseup", mEvent);
- }),
- google.maps.event.addListener(me.marker_.getMap(), "mousemove", function (mEvent) {
- if (cMouseIsDown && me.marker_.getDraggable()) {
- // Change the reported location from the mouse position to the marker position:
- mEvent.latLng = new google.maps.LatLng(mEvent.latLng.lat() - cLatOffset, mEvent.latLng.lng() - cLngOffset);
- cSavedPosition = mEvent.latLng;
- if (cDraggingInProgress) {
- google.maps.event.trigger(me.marker_, "drag", mEvent);
- } else {
- // Calculate offsets from the click point to the marker position:
- cLatOffset = mEvent.latLng.lat() - me.marker_.getPosition().lat();
- cLngOffset = mEvent.latLng.lng() - me.marker_.getPosition().lng();
- google.maps.event.trigger(me.marker_, "dragstart", mEvent);
- }
- }
- }),
- google.maps.event.addDomListener(this.eventDiv_, "mouseover", function (e) {
- //me.eventDiv_.style.cursor = "pointer";
- google.maps.event.trigger(me.marker_, "mouseover", e);
- }),
- google.maps.event.addDomListener(this.eventDiv_, "mouseout", function (e) {
- //me.eventDiv_.style.cursor = me.marker_.getCursor();
- google.maps.event.trigger(me.marker_, "mouseout", e);
- }),
- google.maps.event.addDomListener(this.eventDiv_, "click", function (e) {
- if (cIgnoreClick) { // Ignore the click reported when a label drag ends
- cIgnoreClick = false;
- } else {
- cAbortEvent(e); // Prevent click from being passed on to map
- google.maps.event.trigger(me.marker_, "click", e);
- }
- }),
- google.maps.event.addDomListener(this.eventDiv_, "dblclick", function (e) {
- cAbortEvent(e); // Prevent map zoom when double-clicking on a label
- google.maps.event.trigger(me.marker_, "dblclick", e);
- }),
- google.maps.event.addDomListener(this.eventDiv_, "mousedown", function (e) {
- cMouseIsDown = true;
- cDraggingInProgress = false;
- cLatOffset = 0;
- cLngOffset = 0;
- cAbortEvent(e); // Prevent map pan when starting a drag on a label
- google.maps.event.trigger(me.marker_, "mousedown", e);
- }),
- google.maps.event.addListener(this.marker_, "dragstart", function (mEvent) {
- cDraggingInProgress = true;
- cSavedZIndex = me.marker_.getZIndex();
- }),
- google.maps.event.addListener(this.marker_, "drag", function (mEvent) {
- me.marker_.setPosition(mEvent.latLng);
- me.marker_.setZIndex(1000000); // Moves the marker to the foreground during a drag
- }),
- google.maps.event.addListener(this.marker_, "dragend", function (mEvent) {
- cDraggingInProgress = false;
- me.marker_.setZIndex(cSavedZIndex);
- }),
- google.maps.event.addListener(this.marker_, "position_changed", function () {
- me.setPosition();
- }),
- google.maps.event.addListener(this.marker_, "zindex_changed", function () {
- me.setZIndex();
- }),
- google.maps.event.addListener(this.marker_, "visible_changed", function () {
- me.setVisible();
- }),
- google.maps.event.addListener(this.marker_, "labelvisible_changed", function () {
- me.setVisible();
- }),
- google.maps.event.addListener(this.marker_, "title_changed", function () {
- me.setTitle();
- }),
- google.maps.event.addListener(this.marker_, "labelcontent_changed", function () {
- me.setContent();
- }),
- google.maps.event.addListener(this.marker_, "labelanchor_changed", function () {
- me.setAnchor();
- }),
- google.maps.event.addListener(this.marker_, "labelclass_changed", function () {
- me.setStyles();
- }),
- google.maps.event.addListener(this.marker_, "labelstyle_changed", function () {
- me.setStyles();
- })
- ];
-};
-
-/**
- * Removes the DIV for the label from the DOM. It also removes all event handlers.
- * This method is called automatically when the marker's setMap(null)
- * method is called.
- * @private
- */
-MarkerLabel_.prototype.onRemove = function () {
- var i;
- this.labelDiv_.parentNode.removeChild(this.labelDiv_);
- this.eventDiv_.parentNode.removeChild(this.eventDiv_);
-
- // Remove event listeners:
- for (i = 0; i < this.listeners_.length; i++) {
- google.maps.event.removeListener(this.listeners_[i]);
- }
-};
-
-/**
- * Draws the label on the map.
- * @private
- */
-MarkerLabel_.prototype.draw = function () {
- this.setContent();
- this.setTitle();
- this.setStyles();
-};
-
-/**
- * Sets the content of the label.
- * The content can be plain text or an HTML DOM node.
- * @private
- */
-MarkerLabel_.prototype.setContent = function () {
- var content = this.marker_.get("labelContent");
- if (typeof content.nodeType === "undefined") {
- this.labelDiv_.innerHTML = content;
- this.eventDiv_.innerHTML = this.labelDiv_.innerHTML;
- } else {
- this.labelDiv_.appendChild(content);
- content = content.cloneNode(true);
- this.eventDiv_.appendChild(content);
- }
-};
-
-/**
- * Sets the content of the tool tip for the label. It is
- * always set to be the same as for the marker itself.
- * @private
- */
-MarkerLabel_.prototype.setTitle = function () {
- this.eventDiv_.title = this.marker_.getTitle() || "";
-};
-
-/**
- * Sets the style of the label by setting the style sheet and applying
- * other specific styles requested.
- * @private
- */
-MarkerLabel_.prototype.setStyles = function () {
- var i, labelStyle;
-
- // Apply style values from the style sheet defined in the labelClass parameter:
- this.labelDiv_.className = this.marker_.get("labelClass");
- this.eventDiv_.className = this.labelDiv_.className;
-
- // Clear existing inline style values:
- this.labelDiv_.style.cssText = "";
- this.eventDiv_.style.cssText = "";
- // Apply style values defined in the labelStyle parameter:
- labelStyle = this.marker_.get("labelStyle");
- for (i in labelStyle) {
- if (labelStyle.hasOwnProperty(i)) {
- this.labelDiv_.style[i] = labelStyle[i];
- this.eventDiv_.style[i] = labelStyle[i];
- }
- }
- this.setMandatoryStyles();
-};
-
-/**
- * Sets the mandatory styles to the DIV representing the label as well as to the
- * associated event DIV. This includes setting the DIV position, zIndex, and visibility.
- * @private
- */
-MarkerLabel_.prototype.setMandatoryStyles = function () {
- this.labelDiv_.style.position = "absolute";
- this.labelDiv_.style.overflow = "hidden";
- // Make sure the opacity setting causes the desired effect on MSIE:
- if (typeof this.labelDiv_.style.opacity !== "undefined") {
- this.labelDiv_.style.filter = "alpha(opacity=" + (this.labelDiv_.style.opacity * 100) + ")";
- }
-
- this.eventDiv_.style.position = this.labelDiv_.style.position;
- this.eventDiv_.style.overflow = this.labelDiv_.style.overflow;
- this.eventDiv_.style.opacity = 0.01; // Don't use 0; DIV won't be clickable on MSIE
- this.eventDiv_.style.filter = "alpha(opacity=1)"; // For MSIE
-
- this.setAnchor();
- this.setPosition(); // This also updates zIndex, if necessary.
- this.setVisible();
-};
-
-/**
- * Sets the anchor point of the label.
- * @private
- */
-MarkerLabel_.prototype.setAnchor = function () {
- var anchor = this.marker_.get("labelAnchor");
- this.labelDiv_.style.marginLeft = -anchor.x + "px";
- this.labelDiv_.style.marginTop = -anchor.y + "px";
- this.eventDiv_.style.marginLeft = -anchor.x + "px";
- this.eventDiv_.style.marginTop = -anchor.y + "px";
-};
-
-/**
- * Sets the position of the label. The zIndex is also updated, if necessary.
- * @private
- */
-MarkerLabel_.prototype.setPosition = function () {
- var position = this.getProjection().fromLatLngToDivPixel(this.marker_.getPosition());
-
- this.labelDiv_.style.left = position.x + "px";
- this.labelDiv_.style.top = position.y + "px";
- this.eventDiv_.style.left = this.labelDiv_.style.left;
- this.eventDiv_.style.top = this.labelDiv_.style.top;
-
- this.setZIndex();
-};
-
-/**
- * Sets the zIndex of the label. If the marker's zIndex property has not been defined, the zIndex
- * of the label is set to the vertical coordinate of the label. This is in keeping with the default
- * stacking order for Google Maps: markers to the south are in front of markers to the north.
- * @private
- */
-MarkerLabel_.prototype.setZIndex = function () {
- var zAdjust = (this.marker_.get("labelInBackground") ? -1 : +1);
- if (typeof this.marker_.getZIndex() === "undefined") {
- this.labelDiv_.style.zIndex = parseInt(this.labelDiv_.style.top, 10) + zAdjust;
- this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex;
- } else {
- this.labelDiv_.style.zIndex = this.marker_.getZIndex() + zAdjust;
- this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex;
- }
-};
-
-/**
- * Sets the visibility of the label. The label is visible only if the marker itself is
- * visible (i.e., its visible property is true) and the labelVisible property is true.
- * @private
- */
-MarkerLabel_.prototype.setVisible = function () {
- if (this.marker_.get("labelVisible")) {
- this.labelDiv_.style.display = this.marker_.getVisible() ? "block" : "none";
- } else {
- this.labelDiv_.style.display = "none";
- }
- this.eventDiv_.style.display = this.labelDiv_.style.display;
-};
-
-/**
- * @name MarkerWithLabelOptions
- * @class This class represents the optional parameter passed to the {@link MarkerWithLabel} constructor.
- * The properties available are the same as for google.maps.Marker with the addition
- * of the properties listed below. To change any of these additional properties after the labeled
- * marker has been created, call google.maps.Marker.set(propertyName, propertyValue).
- *
- * When any of these properties changes, a property changed event is fired. The names of these
- * events are derived from the name of the property and are of the form propertyname_changed.
- * For example, if the content of the label changes, a labelcontent_changed event
- * is fired.
- *
- * @property {string|Node} [labelContent] The content of the label (plain text or an HTML DOM node).
- * @property {Point} [labelAnchor] By default, a label is drawn with its anchor point at (0,0) so
- * that its top left corner is positioned at the anchor point of the associated marker. Use this
- * property to change the anchor point of the label. For example, to center a 50px-wide label
- * beneath a marker, specify a labelAnchor of google.maps.Point(25, 0).
- * (Note: x-values increase to the right and y-values increase to the bottom.)
- * @property {string} [labelClass] The name of the CSS class defining the styles for the label.
- * Note that style values for position, overflow, top,
- * left, zIndex, display, marginLeft, and
- * marginTop are ignored; these styles are for internal use only.
- * @property {Object} [labelStyle] An object literal whose properties define specific CSS
- * style values to be applied to the label. Style values defined here override those that may
- * be defined in the labelClass style sheet. If this property is changed after the
- * label has been created, all previously set styles (except those defined in the style sheet)
- * are removed from the label before the new style values are applied.
- * Note that style values for position, overflow, top,
- * left, zIndex, display, marginLeft, and
- * marginTop are ignored; these styles are for internal use only.
- * @property {boolean} [labelInBackground] A flag indicating whether a label that overlaps its
- * associated marker should appear in the background (i.e., in a plane below the marker).
- * The default is false, which causes the label to appear in the foreground.
- * @property {boolean} [labelVisible] A flag indicating whether the label is to be visible.
- * The default is true. Note that even if labelVisible is
- * true, the label will not be visible unless the associated marker is also
- * visible (i.e., unless the marker's visible property is true).
- */
-/**
- * Creates a MarkerWithLabel with the options specified in {@link MarkerWithLabelOptions}.
- * @constructor
- * @param {MarkerWithLabelOptions} [opt_options] The optional parameters.
- */
-function MarkerWithLabel(opt_options) {
- opt_options = opt_options || {};
- opt_options.labelContent = opt_options.labelContent || "";
- opt_options.labelAnchor = opt_options.labelAnchor || new google.maps.Point(0, 0);
- opt_options.labelClass = opt_options.labelClass || "markerLabels";
- opt_options.labelStyle = opt_options.labelStyle || {};
- opt_options.labelInBackground = opt_options.labelInBackground || false;
- if (typeof opt_options.labelVisible === "undefined") {
- opt_options.labelVisible = true;
- }
-
- this.label = new MarkerLabel_(this); // Bind the label to the marker
-
- // Call the parent constructor. It calls Marker.setValues to initialize, so all
- // the new parameters are conveniently saved and can be accessed with get/set.
- // Marker.set triggers a property changed event (called "propertyname_changed")
- // that the marker label listens for in order to react to state changes.
- google.maps.Marker.apply(this, arguments);
-}
-
-// MarkerWithLabel inherits from Marker:
-MarkerWithLabel.prototype = new google.maps.Marker();
-
-MarkerWithLabel.prototype.setMap = function (theMap) {
- // Call the inherited function...
- google.maps.Marker.prototype.setMap.apply(this, arguments);
-
- // ... then deal with the label:
- this.label.setMap(theMap);
-};
-
-
-
-/* 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");
- }
-
- 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);
- }
- }
- }
- } else {
- http_request.onreadystatechange = function() {
- if(http_request.readyState == 4) {
- if(http_request.status == 200) { func(http_request.responseXML); } else {
- fail(http_request);
- }
- }
- }
- }
-
- if(typeof(post) != 'undefined') {
- http_request.open('POST', url, true);
- if(typeof(contenttype) != 'undefined')
- http_request.setRequestHeader("Content-Type", contenttype);
- http_request.send(post);
- } else {
- http_request.open('GET', url, true);
- http_request.send(null);
- }
-}
-
-
- var config = {
- tileUrl: setup.tileUrl,
- updateUrl: setup.updateUrl,
- tileWidth: 128,
- tileHeight: 128,
- updateRate: setup.updateRate,
- zoomSize: [ 32, 128, 256 ]
- };
-
- function MCMapProjection() {
- }
-
- MCMapProjection.prototype.fromLatLngToPoint = function(latLng) {
- var x = (latLng.lng() * config.tileWidth)|0;
- var y = (latLng.lat() * config.tileHeight)|0;
- return new google.maps.Point(x, y);
- };
-
- MCMapProjection.prototype.fromPointToLatLng = function(point) {
- var lng = point.x / config.tileWidth;
- var lat = point.y / config.tileHeight;
- return new google.maps.LatLng(lat, lng);
- };
-
- function fromWorldToLatLng(x, y, z)
- {
- var dx = +x;
- var dy = +y - 127;
- var dz = +z;
- var px = dx + dz;
- var py = dx - dz - dy;
-
- var lng = -px / config.tileWidth / 2 + 0.5;
- var lat = py / config.tileHeight / 2;
-
- return new google.maps.LatLng(lat, lng);
- }
-
- function mcMapType() {
- }
-
- var tileDict = new Array();
- var lastSeen = new Array();
-
- function tileUrl(tile, always) {
- if(always) {
- var now = new Date();
- return config.tileUrl + 't_' + tile + '.png?' + now.getTime();
- } else if(tile in lastSeen) {
- return config.tileUrl + 't_' + tile + '.png?' + lastSeen[tile];
- } else {
- return config.tileUrl + 't_' + tile + '.png?0';
- }
- }
-
- function imgSubst(tile) {
- if(!(tile in tileDict))
- return;
-
- var src = tileUrl(tile);
- var t = tileDict[tile];
- t.src = src;
- t.style.display = '';
- t.onerror = function() {
- setTimeout(function() {
- t.src = tileUrl(tile, 1);
- }, 1000);
- t.onerror = '';
- }
- }
-
- mcMapType.prototype.tileSize = new google.maps.Size(config.tileWidth, config.tileHeight);
- mcMapType.prototype.minZoom = 1;
- mcMapType.prototype.maxZoom = 2;
- mcMapType.prototype.getTile = function(coord, zoom, doc) {
- var img = doc.createElement('IMG');
-
- img.onerror = function() { img.style.display = 'none'; }
-
- img.style.width = config.zoomSize[zoom] + 'px';
- img.style.height = config.zoomSize[zoom] + 'px';
- img.style.borderStyle = 'none';
-
- var tilename = (- coord.x * config.tileWidth) + '_' + coord.y * config.tileHeight;
- tileDict[tilename] = img;
-
- var url = tileUrl(tilename);
- img.src = url;
- //img.style.background = 'url(' + url + ')';
- //img.innerHTML = '' + tilename + '';
-
- return img;
- }
-
- var markers = new Array();
- var lasttimestamp = 0;
- var followPlayer = '';
-
- var lst;
- var plistbtn;
- var lstopen = true;
- var oldplayerlst = '[Connecting]';
-
- function mapUpdate()
- {
- makeRequest(config.updateUrl + lasttimestamp, function(res) {
- var rows = res.split('\n');
- var loggedin = new Array();
-
- lasttimestamp = rows[0];
- delete rows[0];
-
- var playerlst = ''
-
- for(var line in rows) {
- var p = rows[line].split(' ');
- loggedin[p[0]] = 1;
- if(p[0] == '') continue;
-
- if(p.length == 4) {
- if(playerlst != '') playerlst += '
';
- playerlst += '
' + p[0] + '';
-
- if(p[0] == followPlayer) {
- map.setCenter(fromWorldToLatLng(p[1], p[2], p[3]));
- }
-
- if(p[0] in markers) {
- var m = markers[p[0]];
- var converted = fromWorldToLatLng(p[1], p[2], p[3]);
- m.setPosition(converted);
- } else {
- var converted = fromWorldToLatLng(p[1], p[2], p[3]);
- var marker = new MarkerWithLabel({
- position: converted,
- map: map,
- labelContent: p[0],
- labelAnchor: new google.maps.Point(-14, 10),
- labelClass: "labels",
- clickable: false,
- flat: true,
- icon: new google.maps.MarkerImage('marker.png', new google.maps.Size(28, 28), new google.maps.Point(0, 0), new google.maps.Point(14, 14))
- });
-
- markers[p[0]] = marker;
- }
- } else if(p.length == 6) {
- if(p[0] in markers) {
- var m = markers[p[0]];
- var converted = fromWorldToLatLng(p[2], p[3], p[4]);
- m.setPosition(converted);
- } else {
- var image = 'sign.png';
-
- if (p[1] == 'warp')
- image = 'watch.png';
- else if (p[1] == 'home')
- image = 'list_on.png';
- else if (p[1] == 'spawn')
- image = 'list_on.png';
-
- var converted = fromWorldToLatLng(p[2], p[3], p[4]);
- var marker = new MarkerWithLabel({
- position: converted,
- map: map,
- labelContent: p[0],
- labelAnchor: new google.maps.Point(-14, 10),
- labelClass: "labels",
- clickable: false,
- flat: true,
- icon: new google.maps.MarkerImage(image, new google.maps.Size(28, 28), new google.maps.Point(0, 0), new google.maps.Point(14, 14))
- });
-
- markers[p[0]] = marker;
- }
- } else if(p.length == 1) {
- lastSeen[p[0]] = lasttimestamp;
- imgSubst(p[0]);
- }
- }
-
- if(playerlst != oldplayerlst) {
- oldplayerlst = playerlst;
- lst.innerHTML = playerlst;
- }
-
- for(var m in markers) {
- if(!(m in loggedin)) {
- markers[m].setMap(null);
- delete markers[m];
- }
- }
-
- setTimeout(mapUpdate, config.updateRate);
- }, 'text', function() { alert('failed to get update data'); } );
- }
-
- window.onload = function initialize() {
- lst = document.getElementById('lst');
- plistbtn = document.getElementById('plistbtn');
- var mapOptions = {
- zoom: 1,
- center: new google.maps.LatLng(0, 1),
- navigationControl: true,
- navigationControlOptions: {
- style: google.maps.NavigationControlStyle.SMALL
- },
- scaleControl: false,
- mapTypeControl: false,
- streetViewControl: false,
- mapTypeId: 'mcmap'
- };
- map = new google.maps.Map(document.getElementById("mcmap"), mapOptions);
- mapType = new mcMapType();
- mapType.projection = new MCMapProjection();
- map.zoom_changed = function() {
- mapType.tileSize = new google.maps.Size(config.zoomSize[map.zoom], config.zoomSize[map.zoom]);
- };
-
- google.maps.event.addListener(map, 'dragstart', function(mEvent) {
- plfollow('');
- });
-
- map.dragstart = plfollow('');
- map.mapTypes.set('mcmap', mapType);
- map.setMapTypeId('mcmap');
- mapUpdate();
- }
-
- function plistopen() {
- if(lstopen) {
- lstopen = false;
- lst.style.display = 'none';
- lst.style.visibility = 'hidden';
- plistbtn.src = 'list_off.png';
- } else {
- lstopen = true;
- lst.style.display = '';
- lst.style.visibility = '';
- plistbtn.src = 'list_on.png';
- }
- }
-
- function plclick(name) {
- if(name in markers) {
- if(name != followPlayer) plfollow('');
- map.setCenter(markers[name].getPosition());
- }
- }
-
- function plfollow(name) {
- var icon;
-
- if(followPlayer == name) {
- icon = document.getElementById('icon_' + followPlayer);
- if(icon) icon.src = 'follow_off.png';
- followPlayer = '';
- return;
- }
-
- if(followPlayer) {
- icon = document.getElementById('icon_' + followPlayer);
- if(icon) icon.src = 'follow_off.png';
- followPlayer = '';
- }
-
- if(!name) return;
-
- icon = document.getElementById('icon_' + name);
- if(icon) icon.src = 'follow_on.png';
- followPlayer = name;
-
- if(name in markers) {
- map.setCenter(markers[name].getPosition());
- }
- }
+/* THERE SHOULD BE NO NEED FOR MANUAL CONFIGURATION BEYOND THIS POINT */
+
+/**
+ * This constructor creates a label and associates it with a marker.
+ * It is for the private use of the MarkerWithLabel class.
+ * @constructor
+ * @param {Marker} marker The marker with which the label is to be associated.
+ * @private
+ */
+function MarkerLabel_(marker) {
+ this.marker_ = marker;
+
+ this.labelDiv_ = document.createElement("div");
+ this.labelDiv_.style.cssText = "position: absolute; overflow: hidden;";
+
+ // Set up the DIV for handling mouse events in the label. This DIV forms a transparent veil
+ // in the "overlayMouseTarget" pane, a veil that covers just the label. This is done so that
+ // events can be captured even if the label is in the shadow of a google.maps.InfoWindow.
+ // Code is included here to ensure the veil is always exactly the same size as the label.
+ this.eventDiv_ = document.createElement("div");
+ this.eventDiv_.style.cssText = this.labelDiv_.style.cssText;
+}
+
+// MarkerLabel_ inherits from OverlayView:
+MarkerLabel_.prototype = new google.maps.OverlayView();
+
+/**
+ * Adds the DIV representing the label to the DOM. This method is called
+ * automatically when the marker's setMap method is called.
+ * @private
+ */
+MarkerLabel_.prototype.onAdd = function () {
+ var me = this;
+ var cMouseIsDown = false;
+ var cDraggingInProgress = false;
+ var cSavedPosition;
+ var cSavedZIndex;
+ var cLatOffset, cLngOffset;
+ var cIgnoreClick;
+
+ // Stops all processing of an event.
+ //
+ var cAbortEvent = function (e) {
+ if (e.preventDefault) {
+ e.preventDefault();
+ }
+ e.cancelBubble = true;
+ if (e.stopPropagation) {
+ e.stopPropagation();
+ }
+ };
+
+ this.getPanes().overlayImage.appendChild(this.labelDiv_);
+ this.getPanes().overlayMouseTarget.appendChild(this.eventDiv_);
+
+ this.listeners_ = [
+ google.maps.event.addDomListener(document, "mouseup", function (mEvent) {
+ if (cDraggingInProgress) {
+ mEvent.latLng = cSavedPosition;
+ cIgnoreClick = true; // Set flag to ignore the click event reported after a label drag
+ google.maps.event.trigger(me.marker_, "dragend", mEvent);
+ }
+ cMouseIsDown = false;
+ google.maps.event.trigger(me.marker_, "mouseup", mEvent);
+ }),
+ google.maps.event.addListener(me.marker_.getMap(), "mousemove", function (mEvent) {
+ if (cMouseIsDown && me.marker_.getDraggable()) {
+ // Change the reported location from the mouse position to the marker position:
+ mEvent.latLng = new google.maps.LatLng(mEvent.latLng.lat() - cLatOffset, mEvent.latLng.lng() - cLngOffset);
+ cSavedPosition = mEvent.latLng;
+ if (cDraggingInProgress) {
+ google.maps.event.trigger(me.marker_, "drag", mEvent);
+ } else {
+ // Calculate offsets from the click point to the marker position:
+ cLatOffset = mEvent.latLng.lat() - me.marker_.getPosition().lat();
+ cLngOffset = mEvent.latLng.lng() - me.marker_.getPosition().lng();
+ google.maps.event.trigger(me.marker_, "dragstart", mEvent);
+ }
+ }
+ }),
+ google.maps.event.addDomListener(this.eventDiv_, "mouseover", function (e) {
+ //me.eventDiv_.style.cursor = "pointer";
+ google.maps.event.trigger(me.marker_, "mouseover", e);
+ }),
+ google.maps.event.addDomListener(this.eventDiv_, "mouseout", function (e) {
+ //me.eventDiv_.style.cursor = me.marker_.getCursor();
+ google.maps.event.trigger(me.marker_, "mouseout", e);
+ }),
+ google.maps.event.addDomListener(this.eventDiv_, "click", function (e) {
+ if (cIgnoreClick) { // Ignore the click reported when a label drag ends
+ cIgnoreClick = false;
+ } else {
+ cAbortEvent(e); // Prevent click from being passed on to map
+ google.maps.event.trigger(me.marker_, "click", e);
+ }
+ }),
+ google.maps.event.addDomListener(this.eventDiv_, "dblclick", function (e) {
+ cAbortEvent(e); // Prevent map zoom when double-clicking on a label
+ google.maps.event.trigger(me.marker_, "dblclick", e);
+ }),
+ google.maps.event.addDomListener(this.eventDiv_, "mousedown", function (e) {
+ cMouseIsDown = true;
+ cDraggingInProgress = false;
+ cLatOffset = 0;
+ cLngOffset = 0;
+ cAbortEvent(e); // Prevent map pan when starting a drag on a label
+ google.maps.event.trigger(me.marker_, "mousedown", e);
+ }),
+ google.maps.event.addListener(this.marker_, "dragstart", function (mEvent) {
+ cDraggingInProgress = true;
+ cSavedZIndex = me.marker_.getZIndex();
+ }),
+ google.maps.event.addListener(this.marker_, "drag", function (mEvent) {
+ me.marker_.setPosition(mEvent.latLng);
+ me.marker_.setZIndex(1000000); // Moves the marker to the foreground during a drag
+ }),
+ google.maps.event.addListener(this.marker_, "dragend", function (mEvent) {
+ cDraggingInProgress = false;
+ me.marker_.setZIndex(cSavedZIndex);
+ }),
+ google.maps.event.addListener(this.marker_, "position_changed", function () {
+ me.setPosition();
+ }),
+ google.maps.event.addListener(this.marker_, "zindex_changed", function () {
+ me.setZIndex();
+ }),
+ google.maps.event.addListener(this.marker_, "visible_changed", function () {
+ me.setVisible();
+ }),
+ google.maps.event.addListener(this.marker_, "labelvisible_changed", function () {
+ me.setVisible();
+ }),
+ google.maps.event.addListener(this.marker_, "title_changed", function () {
+ me.setTitle();
+ }),
+ google.maps.event.addListener(this.marker_, "labelcontent_changed", function () {
+ me.setContent();
+ }),
+ google.maps.event.addListener(this.marker_, "labelanchor_changed", function () {
+ me.setAnchor();
+ }),
+ google.maps.event.addListener(this.marker_, "labelclass_changed", function () {
+ me.setStyles();
+ }),
+ google.maps.event.addListener(this.marker_, "labelstyle_changed", function () {
+ me.setStyles();
+ })
+ ];
+};
+
+/**
+ * Removes the DIV for the label from the DOM. It also removes all event handlers.
+ * This method is called automatically when the marker's setMap(null)
+ * method is called.
+ * @private
+ */
+MarkerLabel_.prototype.onRemove = function () {
+ var i;
+ this.labelDiv_.parentNode.removeChild(this.labelDiv_);
+ this.eventDiv_.parentNode.removeChild(this.eventDiv_);
+
+ // Remove event listeners:
+ for (i = 0; i < this.listeners_.length; i++) {
+ google.maps.event.removeListener(this.listeners_[i]);
+ }
+};
+
+/**
+ * Draws the label on the map.
+ * @private
+ */
+MarkerLabel_.prototype.draw = function () {
+ this.setContent();
+ this.setTitle();
+ this.setStyles();
+};
+
+/**
+ * Sets the content of the label.
+ * The content can be plain text or an HTML DOM node.
+ * @private
+ */
+MarkerLabel_.prototype.setContent = function () {
+ var content = this.marker_.get("labelContent");
+ if (typeof content.nodeType === "undefined") {
+ this.labelDiv_.innerHTML = content;
+ this.eventDiv_.innerHTML = this.labelDiv_.innerHTML;
+ } else {
+ this.labelDiv_.appendChild(content);
+ content = content.cloneNode(true);
+ this.eventDiv_.appendChild(content);
+ }
+};
+
+/**
+ * Sets the content of the tool tip for the label. It is
+ * always set to be the same as for the marker itself.
+ * @private
+ */
+MarkerLabel_.prototype.setTitle = function () {
+ this.eventDiv_.title = this.marker_.getTitle() || "";
+};
+
+/**
+ * Sets the style of the label by setting the style sheet and applying
+ * other specific styles requested.
+ * @private
+ */
+MarkerLabel_.prototype.setStyles = function () {
+ var i, labelStyle;
+
+ // Apply style values from the style sheet defined in the labelClass parameter:
+ this.labelDiv_.className = this.marker_.get("labelClass");
+ this.eventDiv_.className = this.labelDiv_.className;
+
+ // Clear existing inline style values:
+ this.labelDiv_.style.cssText = "";
+ this.eventDiv_.style.cssText = "";
+ // Apply style values defined in the labelStyle parameter:
+ labelStyle = this.marker_.get("labelStyle");
+ for (i in labelStyle) {
+ if (labelStyle.hasOwnProperty(i)) {
+ this.labelDiv_.style[i] = labelStyle[i];
+ this.eventDiv_.style[i] = labelStyle[i];
+ }
+ }
+ this.setMandatoryStyles();
+};
+
+/**
+ * Sets the mandatory styles to the DIV representing the label as well as to the
+ * associated event DIV. This includes setting the DIV position, zIndex, and visibility.
+ * @private
+ */
+MarkerLabel_.prototype.setMandatoryStyles = function () {
+ this.labelDiv_.style.position = "absolute";
+ this.labelDiv_.style.overflow = "hidden";
+ // Make sure the opacity setting causes the desired effect on MSIE:
+ if (typeof this.labelDiv_.style.opacity !== "undefined") {
+ this.labelDiv_.style.filter = "alpha(opacity=" + (this.labelDiv_.style.opacity * 100) + ")";
+ }
+
+ this.eventDiv_.style.position = this.labelDiv_.style.position;
+ this.eventDiv_.style.overflow = this.labelDiv_.style.overflow;
+ this.eventDiv_.style.opacity = 0.01; // Don't use 0; DIV won't be clickable on MSIE
+ this.eventDiv_.style.filter = "alpha(opacity=1)"; // For MSIE
+
+ this.setAnchor();
+ this.setPosition(); // This also updates zIndex, if necessary.
+ this.setVisible();
+};
+
+/**
+ * Sets the anchor point of the label.
+ * @private
+ */
+MarkerLabel_.prototype.setAnchor = function () {
+ var anchor = this.marker_.get("labelAnchor");
+ this.labelDiv_.style.marginLeft = -anchor.x + "px";
+ this.labelDiv_.style.marginTop = -anchor.y + "px";
+ this.eventDiv_.style.marginLeft = -anchor.x + "px";
+ this.eventDiv_.style.marginTop = -anchor.y + "px";
+};
+
+/**
+ * Sets the position of the label. The zIndex is also updated, if necessary.
+ * @private
+ */
+MarkerLabel_.prototype.setPosition = function () {
+ var position = this.getProjection().fromLatLngToDivPixel(this.marker_.getPosition());
+
+ this.labelDiv_.style.left = position.x + "px";
+ this.labelDiv_.style.top = position.y + "px";
+ this.eventDiv_.style.left = this.labelDiv_.style.left;
+ this.eventDiv_.style.top = this.labelDiv_.style.top;
+
+ this.setZIndex();
+};
+
+/**
+ * Sets the zIndex of the label. If the marker's zIndex property has not been defined, the zIndex
+ * of the label is set to the vertical coordinate of the label. This is in keeping with the default
+ * stacking order for Google Maps: markers to the south are in front of markers to the north.
+ * @private
+ */
+MarkerLabel_.prototype.setZIndex = function () {
+ var zAdjust = (this.marker_.get("labelInBackground") ? -1 : +1);
+ if (typeof this.marker_.getZIndex() === "undefined") {
+ this.labelDiv_.style.zIndex = parseInt(this.labelDiv_.style.top, 10) + zAdjust;
+ this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex;
+ } else {
+ this.labelDiv_.style.zIndex = this.marker_.getZIndex() + zAdjust;
+ this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex;
+ }
+};
+
+/**
+ * Sets the visibility of the label. The label is visible only if the marker itself is
+ * visible (i.e., its visible property is true) and the labelVisible property is true.
+ * @private
+ */
+MarkerLabel_.prototype.setVisible = function () {
+ if (this.marker_.get("labelVisible")) {
+ this.labelDiv_.style.display = this.marker_.getVisible() ? "block" : "none";
+ } else {
+ this.labelDiv_.style.display = "none";
+ }
+ this.eventDiv_.style.display = this.labelDiv_.style.display;
+};
+
+/**
+ * @name MarkerWithLabelOptions
+ * @class This class represents the optional parameter passed to the {@link MarkerWithLabel} constructor.
+ * The properties available are the same as for google.maps.Marker with the addition
+ * of the properties listed below. To change any of these additional properties after the labeled
+ * marker has been created, call google.maps.Marker.set(propertyName, propertyValue).
+ *
+ * When any of these properties changes, a property changed event is fired. The names of these
+ * events are derived from the name of the property and are of the form propertyname_changed.
+ * For example, if the content of the label changes, a labelcontent_changed event
+ * is fired.
+ *
+ * @property {string|Node} [labelContent] The content of the label (plain text or an HTML DOM node).
+ * @property {Point} [labelAnchor] By default, a label is drawn with its anchor point at (0,0) so
+ * that its top left corner is positioned at the anchor point of the associated marker. Use this
+ * property to change the anchor point of the label. For example, to center a 50px-wide label
+ * beneath a marker, specify a labelAnchor of google.maps.Point(25, 0).
+ * (Note: x-values increase to the right and y-values increase to the bottom.)
+ * @property {string} [labelClass] The name of the CSS class defining the styles for the label.
+ * Note that style values for position, overflow, top,
+ * left, zIndex, display, marginLeft, and
+ * marginTop are ignored; these styles are for internal use only.
+ * @property {Object} [labelStyle] An object literal whose properties define specific CSS
+ * style values to be applied to the label. Style values defined here override those that may
+ * be defined in the labelClass style sheet. If this property is changed after the
+ * label has been created, all previously set styles (except those defined in the style sheet)
+ * are removed from the label before the new style values are applied.
+ * Note that style values for position, overflow, top,
+ * left, zIndex, display, marginLeft, and
+ * marginTop are ignored; these styles are for internal use only.
+ * @property {boolean} [labelInBackground] A flag indicating whether a label that overlaps its
+ * associated marker should appear in the background (i.e., in a plane below the marker).
+ * The default is false, which causes the label to appear in the foreground.
+ * @property {boolean} [labelVisible] A flag indicating whether the label is to be visible.
+ * The default is true. Note that even if labelVisible is
+ * true, the label will not be visible unless the associated marker is also
+ * visible (i.e., unless the marker's visible property is true).
+ */
+/**
+ * Creates a MarkerWithLabel with the options specified in {@link MarkerWithLabelOptions}.
+ * @constructor
+ * @param {MarkerWithLabelOptions} [opt_options] The optional parameters.
+ */
+function MarkerWithLabel(opt_options) {
+ opt_options = opt_options || {};
+ opt_options.labelContent = opt_options.labelContent || "";
+ opt_options.labelAnchor = opt_options.labelAnchor || new google.maps.Point(0, 0);
+ opt_options.labelClass = opt_options.labelClass || "markerLabels";
+ opt_options.labelStyle = opt_options.labelStyle || {};
+ opt_options.labelInBackground = opt_options.labelInBackground || false;
+ if (typeof opt_options.labelVisible === "undefined") {
+ opt_options.labelVisible = true;
+ }
+
+ this.label = new MarkerLabel_(this); // Bind the label to the marker
+
+ // Call the parent constructor. It calls Marker.setValues to initialize, so all
+ // the new parameters are conveniently saved and can be accessed with get/set.
+ // Marker.set triggers a property changed event (called "propertyname_changed")
+ // that the marker label listens for in order to react to state changes.
+ google.maps.Marker.apply(this, arguments);
+}
+
+// MarkerWithLabel inherits from Marker:
+MarkerWithLabel.prototype = new google.maps.Marker();
+
+MarkerWithLabel.prototype.setMap = function (theMap) {
+ // Call the inherited function...
+ google.maps.Marker.prototype.setMap.apply(this, arguments);
+
+ // ... then deal with the label:
+ this.label.setMap(theMap);
+};
+
+
+
+/* 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");
+ }
+
+ 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);
+ }
+ }
+ }
+ } else {
+ http_request.onreadystatechange = function() {
+ if(http_request.readyState == 4) {
+ if(http_request.status == 200) { func(http_request.responseXML); } else {
+ fail(http_request);
+ }
+ }
+ }
+ }
+
+ if(typeof(post) != 'undefined') {
+ http_request.open('POST', url, true);
+ if(typeof(contenttype) != 'undefined')
+ http_request.setRequestHeader("Content-Type", contenttype);
+ http_request.send(post);
+ } else {
+ http_request.open('GET', url, true);
+ http_request.send(null);
+ }
+}
+
+
+ var config = {
+ tileUrl: setup.tileUrl,
+ updateUrl: setup.updateUrl,
+ tileWidth: 128,
+ tileHeight: 128,
+ updateRate: setup.updateRate,
+ zoomSize: [ 32, 128, 256 ]
+ };
+
+ function MCMapProjection() {
+ }
+
+ MCMapProjection.prototype.fromLatLngToPoint = function(latLng) {
+ var x = (latLng.lng() * config.tileWidth)|0;
+ var y = (latLng.lat() * config.tileHeight)|0;
+ return new google.maps.Point(x, y);
+ };
+
+ MCMapProjection.prototype.fromPointToLatLng = function(point) {
+ var lng = point.x / config.tileWidth;
+ var lat = point.y / config.tileHeight;
+ return new google.maps.LatLng(lat, lng);
+ };
+
+ function fromWorldToLatLng(x, y, z)
+ {
+ var dx = +x;
+ var dy = +y - 127;
+ var dz = +z;
+ var px = dx + dz;
+ var py = dx - dz - dy;
+
+ var lng = -px / config.tileWidth / 2 + 0.5;
+ var lat = py / config.tileHeight / 2;
+
+ return new google.maps.LatLng(lat, lng);
+ }
+
+ function mcMapType() {
+ }
+
+ var tileDict = new Array();
+ var lastSeen = new Array();
+
+ function tileUrl(tile, always) {
+ if(always) {
+ var now = new Date();
+ return config.tileUrl + 't_' + tile + '.png?' + now.getTime();
+ } else if(tile in lastSeen) {
+ return config.tileUrl + 't_' + tile + '.png?' + lastSeen[tile];
+ } else {
+ return config.tileUrl + 't_' + tile + '.png?0';
+ }
+ }
+
+ function imgSubst(tile) {
+ if(!(tile in tileDict))
+ return;
+
+ var src = tileUrl(tile);
+ var t = tileDict[tile];
+ t.src = src;
+ t.style.display = '';
+ t.onerror = function() {
+ setTimeout(function() {
+ t.src = tileUrl(tile, 1);
+ }, 1000);
+ t.onerror = '';
+ }
+ }
+
+ mcMapType.prototype.tileSize = new google.maps.Size(config.tileWidth, config.tileHeight);
+ mcMapType.prototype.minZoom = 1;
+ mcMapType.prototype.maxZoom = 2;
+ mcMapType.prototype.getTile = function(coord, zoom, doc) {
+ var img = doc.createElement('IMG');
+
+ img.onerror = function() { img.style.display = 'none'; }
+
+ img.style.width = config.zoomSize[zoom] + 'px';
+ img.style.height = config.zoomSize[zoom] + 'px';
+ img.style.borderStyle = 'none';
+
+ var tilename = (- coord.x * config.tileWidth) + '_' + coord.y * config.tileHeight;
+ tileDict[tilename] = img;
+
+ var url = tileUrl(tilename);
+ img.src = url;
+ //img.style.background = 'url(' + url + ')';
+ //img.innerHTML = '' + tilename + '';
+
+ return img;
+ }
+
+ var markers = new Array();
+ var lasttimestamp = 0;
+ var followPlayer = '';
+
+ var lst;
+ var plistbtn;
+ var lstopen = true;
+ var oldplayerlst = '[Connecting]';
+
+ function mapUpdate()
+ {
+ makeRequest(config.updateUrl + lasttimestamp, function(res) {
+ var rows = res.split('\n');
+ var loggedin = new Array();
+
+ lasttimestamp = rows[0];
+ delete rows[0];
+
+ var playerlst = ''
+
+ for(var line in rows) {
+ var p = rows[line].split(' ');
+ loggedin[p[0]] = 1;
+ if(p[0] == '') continue;
+
+ if(p.length == 4) {
+ if(playerlst != '') playerlst += '
';
+ playerlst += '
' + p[0] + '';
+
+ if(p[0] == followPlayer) {
+ map.setCenter(fromWorldToLatLng(p[1], p[2], p[3]));
+ }
+
+ if(p[0] in markers) {
+ var m = markers[p[0]];
+ var converted = fromWorldToLatLng(p[1], p[2], p[3]);
+ m.setPosition(converted);
+ } else {
+ var converted = fromWorldToLatLng(p[1], p[2], p[3]);
+ var marker = new MarkerWithLabel({
+ position: converted,
+ map: map,
+ labelContent: p[0],
+ labelAnchor: new google.maps.Point(-14, 10),
+ labelClass: "labels",
+ clickable: false,
+ flat: true,
+ icon: new google.maps.MarkerImage('marker.png', new google.maps.Size(28, 28), new google.maps.Point(0, 0), new google.maps.Point(14, 14))
+ });
+
+ markers[p[0]] = marker;
+ }
+ } else if(p.length == 6) {
+ if(p[0] in markers) {
+ var m = markers[p[0]];
+ var converted = fromWorldToLatLng(p[3], p[4], p[5]);
+ m.setPosition(converted);
+ } else {
+ var image = 'sign.png';
+
+ if (p[1] == 'warp')
+ image = 'watch.png';
+ else if (p[1] == 'home')
+ image = 'list_on.png';
+ else if (p[1] == 'spawn')
+ image = 'list_on.png';
+
+ var converted = fromWorldToLatLng(p[3], p[4], p[5]);
+ var marker = new MarkerWithLabel({
+ position: converted,
+ map: map,
+ labelContent: p[0],
+ labelAnchor: new google.maps.Point(-14, 10),
+ labelClass: "labels",
+ clickable: false,
+ flat: true,
+ icon: new google.maps.MarkerImage(image, new google.maps.Size(28, 28), new google.maps.Point(0, 0), new google.maps.Point(14, 14))
+ });
+
+ markers[p[0]] = marker;
+ }
+ } else if(p.length == 1) {
+ lastSeen[p[0]] = lasttimestamp;
+ imgSubst(p[0]);
+ }
+ }
+
+ if(playerlst != oldplayerlst) {
+ oldplayerlst = playerlst;
+ lst.innerHTML = playerlst;
+ }
+
+ for(var m in markers) {
+ if(!(m in loggedin)) {
+ markers[m].setMap(null);
+ delete markers[m];
+ }
+ }
+
+ setTimeout(mapUpdate, config.updateRate);
+ }, 'text', function() { alert('failed to get update data'); } );
+ }
+
+ window.onload = function initialize() {
+ lst = document.getElementById('lst');
+ plistbtn = document.getElementById('plistbtn');
+ var mapOptions = {
+ zoom: 1,
+ center: new google.maps.LatLng(0, 1),
+ navigationControl: true,
+ navigationControlOptions: {
+ style: google.maps.NavigationControlStyle.SMALL
+ },
+ scaleControl: false,
+ mapTypeControl: false,
+ streetViewControl: false,
+ mapTypeId: 'mcmap'
+ };
+ map = new google.maps.Map(document.getElementById("mcmap"), mapOptions);
+ mapType = new mcMapType();
+ mapType.projection = new MCMapProjection();
+ map.zoom_changed = function() {
+ mapType.tileSize = new google.maps.Size(config.zoomSize[map.zoom], config.zoomSize[map.zoom]);
+ };
+
+ google.maps.event.addListener(map, 'dragstart', function(mEvent) {
+ plfollow('');
+ });
+
+ map.dragstart = plfollow('');
+ map.mapTypes.set('mcmap', mapType);
+ map.setMapTypeId('mcmap');
+ mapUpdate();
+ }
+
+ function plistopen() {
+ if(lstopen) {
+ lstopen = false;
+ lst.style.display = 'none';
+ lst.style.visibility = 'hidden';
+ plistbtn.src = 'list_off.png';
+ } else {
+ lstopen = true;
+ lst.style.display = '';
+ lst.style.visibility = '';
+ plistbtn.src = 'list_on.png';
+ }
+ }
+
+ function plclick(name) {
+ if(name in markers) {
+ if(name != followPlayer) plfollow('');
+ map.setCenter(markers[name].getPosition());
+ }
+ }
+
+ function plfollow(name) {
+ var icon;
+
+ if(followPlayer == name) {
+ icon = document.getElementById('icon_' + followPlayer);
+ if(icon) icon.src = 'follow_off.png';
+ followPlayer = '';
+ return;
+ }
+
+ if(followPlayer) {
+ icon = document.getElementById('icon_' + followPlayer);
+ if(icon) icon.src = 'follow_off.png';
+ followPlayer = '';
+ }
+
+ if(!name) return;
+
+ icon = document.getElementById('icon_' + name);
+ if(icon) icon.src = 'follow_on.png';
+ followPlayer = name;
+
+ if(name in markers) {
+ map.setCenter(markers[name].getPosition());
+ }
+ }