Index: binary-improvements/webserver/js/inventory_dialog.js
===================================================================
--- binary-improvements/webserver/js/inventory_dialog.js	(revision 245)
+++ binary-improvements/webserver/js/inventory_dialog.js	(revision 249)
@@ -57,4 +57,5 @@
 
 		$( "#playerInventoryDialog" ).css("z-index", "1010").dialog({
+			dialogClass: "playerInventoryDialog",
 			modal: true,
 			width: BAG_COLS*(INV_ITEM_WIDTH+14) + 3*(INV_ITEM_WIDTH+14) + 20,
Index: binary-improvements/webserver/js/leaflet.control.gametime.js
===================================================================
--- binary-improvements/webserver/js/leaflet.control.gametime.js	(revision 249)
+++ binary-improvements/webserver/js/leaflet.control.gametime.js	(revision 249)
@@ -0,0 +1,47 @@
+L.Control.GameTime = L.Control.extend({
+        options: {
+                position: 'bottomright'
+        },
+
+        onAdd: function (map) {
+                var name = 'control-gametime',
+                    container = L.DomUtil.create('div', name + ' webmap-control');
+
+                container.innerHTML = "Loading ..."
+                L.DomEvent.on (container, 'mousemove', L.DomEvent.stopPropagation);
+
+                this._map = map;
+                this._div = container;
+
+                window.setTimeout($.proxy(this._updateGameTimeEvent, this), 0);
+
+                return container;
+        },
+
+        onRemove: function (map) {
+        },
+
+        _updateGameTimeEvent: function() {
+                var div = this._div;
+                $.getJSON( "../api/getstats")
+                .done(function(data) {
+                        var time = "Day " + data.gametime.days + ", ";
+                        if (data.gametime.hours < 10)
+                                time += "0";
+                        time += data.gametime.hours;
+                        time += ":";
+                        if (data.gametime.minutes < 10)
+                                time += "0";
+                        time += data.gametime.minutes;
+                        div.innerHTML = time;
+                })
+                .fail(function(jqxhr, textStatus, error) {
+                        console.log("Error fetching game stats");
+                })
+                .always(function() {
+                });
+                window.setTimeout($.proxy(this._updateGameTimeEvent, this), 2000);
+        }
+
+});
+
Index: binary-improvements/webserver/js/leaflet.control.login.js
===================================================================
--- binary-improvements/webserver/js/leaflet.control.login.js	(revision 249)
+++ binary-improvements/webserver/js/leaflet.control.login.js	(revision 249)
@@ -0,0 +1,35 @@
+L.Control.Login = L.Control.extend({
+	options: {
+		position: 'bottomleft'
+	},
+
+	onAdd: function (map) {
+		var name = 'control-login',
+		    container = L.DomUtil.create('div', name + ' leaflet-bar');
+	
+		this._map = map;
+		this._div = container;
+		
+		if (userdata.loggedin == true) {
+			container.innerHTML =
+				"Logged in as: " + userdata.username + "<br/>\
+				<a href=\"/session/logout\">Sign&nbsp;out</a>";
+		} else {
+			container.innerHTML =
+				"Not logged in<br/>\
+				<a href=\"/session/login\">\
+				<img src=\"img/steamlogin.png\" title=\"Sign in through Steam\"></a>";
+		}
+
+		
+		return container;
+	},
+
+	onRemove: function (map) {
+	},
+
+	_onMouseMove: function (e) {
+		this._div.innerHTML = FormatCoord(e.latlng);
+	}
+});
+
Index: binary-improvements/webserver/js/leaflet.control.reloadtiles.js
===================================================================
--- binary-improvements/webserver/js/leaflet.control.reloadtiles.js	(revision 245)
+++ binary-improvements/webserver/js/leaflet.control.reloadtiles.js	(revision 249)
@@ -2,4 +2,8 @@
 	options: {
 		position: 'bottomleft',
+		autoreload_enable: true,
+		autoreload_minInterval: 30,
+		autoreload_interval: 120,
+		autoreload_defaultOn: false,
 		layers: []
 	},
@@ -9,12 +13,58 @@
 		    container = L.DomUtil.create('div', name + ' webmap-control');
 
-		L.DomEvent.on (container, 'mousemove', L.DomEvent.stopPropagation);
+		var stop = L.DomEvent.stopPropagation;
+		L.DomEvent
+		    .on (container, 'mousemove', stop)
+		    .on (container, 'click', stop)
+		    .on (container, 'mousedown', stop)
+		    .on (container, 'dblclick', stop);
 
 		this._map = map;
+		
+		this._reloadbutton = $("<a>")
+			.addClass (name+"-btn")
+			.text ("Reload tiles now")
+			.attr ("href", "#")
+			.attr ("title", "Reload tiles now")
+			.on ("click.action", null, this, this._reload);
+		$(container).append (this._reloadbutton);
 
-		this._reloadbutton = this._createButton(
-			"Reload tiles", "Reload tiles",
-			name + "-btn", container, this._reload, this);
+		if (this.options.autoreload_enable) {
+			$(container).append ("<br>");
+		
+			this._autocheck = $("<input>")
+				.addClass (name + "-chk")
+				.attr ("type", "checkbox")
+				.attr ("name", "map_reloadtiles_autoreload")
+				.attr ("id", "map_reloadtiles_autoreload")
+				.attr ("value", "1")
+				.on ("change", null, this, this._selectreload);
+			if (this.options.autoreload_defaultOn) {
+				this._autocheck.attr ("checked", "checked");
+				this._timeout = window.setTimeout ($.proxy (this._reloadTilesEvent, this), this.options.autoreload_interval*1000);
+			}
+			$(container).append (this._autocheck);
+		
+			var label1 = $("<label>")
+				.attr ("for", "map_reloadtiles_autoreload");
+			label1.append ("Reload every ");
+			$(container).append (label1);
+		
+			this._reloadinterval = $("<input>")
+				.addClass (name + "-txt")
+				.attr ("name", "map_reloadtiles_autoreload_time")
+				.attr ("type", "text")
+				.attr ("size", "4")
+				.attr ("maxlength", "5")
+				.attr ("value", this.options.autoreload_interval)
+				.on ("input", null, this, this._verifyinterval);
+			$(container).append (this._reloadinterval);
 
+			var label2 = $("<label>")
+				.attr ("for", "map_reloadtiles_autoreload");
+			label2.append (" seconds");
+			$(container).append (label2);
+		}
+		
 		return container;
 	},
@@ -22,32 +72,45 @@
 	onRemove: function (map) {
 	},
+	
+	_selectreload: function (e) {
+		if (e.data._autocheck.prop ("checked")) {
+			e.data._timeout = window.setTimeout ($.proxy (e.data._reloadTilesEvent, e.data), e.data.options.autoreload_interval*1000);
+		} else {
+			window.clearTimeout (e.data._timeout);
+		}
+	},
+	
+	_verifyinterval: function (e) {
+		var val = e.data._reloadinterval.val ();
+		if (/^[\d]+$/.test (val)) {
+			if (val >= e.data.options.autoreload_minInterval) {
+				e.data._reloadinterval.removeClass ("invalidinput");
+				e.data.options.autoreload_interval = val;
+				if (e.data._autocheck.prop ("checked")) {
+					window.clearTimeout (e.data._timeout);
+					e.data._timeout = window.setTimeout ($.proxy (e.data._reloadTilesEvent, e.data), e.data.options.autoreload_interval*1000);
+				}
+			} else {
+				e.data._reloadinterval.addClass ("invalidinput");
+			}
+		} else {
+			e.data._reloadinterval.addClass ("invalidinput");
+		}
+	},
 
 	_reload: function (e) {
 		var newTileTime = new Date().getTime();
 		
-		for (var i = 0; i < this.options.layers.length; i++) {
-			this.options.layers [i].options.time = newTileTime;
-			this.options.layers [i].redraw ();
+		for (var i = 0; i < e.data.options.layers.length; i++) {
+			e.data.options.layers [i].options.time = newTileTime;
+			e.data.options.layers [i].redraw ();
 		}
 	},
 
-	_createButton: function (html, title, className, container, fn, context) {
-		var link = L.DomUtil.create('a', className, container);
-		link.innerHTML = html;
-		link.href = '#';
-		link.title = title;
-
-		var stop = L.DomEvent.stopPropagation;
-
-		L.DomEvent
-		    .on(link, 'click', stop)
-		    .on(link, 'mousedown', stop)
-		    .on(link, 'dblclick', stop)
-		    .on(link, 'click', L.DomEvent.preventDefault)
-		    .on(link, 'click', fn, context)
-		    .on(link, 'click', this._refocusOnMap, context);
-		   
-		return link;
-	}
+	_reloadTilesEvent: function() {
+		var div = this._div;
+		this._reload ({data: this});
+		this._timeout = window.setTimeout ($.proxy (this._reloadTilesEvent, this), this.options.autoreload_interval*1000);
+	},
 
 });
Index: binary-improvements/webserver/js/leaflet.layer.sdtdtiles.js
===================================================================
--- binary-improvements/webserver/js/leaflet.layer.sdtdtiles.js	(revision 249)
+++ binary-improvements/webserver/js/leaflet.layer.sdtdtiles.js	(revision 249)
@@ -0,0 +1,22 @@
+function GetSdtdTileLayer (mapinfo, initTime, isMiniMap) {
+	if (typeof isMiniMap == 'undefined') isMiniMap = false;
+	
+	var tileLayer = L.tileLayer('../map/{z}/{x}/{y}.png?t={time}', {
+		maxZoom: isMiniMap ? mapinfo.maxzoom : mapinfo.maxzoom + 1,
+		minZoom: isMiniMap ? 0 : Math.max(0, mapinfo.maxzoom - 5),
+		maxNativeZoom: mapinfo.maxzoom,
+		tileSize: mapinfo.tilesize,
+		continuousWorld: true,
+		tms: true,
+		unloadInvisibleTiles: false,
+		time: initTime
+	});
+	
+	// TileLayer w/ TMS=true fix for zoomlevel >= 8
+	tileLayer._getWrapTileNum = function () {
+		return L.point(0, 0);
+	};
+	
+	return tileLayer;
+}
+
Index: binary-improvements/webserver/js/map.js
===================================================================
--- binary-improvements/webserver/js/map.js	(revision 245)
+++ binary-improvements/webserver/js/map.js	(revision 249)
@@ -33,11 +33,6 @@
 	});
 
-
-
-
 	// ===============================================================================================
 	// Map and basic tile layers
-
-	var initTime = new Date().getTime();
 
 	map = L.map('tab_map', {
@@ -48,33 +43,8 @@
 	}).setView([0, 0], Math.max(0, mapinfo.maxzoom - 5));
 
-	var tileLayer = L.tileLayer('../map/{z}/{x}/{y}.png?t={time}', {
-		maxZoom: mapinfo.maxzoom + 1,
-		minZoom: Math.max(0, mapinfo.maxzoom - 5),
-		maxNativeZoom: mapinfo.maxzoom,
-		tileSize: mapinfo.tilesize,
-		continuousWorld: true,
-		tms: true,
-		unloadInvisibleTiles: false,
-		time: initTime
-	});
-	
-	// TileLayer w/ TMS=true fix for zoomlevel >= 8
-	tileLayer._getWrapTileNum = function () {
-		return L.point(0, 0);
-	};
-
-	var tileLayerMiniMap = L.tileLayer('../map/{z}/{x}/{y}.png?t={time}', {
-		maxZoom: mapinfo.maxzoom,
-		minZoom: 0,
-		maxNativeZoom: mapinfo.maxzoom,
-		tileSize: mapinfo.tilesize,
-		continuousWorld: true,
-		tms: true,
-		unloadInvisibleTiles: false,
-		time: initTime
-	});
-
-
-
+
+	var initTime = new Date().getTime();
+	var tileLayer = GetSdtdTileLayer (mapinfo, initTime);
+	var tileLayerMiniMap = GetSdtdTileLayer (mapinfo, initTime, true);
 
 
@@ -92,12 +62,10 @@
 
 
-
-	var baseLayers = {
-		//"Map": tileLayer
-	};
-
-	var layerControl = L.control.layers(baseLayers, null, {
-		collapsed: false
-	});
+	var layerControl = L.control.layers({
+			//"Map": tileLayer
+		}, null, {
+			collapsed: false
+		}
+	);
 	
 	var layerCount = 0;
@@ -105,7 +73,17 @@
 
 	tileLayer.addTo(map);
+
 	new L.Control.Coordinates({}).addTo(map);
-	new L.Control.ReloadTiles({layers: [tileLayer, tileLayerMiniMap]}).addTo(map);
+	
+	new L.Control.ReloadTiles({
+		autoreload_enable: true,
+		autoreload_minInterval: 30,
+		autoreload_interval: 120,
+		autoreload_defaultOn: false,
+		layers: [tileLayer, tileLayerMiniMap]
+	}).addTo(map);
+	
 	layerControl.addOverlay (GetRegionLayer (mapinfo), "Region files");
+	
 	var miniMap = new L.Control.MiniMap(tileLayerMiniMap, {
 		zoomLevelOffset: -6,
@@ -113,8 +91,20 @@
 	}).addTo(map);
 
+	var measure = L.control.measure({
+		//primaryLengthUnit: "meters",
+		//primaryAreaUnit: "sqmeters",
+		//activeColor: "#ABE67E",
+		//completedColor: "#C8F2BE",
+		position: "bottomleft"
+	});
+	//measure.addTo(map);
+
+	//new L.Control.GameTime({}).addTo(map);
+	
 	if (HasPermission ("webapi.getlandclaims")) {
 		layerControl.addOverlay (GetLandClaimsLayer (map, mapinfo), "Land claims");
 		layerCount++;
 	}
+	
 	if (HasPermission ("webapi.getplayerslocation")) {
 		layerControl.addOverlay (playersOfflineMarkerGroup, "Players (offline) (<span id='mapControlOfflineCount'>0</span>)");
@@ -148,5 +138,4 @@
 			if (playersMappingList.hasOwnProperty(val.steamid)) {
 				marker = playersMappingList[val.steamid].currentPosMarker;
-				marker.setLatLng([val.position.x, val.position.z]);
 			} else {
 				marker = L.marker([val.position.x, val.position.z]).bindPopup(
@@ -158,15 +147,18 @@
 				playersMappingList[val.steamid] = { online: !val.online };
 			}
-			if (playersMappingList[val.steamid].online != val.online) {
-				if (val.online) {
+			if (playersMappingList[val.steamid].online) {
+				playersOnlineMarkerGroup.removeLayer(marker);
+			} else {
+				playersOfflineMarkerGroup.removeLayer(marker);
+			}
+			marker.setLatLng([val.position.x, val.position.z]);
+			if (val.online) {
 					marker.setOpacity(1.0);
-					playersOfflineMarkerGroup.removeLayer(marker);
 					playersOnlineMarkerGroup.addLayer(marker);
-				} else {
+			} else {
 					marker.setOpacity(0.5);
-					playersOnlineMarkerGroup.removeLayer(marker);
 					playersOfflineMarkerGroup.addLayer(marker);
-				}
 			}
+
 			val.currentPosMarker = marker;
 			playersMappingList[val.steamid] = val;
Index: binary-improvements/webserver/js/permissions.js
===================================================================
--- binary-improvements/webserver/js/permissions.js	(revision 245)
+++ binary-improvements/webserver/js/permissions.js	(revision 249)
@@ -36,5 +36,7 @@
 	})
 	.always(function () {
-		$("#nopermissionwarning").attr ("style", "display: block");
+		if (PermissionCount () == 0) {
+			$("#nopermissionwarning").attr ("style", "display: block");
+		}
 	})
 }
@@ -49,2 +51,10 @@
 }
 
+function PermissionCount () {
+	var cnt = 0;
+	for (var i = 0; i < userdata.permissions.length; i++) {
+		if (userdata.permissions [i].allowed) cnt++;
+	}
+	return cnt;
+}
+
Index: binary-improvements/webserver/js/tabs.js
===================================================================
--- binary-improvements/webserver/js/tabs.js	(revision 245)
+++ binary-improvements/webserver/js/tabs.js	(revision 249)
@@ -1,2 +1,15 @@
+var tabElements = {};
+var currentTabClass = "current_tab";
+
+function OpenTab () {
+	var menuElement = $(this);
+	var linkElement = menuElement.children ("a");
+	var linkName = linkElement.attr ("href");
+
+	$("*").removeClass (currentTabClass);
+	menuElement.addClass (currentTabClass);
+	$(linkName).addClass (currentTabClass);
+}
+
 function InitializeTabs () {
 	$("#adminmenu > ul > li").addClass ("menu_button");
