Index: binary-improvements/MapRendering/Web/API/ExecuteConsoleCommand.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/ExecuteConsoleCommand.cs	(revision 448)
+++ 	(revision )
@@ -1,50 +1,0 @@
-using System;
-using System.Net;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class ExecuteConsoleCommand : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			if (string.IsNullOrEmpty (_req.QueryString ["command"])) {
-				_resp.StatusCode = (int) HttpStatusCode.BadRequest;
-				Web.SetResponseTextContent (_resp, "No command given");
-				return;
-			}
-
-			WebCommandResult.ResultType responseType =
-				_req.QueryString ["raw"] != null
-					? WebCommandResult.ResultType.Raw
-					: (_req.QueryString ["simple"] != null
-						? WebCommandResult.ResultType.ResultOnly
-						: WebCommandResult.ResultType.Full);
-
-			string commandline = _req.QueryString ["command"];
-			string commandPart = commandline.Split (' ') [0];
-			string argumentsPart = commandline.Substring (Math.Min (commandline.Length, commandPart.Length + 1));
-
-			IConsoleCommand command = SdtdConsole.Instance.GetCommand (commandline);
-
-			if (command == null) {
-				_resp.StatusCode = (int) HttpStatusCode.NotFound;
-				Web.SetResponseTextContent (_resp, "Unknown command");
-				return;
-			}
-
-			int commandPermissionLevel = GameManager.Instance.adminTools.Commands.GetCommandPermissionLevel (command.GetCommands ());
-
-			if (_permissionLevel > commandPermissionLevel) {
-				_resp.StatusCode = (int) HttpStatusCode.Forbidden;
-				Web.SetResponseTextContent (_resp, "You are not allowed to execute this command");
-				return;
-			}
-
-			_resp.SendChunked = true;
-			WebCommandResult wcr = new WebCommandResult (commandPart, argumentsPart, responseType, _resp);
-			SdtdConsole.Instance.ExecuteAsync (commandline, wcr);
-		}
-
-		public override int DefaultPermissionLevel () {
-			return 2000;
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetAllowedCommands.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetAllowedCommands.cs	(revision 448)
+++ 	(revision )
@@ -1,37 +1,0 @@
-using System.Net;
-using AllocsFixes.JSON;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetAllowedCommands : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			JSONObject result = new JSONObject ();
-			JSONArray entries = new JSONArray ();
-			foreach (IConsoleCommand cc in SdtdConsole.Instance.GetCommands ()) {
-				int commandPermissionLevel = GameManager.Instance.adminTools.Commands.GetCommandPermissionLevel (cc.GetCommands ());
-				if (_permissionLevel <= commandPermissionLevel) {
-					string cmd = string.Empty;
-					foreach (string s in cc.GetCommands ()) {
-						if (s.Length > cmd.Length) {
-							cmd = s;
-						}
-					}
-
-					JSONObject cmdObj = new JSONObject ();
-					cmdObj.Add ("command", new JSONString (cmd));
-					cmdObj.Add ("description", new JSONString (cc.GetDescription ()));
-					cmdObj.Add ("help", new JSONString (cc.GetHelp ()));
-					entries.Add (cmdObj);
-				}
-			}
-
-			result.Add ("commands", entries);
-
-			WriteJSON (_resp, result);
-		}
-
-		public override int DefaultPermissionLevel () {
-			return 2000;
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetAnimalsLocation.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetAnimalsLocation.cs	(revision 448)
+++ 	(revision )
@@ -1,41 +1,0 @@
-﻿using System.Collections.Generic;
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.LiveData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	internal class GetAnimalsLocation : WebAPI {
-		private readonly List<EntityAnimal> animals = new List<EntityAnimal> ();
-
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			JSONArray animalsJsResult = new JSONArray ();
-
-			Animals.Instance.Get (animals);
-			for (int i = 0; i < animals.Count; i++) {
-				EntityAnimal entity = animals [i];
-				Vector3i position = new Vector3i (entity.GetPosition ());
-
-				JSONObject jsonPOS = new JSONObject ();
-				jsonPOS.Add ("x", new JSONNumber (position.x));
-				jsonPOS.Add ("y", new JSONNumber (position.y));
-				jsonPOS.Add ("z", new JSONNumber (position.z));
-
-				JSONObject pJson = new JSONObject ();
-				pJson.Add ("id", new JSONNumber (entity.entityId));
-
-				if (!string.IsNullOrEmpty (entity.EntityName)) {
-					pJson.Add ("name", new JSONString (entity.EntityName));
-				} else {
-					pJson.Add ("name", new JSONString ("animal class #" + entity.entityClass));
-				}
-
-				pJson.Add ("position", jsonPOS);
-
-				animalsJsResult.Add (pJson);
-			}
-
-			WriteJSON (_resp, animalsJsResult);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetHostileLocation.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetHostileLocation.cs	(revision 448)
+++ 	(revision )
@@ -1,41 +1,0 @@
-﻿using System.Collections.Generic;
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.LiveData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	internal class GetHostileLocation : WebAPI {
-		private readonly List<EntityEnemy> enemies = new List<EntityEnemy> ();
-
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			JSONArray hostilesJsResult = new JSONArray ();
-
-			Hostiles.Instance.Get (enemies);
-			for (int i = 0; i < enemies.Count; i++) {
-				EntityEnemy entity = enemies [i];
-				Vector3i position = new Vector3i (entity.GetPosition ());
-
-				JSONObject jsonPOS = new JSONObject ();
-				jsonPOS.Add ("x", new JSONNumber (position.x));
-				jsonPOS.Add ("y", new JSONNumber (position.y));
-				jsonPOS.Add ("z", new JSONNumber (position.z));
-
-				JSONObject pJson = new JSONObject ();
-				pJson.Add ("id", new JSONNumber (entity.entityId));
-
-				if (!string.IsNullOrEmpty (entity.EntityName)) {
-					pJson.Add ("name", new JSONString (entity.EntityName));
-				} else {
-					pJson.Add ("name", new JSONString ("enemy class #" + entity.entityClass));
-				}
-
-				pJson.Add ("position", jsonPOS);
-
-				hostilesJsResult.Add (pJson);
-			}
-
-			WriteJSON (_resp, hostilesJsResult);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetLandClaims.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetLandClaims.cs	(revision 448)
+++ 	(revision )
@@ -1,78 +1,0 @@
-using System.Collections.Generic;
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.PersistentData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetLandClaims : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			PlatformUserIdentifierAbs requestedUserId = null;
-			if (_req.QueryString ["userid"] != null) {
-				if (!PlatformUserIdentifierAbs.TryFromCombinedString (_req.QueryString ["userid"], out requestedUserId)) {
-					_resp.StatusCode = (int) HttpStatusCode.BadRequest;
-					Web.SetResponseTextContent (_resp, "Invalid user id given");
-					return;
-				}
-			}
-
-			// default user, cheap way to avoid 'null reference exception'
-			PlatformUserIdentifierAbs userId = _user?.UserId;
-
-			bool bViewAll = WebConnection.CanViewAllClaims (_permissionLevel);
-
-			JSONObject result = new JSONObject ();
-			result.Add ("claimsize", new JSONNumber (GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> (nameof(EnumGamePrefs.LandClaimSize)))));
-
-			JSONArray claimOwners = new JSONArray ();
-			result.Add ("claimowners", claimOwners);
-
-			LandClaimList.OwnerFilter[] ownerFilters = null;
-			if (requestedUserId != null || !bViewAll) {
-				if (requestedUserId != null && !bViewAll) {
-					ownerFilters = new[] {
-						LandClaimList.UserIdFilter (userId),
-						LandClaimList.UserIdFilter (requestedUserId)
-					};
-				} else if (!bViewAll) {
-					ownerFilters = new[] {LandClaimList.UserIdFilter (userId)};
-				} else {
-					ownerFilters = new[] {LandClaimList.UserIdFilter (requestedUserId)};
-				}
-			}
-
-			LandClaimList.PositionFilter[] posFilters = null;
-
-			Dictionary<Player, List<Vector3i>> claims = LandClaimList.GetLandClaims (ownerFilters, posFilters);
-
-			foreach (KeyValuePair<Player, List<Vector3i>> kvp in claims) {
-				JSONObject owner = new JSONObject ();
-				claimOwners.Add (owner);
-
-				owner.Add ("steamid", new JSONString (kvp.Key.PlatformId?.CombinedString ?? ""));
-				owner.Add ("crossplatformid", new JSONString (kvp.Key.CrossPlatformId?.CombinedString ?? ""));
-				owner.Add ("claimactive", new JSONBoolean (kvp.Key.LandProtectionActive));
-
-				if (kvp.Key.Name.Length > 0) {
-					owner.Add ("playername", new JSONString (kvp.Key.Name));
-				} else {
-					owner.Add ("playername", new JSONNull ());
-				}
-
-				JSONArray claimsJson = new JSONArray ();
-				owner.Add ("claims", claimsJson);
-
-				foreach (Vector3i v in kvp.Value) {
-					JSONObject claim = new JSONObject ();
-					claim.Add ("x", new JSONNumber (v.x));
-					claim.Add ("y", new JSONNumber (v.y));
-					claim.Add ("z", new JSONNumber (v.z));
-
-					claimsJson.Add (claim);
-				}
-			}
-
-			WriteJSON (_resp, result);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetLog.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetLog.cs	(revision 448)
+++ 	(revision )
@@ -1,60 +1,0 @@
-using System.Collections.Generic;
-using System.Net;
-using AllocsFixes.JSON;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetLog : WebAPI {
-		private const int MAX_COUNT = 1000;
-		
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			int count, firstLine, lastLine;
-
-			if (_req.QueryString ["count"] == null || !int.TryParse (_req.QueryString ["count"], out count)) {
-				count = 50;
-			}
-
-			if (count == 0) {
-				count = 1;
-			}
-
-			if (count > MAX_COUNT) {
-				count = MAX_COUNT;
-			}
-
-			if (count < -MAX_COUNT) {
-				count = -MAX_COUNT;
-			}
-
-			if (_req.QueryString ["firstLine"] == null || !int.TryParse (_req.QueryString ["firstLine"], out firstLine)) {
-				if (count > 0) {
-					firstLine = LogBuffer.Instance.OldestLine;
-				} else {
-					firstLine = LogBuffer.Instance.LatestLine;
-				}
-			}
-
-			JSONObject result = new JSONObject ();
-
-			List<LogBuffer.LogEntry> logEntries = LogBuffer.Instance.GetRange (ref firstLine, count, out lastLine);
-
-			JSONArray entries = new JSONArray ();
-			foreach (LogBuffer.LogEntry logEntry in logEntries) {
-				JSONObject entry = new JSONObject ();
-				entry.Add ("date", new JSONString (logEntry.date));
-				entry.Add ("time", new JSONString (logEntry.time));
-				entry.Add ("uptime", new JSONString (logEntry.uptime));
-				entry.Add ("msg", new JSONString (logEntry.message));
-				entry.Add ("trace", new JSONString (logEntry.trace));
-				entry.Add ("type", new JSONString (logEntry.type.ToStringCached ()));
-				entries.Add (entry);
-			}
-
-			result.Add ("firstLine", new JSONNumber (firstLine));
-			result.Add ("lastLine", new JSONNumber (lastLine));
-			result.Add ("entries", entries);
-
-			WriteJSON (_resp, result);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetPlayerInventories.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayerInventories.cs	(revision 448)
+++ 	(revision )
@@ -1,29 +1,0 @@
-using System.Collections.Generic;
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.PersistentData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetPlayerInventories : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			GetPlayerInventory.GetInventoryArguments (_req, out bool showIconColor, out bool showIconName);
-
-			JSONArray AllInventoriesResult = new JSONArray ();
-
-			foreach (KeyValuePair<PlatformUserIdentifierAbs, Player> kvp in PersistentContainer.Instance.Players.Dict) {
-				Player p = kvp.Value;
-
-				if (p == null) {
-					continue;
-				}
-
-				if (p.IsOnline) {
-					AllInventoriesResult.Add (GetPlayerInventory.DoPlayer (p, showIconColor, showIconName));
-				}
-			}
-
-			WriteJSON (_resp, AllInventoriesResult);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetPlayerInventory.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayerInventory.cs	(revision 448)
+++ 	(revision )
@@ -1,129 +1,0 @@
-using System.Collections.Generic;
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.PersistentData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetPlayerInventory : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			if (_req.QueryString ["userid"] == null) {
-				_resp.StatusCode = (int) HttpStatusCode.BadRequest;
-				Web.SetResponseTextContent (_resp, "No user id given");
-				return;
-			}
-
-			string userIdString = _req.QueryString ["userid"];
-			if (!PlatformUserIdentifierAbs.TryFromCombinedString (userIdString, out PlatformUserIdentifierAbs userId)) {
-				_resp.StatusCode = (int) HttpStatusCode.BadRequest;
-				Web.SetResponseTextContent (_resp, "Invalid user id given");
-				return;
-			}
-
-			Player p = PersistentContainer.Instance.Players.GetByUserId (userId);
-			if (p == null) {
-				_resp.StatusCode = (int) HttpStatusCode.NotFound;
-				Web.SetResponseTextContent (_resp, "Unknown user id given");
-				return;
-			}
-
-			GetInventoryArguments (_req, out bool showIconColor, out bool showIconName);
-
-			JSONObject result = DoPlayer (p, showIconColor, showIconName);
-
-			WriteJSON (_resp, result);
-		}
-
-		internal static void GetInventoryArguments (HttpListenerRequest _req, out bool _showIconColor, out bool _showIconName) {
-			if (_req.QueryString ["showiconcolor"] == null || !bool.TryParse (_req.QueryString ["showiconcolor"], out _showIconColor)) {
-				_showIconColor = true;
-			}
-			
-			if (_req.QueryString ["showiconname"] == null || !bool.TryParse (_req.QueryString ["showiconname"], out _showIconName)) {
-				_showIconName = true;
-			}
-		}
-
-		internal static JSONObject DoPlayer (Player _player, bool _showIconColor, bool _showIconName) {
-			PersistentData.Inventory inv = _player.Inventory;
-
-			JSONObject result = new JSONObject ();
-
-			JSONArray bag = new JSONArray ();
-			JSONArray belt = new JSONArray ();
-			JSONObject equipment = new JSONObject ();
-			result.Add ("userid", new JSONString (_player.PlatformId.CombinedString));
-			result.Add ("crossplatformid", new JSONString (_player.CrossPlatformId?.CombinedString ?? ""));
-			result.Add ("entityid", new JSONNumber (_player.EntityID));
-			result.Add ("playername", new JSONString (_player.Name));
-			result.Add ("bag", bag);
-			result.Add ("belt", belt);
-			result.Add ("equipment", equipment);
-
-			DoInventory (belt, inv.belt, _showIconColor, _showIconName);
-			DoInventory (bag, inv.bag, _showIconColor, _showIconName);
-
-			AddEquipment (equipment, "head", inv.equipment, EquipmentSlots.Headgear, _showIconColor, _showIconName);
-			AddEquipment (equipment, "eyes", inv.equipment, EquipmentSlots.Eyewear, _showIconColor, _showIconName);
-			AddEquipment (equipment, "face", inv.equipment, EquipmentSlots.Face, _showIconColor, _showIconName);
-
-			AddEquipment (equipment, "armor", inv.equipment, EquipmentSlots.ChestArmor, _showIconColor, _showIconName);
-			AddEquipment (equipment, "jacket", inv.equipment, EquipmentSlots.Jacket, _showIconColor, _showIconName);
-			AddEquipment (equipment, "shirt", inv.equipment, EquipmentSlots.Shirt, _showIconColor, _showIconName);
-
-			AddEquipment (equipment, "legarmor", inv.equipment, EquipmentSlots.LegArmor, _showIconColor, _showIconName);
-			AddEquipment (equipment, "pants", inv.equipment, EquipmentSlots.Legs, _showIconColor, _showIconName);
-			AddEquipment (equipment, "boots", inv.equipment, EquipmentSlots.Feet, _showIconColor, _showIconName);
-
-			AddEquipment (equipment, "gloves", inv.equipment, EquipmentSlots.Hands, _showIconColor, _showIconName);
-
-			return result;
-		}
-
-		private static void DoInventory (JSONArray _jsonRes, List<InvItem> _inv, bool _showIconColor, bool _showIconName) {
-			for (int i = 0; i < _inv.Count; i++) {
-				_jsonRes.Add (GetJsonForItem (_inv [i], _showIconColor, _showIconName));
-			}
-		}
-
-		private static void AddEquipment (JSONObject _eq, string _slotname, InvItem[] _items, EquipmentSlots _slot, bool _showIconColor, bool _showIconName) {
-			int[] slotindices = XUiM_PlayerEquipment.GetSlotIndicesByEquipmentSlot (_slot);
-
-			for (int i = 0; i < slotindices.Length; i++) {
-				if (_items? [slotindices [i]] != null) {
-					InvItem item = _items [slotindices [i]];
-					_eq.Add (_slotname, GetJsonForItem (item, _showIconColor, _showIconName));
-					return;
-				}
-			}
-
-			_eq.Add (_slotname, new JSONNull ());
-		}
-
-		private static JSONNode GetJsonForItem (InvItem _item, bool _showIconColor, bool _showIconName) {
-			if (_item == null) {
-				return new JSONNull ();
-			}
-
-			JSONObject jsonItem = new JSONObject ();
-			jsonItem.Add ("count", new JSONNumber (_item.count));
-			jsonItem.Add ("name", new JSONString (_item.itemName));
-			
-			if (_showIconName) {
-				jsonItem.Add ("icon", new JSONString (_item.icon));
-			}
-
-			if (_showIconColor) {
-				jsonItem.Add ("iconcolor", new JSONString (_item.iconcolor));
-			}
-
-			jsonItem.Add ("quality", new JSONNumber (_item.quality));
-			if (_item.quality >= 0) {
-				jsonItem.Add ("qualitycolor", new JSONString (QualityInfo.GetQualityColorHex (_item.quality)));
-			}
-
-			return jsonItem;
-
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetPlayerList.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayerList.cs	(revision 448)
+++ 	(revision )
@@ -1,271 +1,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Text.RegularExpressions;
-using AllocsFixes.JSON;
-using AllocsFixes.PersistentData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetPlayerList : WebAPI {
-		private static readonly Regex numberFilterMatcher =
-			new Regex (@"^(>=|=>|>|<=|=<|<|==|=)?\s*([0-9]+(\.[0-9]*)?)$");
-
-#if ENABLE_PROFILER
-		private static readonly UnityEngine.Profiling.CustomSampler jsonSerializeSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Build");
-#endif
-
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			AdminTools admTools = GameManager.Instance.adminTools;
-			PlatformUserIdentifierAbs userId = _user?.UserId;
-
-			bool bViewAll = WebConnection.CanViewAllPlayers (_permissionLevel);
-
-			// TODO: Sort (and filter?) prior to converting to JSON ... hard as how to get the correct column's data? (i.e. column name matches JSON object field names, not source data)
-
-			int rowsPerPage = 25;
-			if (_req.QueryString ["rowsperpage"] != null) {
-				int.TryParse (_req.QueryString ["rowsperpage"], out rowsPerPage);
-			}
-
-			int page = 0;
-			if (_req.QueryString ["page"] != null) {
-				int.TryParse (_req.QueryString ["page"], out page);
-			}
-
-			int firstEntry = page * rowsPerPage;
-
-			Players playersList = PersistentContainer.Instance.Players;
-
-			
-			List<JSONObject> playerList = new List<JSONObject> ();
-
-#if ENABLE_PROFILER
-			jsonSerializeSampler.Begin ();
-#endif
-
-			foreach (KeyValuePair<PlatformUserIdentifierAbs, Player> kvp in playersList.Dict) {
-				Player p = kvp.Value;
-
-				if (bViewAll || p.InternalId.Equals (userId)) {
-					JSONObject pos = new JSONObject ();
-					pos.Add ("x", new JSONNumber (p.LastPosition.x));
-					pos.Add ("y", new JSONNumber (p.LastPosition.y));
-					pos.Add ("z", new JSONNumber (p.LastPosition.z));
-
-					JSONObject pJson = new JSONObject ();
-					pJson.Add ("steamid", new JSONString (kvp.Value.PlatformId.CombinedString));
-					pJson.Add ("crossplatformid", new JSONString (kvp.Value.CrossPlatformId?.CombinedString ?? ""));
-					pJson.Add ("entityid", new JSONNumber (p.EntityID));
-					pJson.Add ("ip", new JSONString (p.IP));
-					pJson.Add ("name", new JSONString (p.Name));
-					pJson.Add ("online", new JSONBoolean (p.IsOnline));
-					pJson.Add ("position", pos);
-
-					pJson.Add ("totalplaytime", new JSONNumber (p.TotalPlayTime));
-					pJson.Add ("lastonline",
-						new JSONString (p.LastOnline.ToUniversalTime ().ToString ("yyyy-MM-ddTHH:mm:ssZ")));
-					pJson.Add ("ping", new JSONNumber (p.IsOnline ? p.ClientInfo.ping : -1));
-
-					JSONBoolean banned = admTools != null ? new JSONBoolean (admTools.Blacklist.IsBanned (kvp.Key, out _, out _)) : new JSONBoolean (false);
-
-					pJson.Add ("banned", banned);
-
-					playerList.Add (pJson);
-				}
-			}
-
-#if ENABLE_PROFILER
-			jsonSerializeSampler.End ();
-#endif
-
-			IEnumerable<JSONObject> list = playerList;
-
-			foreach (string key in _req.QueryString.AllKeys) {
-				if (!string.IsNullOrEmpty (key) && key.StartsWith ("filter[")) {
-					string filterCol = key.Substring (key.IndexOf ('[') + 1);
-					filterCol = filterCol.Substring (0, filterCol.Length - 1);
-					string filterVal = _req.QueryString.Get (key).Trim ();
-
-					list = ExecuteFilter (list, filterCol, filterVal);
-				}
-			}
-
-			int totalAfterFilter = list.Count ();
-
-			foreach (string key in _req.QueryString.AllKeys) {
-				if (!string.IsNullOrEmpty (key) && key.StartsWith ("sort[")) {
-					string sortCol = key.Substring (key.IndexOf ('[') + 1);
-					sortCol = sortCol.Substring (0, sortCol.Length - 1);
-					string sortVal = _req.QueryString.Get (key);
-
-					list = ExecuteSort (list, sortCol, sortVal == "0");
-				}
-			}
-
-			list = list.Skip (firstEntry);
-			list = list.Take (rowsPerPage);
-
-
-			JSONArray playersJsResult = new JSONArray ();
-			foreach (JSONObject jsO in list) {
-				playersJsResult.Add (jsO);
-			}
-
-			JSONObject result = new JSONObject ();
-			result.Add ("total", new JSONNumber (totalAfterFilter));
-			result.Add ("totalUnfiltered", new JSONNumber (playerList.Count));
-			result.Add ("firstResult", new JSONNumber (firstEntry));
-			result.Add ("players", playersJsResult);
-
-			WriteJSON (_resp, result);
-		}
-
-		private IEnumerable<JSONObject> ExecuteFilter (IEnumerable<JSONObject> _list, string _filterCol,
-			string _filterVal) {
-			if (!_list.Any()) {
-				return _list;
-			}
-
-			if (_list.First ().ContainsKey (_filterCol)) {
-				Type colType = _list.First () [_filterCol].GetType ();
-				if (colType == typeof (JSONNumber)) {
-					return ExecuteNumberFilter (_list, _filterCol, _filterVal);
-				}
-
-				if (colType == typeof (JSONBoolean)) {
-					bool value = StringParsers.ParseBool (_filterVal);
-					return _list.Where (_line => ((JSONBoolean) _line [_filterCol]).GetBool () == value);
-				}
-
-				if (colType == typeof (JSONString)) {
-					// regex-match whole ^string$, replace * by .*, ? by .?, + by .+
-					_filterVal = _filterVal.Replace ("*", ".*").Replace ("?", ".?").Replace ("+", ".+");
-					_filterVal = "^" + _filterVal + "$";
-
-					//Log.Out ("GetPlayerList: Filter on String with Regex '" + _filterVal + "'");
-					Regex matcher = new Regex (_filterVal, RegexOptions.IgnoreCase);
-					return _list.Where (_line => matcher.IsMatch (((JSONString) _line [_filterCol]).GetString ()));
-				}
-			}
-
-			return _list;
-		}
-
-
-		private IEnumerable<JSONObject> ExecuteNumberFilter (IEnumerable<JSONObject> _list, string _filterCol,
-			string _filterVal) {
-			// allow value (exact match), =, ==, >=, >, <=, <
-			Match filterMatch = numberFilterMatcher.Match (_filterVal);
-			if (filterMatch.Success) {
-				double value = StringParsers.ParseDouble (filterMatch.Groups [2].Value);
-				NumberMatchType matchType;
-				double epsilon = value / 100000;
-				switch (filterMatch.Groups [1].Value) {
-					case "":
-					case "=":
-					case "==":
-						matchType = NumberMatchType.Equal;
-						break;
-					case ">":
-						matchType = NumberMatchType.Greater;
-						break;
-					case ">=":
-					case "=>":
-						matchType = NumberMatchType.GreaterEqual;
-						break;
-					case "<":
-						matchType = NumberMatchType.Lesser;
-						break;
-					case "<=":
-					case "=<":
-						matchType = NumberMatchType.LesserEqual;
-						break;
-					default:
-						matchType = NumberMatchType.Equal;
-						break;
-				}
-
-				return _list.Where (delegate (JSONObject _line) {
-					double objVal = ((JSONNumber) _line [_filterCol]).GetDouble ();
-					switch (matchType) {
-						case NumberMatchType.Greater:
-							return objVal > value;
-						case NumberMatchType.GreaterEqual:
-							return objVal >= value;
-						case NumberMatchType.Lesser:
-							return objVal < value;
-						case NumberMatchType.LesserEqual:
-							return objVal <= value;
-						case NumberMatchType.Equal:
-						default:
-							return NearlyEqual (objVal, value, epsilon);
-					}
-				});
-			}
-
-			Log.Out ("GetPlayerList: ignoring invalid filter for number-column '{0}': '{1}'", _filterCol, _filterVal);
-			return _list;
-		}
-
-
-		private IEnumerable<JSONObject> ExecuteSort (IEnumerable<JSONObject> _list, string _sortCol, bool _ascending) {
-			if (_list.Count () == 0) {
-				return _list;
-			}
-
-			if (_list.First ().ContainsKey (_sortCol)) {
-				Type colType = _list.First () [_sortCol].GetType ();
-				if (colType == typeof (JSONNumber)) {
-					if (_ascending) {
-						return _list.OrderBy (_line => ((JSONNumber) _line [_sortCol]).GetDouble ());
-					}
-
-					return _list.OrderByDescending (_line => ((JSONNumber) _line [_sortCol]).GetDouble ());
-				}
-
-				if (colType == typeof (JSONBoolean)) {
-					if (_ascending) {
-						return _list.OrderBy (_line => ((JSONBoolean) _line [_sortCol]).GetBool ());
-					}
-
-					return _list.OrderByDescending (_line => ((JSONBoolean) _line [_sortCol]).GetBool ());
-				}
-
-				if (_ascending) {
-					return _list.OrderBy (_line => _line [_sortCol].ToString ());
-				}
-
-				return _list.OrderByDescending (_line => _line [_sortCol].ToString ());
-			}
-
-			return _list;
-		}
-
-
-		private bool NearlyEqual (double _a, double _b, double _epsilon) {
-			double absA = Math.Abs (_a);
-			double absB = Math.Abs (_b);
-			double diff = Math.Abs (_a - _b);
-
-			if (_a == _b) {
-				return true;
-			}
-
-			if (_a == 0 || _b == 0 || diff < double.Epsilon) {
-				return diff < _epsilon;
-			}
-
-			return diff / (absA + absB) < _epsilon;
-		}
-
-		private enum NumberMatchType {
-			Equal,
-			Greater,
-			GreaterEqual,
-			Lesser,
-			LesserEqual
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetPlayersLocation.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayersLocation.cs	(revision 448)
+++ 	(revision )
@@ -1,62 +1,0 @@
-using System.Collections.Generic;
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.PersistentData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetPlayersLocation : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			AdminTools admTools = GameManager.Instance.adminTools;
-			PlatformUserIdentifierAbs userId = _user?.UserId;
-
-			bool listOffline = false;
-			if (_req.QueryString ["offline"] != null) {
-				bool.TryParse (_req.QueryString ["offline"], out listOffline);
-			}
-
-			bool bViewAll = WebConnection.CanViewAllPlayers (_permissionLevel);
-
-			JSONArray playersJsResult = new JSONArray ();
-
-			Players playersList = PersistentContainer.Instance.Players;
-
-			foreach (KeyValuePair<PlatformUserIdentifierAbs, Player> kvp in playersList.Dict) {
-				if (admTools != null) {
-					if (admTools.Blacklist.IsBanned (kvp.Key, out _, out _)) {
-						continue;
-					}
-				}
-
-				Player p = kvp.Value;
-
-				if (listOffline || p.IsOnline) {
-					if (bViewAll || p.InternalId.Equals (userId)) {
-						JSONObject pos = new JSONObject ();
-						pos.Add ("x", new JSONNumber (p.LastPosition.x));
-						pos.Add ("y", new JSONNumber (p.LastPosition.y));
-						pos.Add ("z", new JSONNumber (p.LastPosition.z));
-
-						JSONObject pJson = new JSONObject ();
-						pJson.Add ("steamid", new JSONString (kvp.Value.PlatformId.CombinedString));
-						pJson.Add ("crossplatformid", new JSONString (kvp.Value.CrossPlatformId?.CombinedString ?? ""));
-
-						//					pJson.Add("entityid", new JSONNumber (p.EntityID));
-						//                    pJson.Add("ip", new JSONString (p.IP));
-						pJson.Add ("name", new JSONString (p.Name));
-						pJson.Add ("online", new JSONBoolean (p.IsOnline));
-						pJson.Add ("position", pos);
-
-						//					pJson.Add ("totalplaytime", new JSONNumber (p.TotalPlayTime));
-						//					pJson.Add ("lastonline", new JSONString (p.LastOnline.ToString ("s")));
-						//					pJson.Add ("ping", new JSONNumber (p.IsOnline ? p.ClientInfo.ping : -1));
-
-						playersJsResult.Add (pJson);
-					}
-				}
-			}
-
-			WriteJSON (_resp, playersJsResult);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetPlayersOnline.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayersOnline.cs	(revision 448)
+++ 	(revision )
@@ -1,49 +1,0 @@
-using System.Collections.Generic;
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.PersistentData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetPlayersOnline : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			JSONArray players = new JSONArray ();
-
-			World w = GameManager.Instance.World;
-			foreach (KeyValuePair<int, EntityPlayer> current in w.Players.dict) {
-				ClientInfo ci = ConnectionManager.Instance.Clients.ForEntityId (current.Key);
-				Player player = PersistentContainer.Instance.Players.GetByInternalId (ci.InternalId);
-
-				JSONObject pos = new JSONObject ();
-				pos.Add ("x", new JSONNumber ((int) current.Value.GetPosition ().x));
-				pos.Add ("y", new JSONNumber ((int) current.Value.GetPosition ().y));
-				pos.Add ("z", new JSONNumber ((int) current.Value.GetPosition ().z));
-
-				JSONObject p = new JSONObject ();
-				p.Add ("steamid", new JSONString (ci.PlatformId.CombinedString));
-				p.Add ("crossplatformid", new JSONString (ci.CrossplatformId?.CombinedString ?? ""));
-				p.Add ("entityid", new JSONNumber (ci.entityId));
-				p.Add ("ip", new JSONString (ci.ip));
-				p.Add ("name", new JSONString (current.Value.EntityName));
-				p.Add ("online", new JSONBoolean (true));
-				p.Add ("position", pos);
-
-				p.Add ("level", new JSONNumber (player?.Level ?? -1));
-				p.Add ("health", new JSONNumber (current.Value.Health));
-				p.Add ("stamina", new JSONNumber (current.Value.Stamina));
-				p.Add ("zombiekills", new JSONNumber (current.Value.KilledZombies));
-				p.Add ("playerkills", new JSONNumber (current.Value.KilledPlayers));
-				p.Add ("playerdeaths", new JSONNumber (current.Value.Died));
-				p.Add ("score", new JSONNumber (current.Value.Score));
-
-				p.Add ("totalplaytime", new JSONNumber (player?.TotalPlayTime ?? -1));
-				p.Add ("lastonline", new JSONString (player != null ? player.LastOnline.ToString ("s") : string.Empty));
-				p.Add ("ping", new JSONNumber (ci.ping));
-
-				players.Add (p);
-			}
-
-			WriteJSON (_resp, players);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetServerInfo.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetServerInfo.cs	(revision 448)
+++ 	(revision )
@@ -1,47 +1,0 @@
-using System;
-using System.Net;
-using AllocsFixes.JSON;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetServerInfo : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			JSONObject serverInfo = new JSONObject ();
-
-			GameServerInfo gsi = ConnectionManager.Instance.LocalServerInfo;
-
-			foreach (string stringGamePref in Enum.GetNames (typeof (GameInfoString))) {
-				string value = gsi.GetValue ((GameInfoString) Enum.Parse (typeof (GameInfoString), stringGamePref));
-
-				JSONObject singleStat = new JSONObject ();
-				singleStat.Add ("type", new JSONString ("string"));
-				singleStat.Add ("value", new JSONString (value));
-
-				serverInfo.Add (stringGamePref, singleStat);
-			}
-
-			foreach (string intGamePref in Enum.GetNames (typeof (GameInfoInt))) {
-				int value = gsi.GetValue ((GameInfoInt) Enum.Parse (typeof (GameInfoInt), intGamePref));
-
-				JSONObject singleStat = new JSONObject ();
-				singleStat.Add ("type", new JSONString ("int"));
-				singleStat.Add ("value", new JSONNumber (value));
-
-				serverInfo.Add (intGamePref, singleStat);
-			}
-
-			foreach (string boolGamePref in Enum.GetNames (typeof (GameInfoBool))) {
-				bool value = gsi.GetValue ((GameInfoBool) Enum.Parse (typeof (GameInfoBool), boolGamePref));
-
-				JSONObject singleStat = new JSONObject ();
-				singleStat.Add ("type", new JSONString ("bool"));
-				singleStat.Add ("value", new JSONBoolean (value));
-
-				serverInfo.Add (boolGamePref, singleStat);
-			}
-
-
-			WriteJSON (_resp, serverInfo);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetStats.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetStats.cs	(revision 448)
+++ 	(revision )
@@ -1,28 +1,0 @@
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.LiveData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetStats : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			JSONObject result = new JSONObject ();
-
-			JSONObject time = new JSONObject ();
-			time.Add ("days", new JSONNumber (GameUtils.WorldTimeToDays (GameManager.Instance.World.worldTime)));
-			time.Add ("hours", new JSONNumber (GameUtils.WorldTimeToHours (GameManager.Instance.World.worldTime)));
-			time.Add ("minutes", new JSONNumber (GameUtils.WorldTimeToMinutes (GameManager.Instance.World.worldTime)));
-			result.Add ("gametime", time);
-
-			result.Add ("players", new JSONNumber (GameManager.Instance.World.Players.Count));
-			result.Add ("hostiles", new JSONNumber (Hostiles.Instance.GetCount ()));
-			result.Add ("animals", new JSONNumber (Animals.Instance.GetCount ()));
-
-			WriteJSON (_resp, result);
-		}
-
-		public override int DefaultPermissionLevel () {
-			return 2000;
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/GetWebUIUpdates.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetWebUIUpdates.cs	(revision 448)
+++ 	(revision )
@@ -1,36 +1,0 @@
-using System.Net;
-using AllocsFixes.JSON;
-using AllocsFixes.LiveData;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class GetWebUIUpdates : WebAPI {
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			int latestLine;
-			if (_req.QueryString ["latestLine"] == null ||
-			    !int.TryParse (_req.QueryString ["latestLine"], out latestLine)) {
-				latestLine = 0;
-			}
-
-			JSONObject result = new JSONObject ();
-
-			JSONObject time = new JSONObject ();
-			time.Add ("days", new JSONNumber (GameUtils.WorldTimeToDays (GameManager.Instance.World.worldTime)));
-			time.Add ("hours", new JSONNumber (GameUtils.WorldTimeToHours (GameManager.Instance.World.worldTime)));
-			time.Add ("minutes", new JSONNumber (GameUtils.WorldTimeToMinutes (GameManager.Instance.World.worldTime)));
-			result.Add ("gametime", time);
-
-			result.Add ("players", new JSONNumber (GameManager.Instance.World.Players.Count));
-			result.Add ("hostiles", new JSONNumber (Hostiles.Instance.GetCount ()));
-			result.Add ("animals", new JSONNumber (Animals.Instance.GetCount ()));
-
-			result.Add ("newlogs", new JSONNumber (LogBuffer.Instance.LatestLine - latestLine));
-
-			WriteJSON (_resp, result);
-		}
-
-		public override int DefaultPermissionLevel () {
-			return 2000;
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/Null.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/Null.cs	(revision 448)
+++ 	(revision )
@@ -1,17 +1,0 @@
-﻿using System.Net;
-using System.Text;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public class Null : WebAPI {
-		public Null (string _name) : base(_name) {
-		}
-		
-		public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel) {
-			_resp.ContentLength64 = 0;
-			_resp.ContentType = "text/plain";
-			_resp.ContentEncoding = Encoding.ASCII;
-			_resp.OutputStream.Write (new byte[] { }, 0, 0);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/API/WebAPI.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/WebAPI.cs	(revision 448)
+++ 	(revision )
@@ -1,53 +1,0 @@
-using System.Net;
-using System.Text;
-using AllocsFixes.JSON;
-
-namespace AllocsFixes.NetConnections.Servers.Web.API {
-	public abstract class WebAPI {
-		public readonly string Name;
-
-		protected WebAPI (string _name = null) {
-			Name = _name ?? GetType ().Name;
-		}
-
-#if ENABLE_PROFILER
-		private static readonly UnityEngine.Profiling.CustomSampler jsonSerializeSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Serialize");
-		private static readonly UnityEngine.Profiling.CustomSampler netWriteSampler = UnityEngine.Profiling.CustomSampler.Create ("JSON_Write");
-#endif
-
-		public static void WriteJSON (HttpListenerResponse _resp, JSONNode _root) {
-#if ENABLE_PROFILER
-			jsonSerializeSampler.Begin ();
-#endif
-			StringBuilder sb = new StringBuilder ();
-			_root.ToString (sb);
-#if ENABLE_PROFILER
-			jsonSerializeSampler.End ();
-			netWriteSampler.Begin ();
-#endif
-			byte[] buf = Encoding.UTF8.GetBytes (sb.ToString ());
-			_resp.ContentLength64 = buf.Length;
-			_resp.ContentType = "application/json";
-			_resp.ContentEncoding = Encoding.UTF8;
-			_resp.OutputStream.Write (buf, 0, buf.Length);
-#if ENABLE_PROFILER
-			netWriteSampler.End ();
-#endif
-		}
-
-		public static void WriteText (HttpListenerResponse _resp, string _text) {
-			byte[] buf = Encoding.UTF8.GetBytes (_text);
-			_resp.ContentLength64 = buf.Length;
-			_resp.ContentType = "text/plain";
-			_resp.ContentEncoding = Encoding.UTF8;
-			_resp.OutputStream.Write (buf, 0, buf.Length);
-		}
-
-		public abstract void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user,
-			int _permissionLevel);
-
-		public virtual int DefaultPermissionLevel () {
-			return 0;
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/ConnectionHandler.cs
===================================================================
--- binary-improvements/MapRendering/Web/ConnectionHandler.cs	(revision 448)
+++ 	(revision )
@@ -1,51 +1,0 @@
-using System;
-using System.Collections.Generic;
-using System.Net;
-using Platform.Steam;
-
-namespace AllocsFixes.NetConnections.Servers.Web {
-	public class ConnectionHandler {
-		private readonly Dictionary<string, WebConnection> connections = new Dictionary<string, WebConnection> ();
-
-		public WebConnection IsLoggedIn (string _sessionId, IPAddress _ip) {
-			if (!connections.ContainsKey (_sessionId)) {
-				return null;
-			}
-
-			WebConnection con = connections [_sessionId];
-
-//			if (con.Age.TotalMinutes > parent.sessionTimeoutMinutes) {
-//				connections.Remove (_sessionId);
-//				return null;
-//			}
-
-			if (!Equals (con.Endpoint, _ip)) {
-				// Fixed: Allow different clients from same NAT network
-//				connections.Remove (_sessionId);
-				return null;
-			}
-
-			con.UpdateUsage ();
-
-			return con;
-		}
-
-		public void LogOut (string _sessionId) {
-			connections.Remove (_sessionId);
-		}
-
-		public WebConnection LogIn (ulong _steamId, IPAddress _ip) {
-			string sessionId = Guid.NewGuid ().ToString ();
-			PlatformUserIdentifierAbs userId = new UserIdentifierSteam (_steamId);
-			WebConnection con = new WebConnection (sessionId, _ip, userId);
-			connections.Add (sessionId, con);
-			return con;
-		}
-
-		public void SendLine (string _line) {
-			foreach (KeyValuePair<string, WebConnection> kvp in connections) {
-				kvp.Value.SendLine (_line);
-			}
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/LogBuffer.cs
===================================================================
--- binary-improvements/MapRendering/Web/LogBuffer.cs	(revision 448)
+++ 	(revision )
@@ -1,150 +1,0 @@
-using System;
-using System.Collections.Generic;
-using UnityEngine;
-
-namespace AllocsFixes.NetConnections.Servers.Web {
-	public class LogBuffer {
-		private const int MAX_ENTRIES = 3000;
-		private static LogBuffer instance;
-
-		private readonly List<LogEntry> logEntries = new List<LogEntry> ();
-
-		private int listOffset;
-
-		public static void Init () {
-			if (instance == null) {
-				instance = new LogBuffer ();
-			}
-		}
-
-		private LogBuffer () {
-			Log.LogCallbacksExtended += LogCallback;
-		}
-
-		public static LogBuffer Instance {
-			get {
-				if (instance == null) {
-					instance = new LogBuffer ();
-				}
-
-				return instance;
-			}
-		}
-
-		public int OldestLine {
-			get {
-				lock (logEntries) {
-					return listOffset;
-				}
-			}
-		}
-
-		public int LatestLine {
-			get {
-				lock (logEntries) {
-					return listOffset + logEntries.Count - 1;
-				}
-			}
-		}
-
-		public int StoredLines {
-			get {
-				lock (logEntries) {
-					return logEntries.Count;
-				}
-			}
-		}
-
-		public LogEntry this [int _index] {
-			get {
-				lock (logEntries) {
-					if (_index >= listOffset && _index < listOffset + logEntries.Count) {
-						return logEntries [_index];
-					}
-				}
-
-				return null;
-			}
-		}
-
-		private void LogCallback (string _formattedMsg, string _plainMsg, string _trace, LogType _type, DateTime _timestamp, long _uptime) {
-			LogEntry le = new LogEntry ();
-
-			le.date = $"{_timestamp.Year:0000}-{_timestamp.Month:00}-{_timestamp.Day:00}";
-			le.time = $"{_timestamp.Hour:00}:{_timestamp.Minute:00}:{_timestamp.Second:00}";
-			le.uptime = _uptime.ToString ();
-			le.message = _plainMsg;
-			le.trace = _trace;
-			le.type = _type;
-
-			lock (logEntries) {
-				logEntries.Add (le);
-				if (logEntries.Count > MAX_ENTRIES) {
-					listOffset += logEntries.Count - MAX_ENTRIES;
-					logEntries.RemoveRange (0, logEntries.Count - MAX_ENTRIES);
-				}
-			}
-		}
-
-		private readonly List<LogEntry> emptyList = new List<LogEntry> ();
-
-		public List<LogEntry> GetRange (ref int _start, int _count, out int _end) {
-			lock (logEntries) {
-				int index;
-				
-				if (_count < 0) {
-					_count = -_count;
-					
-					if (_start >= listOffset + logEntries.Count) {
-						_start = listOffset + logEntries.Count - 1;
-					}
-
-					_end = _start;
-
-					if (_start < listOffset) {
-						return emptyList;
-					}
-					
-					_start -= _count - 1;
-
-					if (_start < listOffset) {
-						_start = listOffset;
-					}
-
-					index = _start - listOffset;
-					_end += 1;
-					_count = _end - _start;
-				} else {
-					if (_start < listOffset) {
-						_start = listOffset;
-					}
-
-					if (_start >= listOffset + logEntries.Count) {
-						_end = _start;
-						return emptyList;
-					}
-
-					index = _start - listOffset;
-
-					if (index + _count > logEntries.Count) {
-						_count = logEntries.Count - index;
-					}
-
-					_end = _start + _count;
-				}
-
-				return logEntries.GetRange (index, _count);
-			}
-		}
-
-
-		public class LogEntry {
-			public string date;
-			public string message;
-			public string time;
-			public string trace;
-			public LogType type;
-			public string uptime;
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/MimeType.cs
===================================================================
--- binary-improvements/MapRendering/Web/MimeType.cs	(revision 448)
+++ 	(revision )
@@ -1,584 +1,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace AllocsFixes.NetConnections.Servers.Web {
-	public class MimeType {
-		private static readonly IDictionary<string, string> _mappings =
-			new CaseInsensitiveStringDictionary<string> {
-				{".323", "text/h323"},
-				{".3g2", "video/3gpp2"},
-				{".3gp", "video/3gpp"},
-				{".3gp2", "video/3gpp2"},
-				{".3gpp", "video/3gpp"},
-				{".7z", "application/x-7z-compressed"},
-				{".aa", "audio/audible"},
-				{".AAC", "audio/aac"},
-				{".aaf", "application/octet-stream"},
-				{".aax", "audio/vnd.audible.aax"},
-				{".ac3", "audio/ac3"},
-				{".aca", "application/octet-stream"},
-				{".accda", "application/msaccess.addin"},
-				{".accdb", "application/msaccess"},
-				{".accdc", "application/msaccess.cab"},
-				{".accde", "application/msaccess"},
-				{".accdr", "application/msaccess.runtime"},
-				{".accdt", "application/msaccess"},
-				{".accdw", "application/msaccess.webapplication"},
-				{".accft", "application/msaccess.ftemplate"},
-				{".acx", "application/internet-property-stream"},
-				{".AddIn", "text/xml"},
-				{".ade", "application/msaccess"},
-				{".adobebridge", "application/x-bridge-url"},
-				{".adp", "application/msaccess"},
-				{".ADT", "audio/vnd.dlna.adts"},
-				{".ADTS", "audio/aac"},
-				{".afm", "application/octet-stream"},
-				{".ai", "application/postscript"},
-				{".aif", "audio/x-aiff"},
-				{".aifc", "audio/aiff"},
-				{".aiff", "audio/aiff"},
-				{".air", "application/vnd.adobe.air-application-installer-package+zip"},
-				{".amc", "application/x-mpeg"},
-				{".application", "application/x-ms-application"},
-				{".art", "image/x-jg"},
-				{".asa", "application/xml"},
-				{".asax", "application/xml"},
-				{".ascx", "application/xml"},
-				{".asd", "application/octet-stream"},
-				{".asf", "video/x-ms-asf"},
-				{".ashx", "application/xml"},
-				{".asi", "application/octet-stream"},
-				{".asm", "text/plain"},
-				{".asmx", "application/xml"},
-				{".aspx", "application/xml"},
-				{".asr", "video/x-ms-asf"},
-				{".asx", "video/x-ms-asf"},
-				{".atom", "application/atom+xml"},
-				{".au", "audio/basic"},
-				{".avi", "video/x-msvideo"},
-				{".axs", "application/olescript"},
-				{".bas", "text/plain"},
-				{".bcpio", "application/x-bcpio"},
-				{".bin", "application/octet-stream"},
-				{".bmp", "image/bmp"},
-				{".c", "text/plain"},
-				{".cab", "application/octet-stream"},
-				{".caf", "audio/x-caf"},
-				{".calx", "application/vnd.ms-office.calx"},
-				{".cat", "application/vnd.ms-pki.seccat"},
-				{".cc", "text/plain"},
-				{".cd", "text/plain"},
-				{".cdda", "audio/aiff"},
-				{".cdf", "application/x-cdf"},
-				{".cer", "application/x-x509-ca-cert"},
-				{".chm", "application/octet-stream"},
-				{".class", "application/x-java-applet"},
-				{".clp", "application/x-msclip"},
-				{".cmx", "image/x-cmx"},
-				{".cnf", "text/plain"},
-				{".cod", "image/cis-cod"},
-				{".config", "application/xml"},
-				{".contact", "text/x-ms-contact"},
-				{".coverage", "application/xml"},
-				{".cpio", "application/x-cpio"},
-				{".cpp", "text/plain"},
-				{".crd", "application/x-mscardfile"},
-				{".crl", "application/pkix-crl"},
-				{".crt", "application/x-x509-ca-cert"},
-				{".cs", "text/plain"},
-				{".csdproj", "text/plain"},
-				{".csh", "application/x-csh"},
-				{".csproj", "text/plain"},
-				{".css", "text/css"},
-				{".csv", "text/csv"},
-				{".cur", "application/octet-stream"},
-				{".cxx", "text/plain"},
-				{".dat", "application/octet-stream"},
-				{".datasource", "application/xml"},
-				{".dbproj", "text/plain"},
-				{".dcr", "application/x-director"},
-				{".def", "text/plain"},
-				{".deploy", "application/octet-stream"},
-				{".der", "application/x-x509-ca-cert"},
-				{".dgml", "application/xml"},
-				{".dib", "image/bmp"},
-				{".dif", "video/x-dv"},
-				{".dir", "application/x-director"},
-				{".disco", "text/xml"},
-				{".dll", "application/x-msdownload"},
-				{".dll.config", "text/xml"},
-				{".dlm", "text/dlm"},
-				{".doc", "application/msword"},
-				{".docm", "application/vnd.ms-word.document.macroEnabled.12"},
-				{".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
-				{".dot", "application/msword"},
-				{".dotm", "application/vnd.ms-word.template.macroEnabled.12"},
-				{".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
-				{".dsp", "application/octet-stream"},
-				{".dsw", "text/plain"},
-				{".dtd", "text/xml"},
-				{".dtsConfig", "text/xml"},
-				{".dv", "video/x-dv"},
-				{".dvi", "application/x-dvi"},
-				{".dwf", "drawing/x-dwf"},
-				{".dwp", "application/octet-stream"},
-				{".dxr", "application/x-director"},
-				{".eml", "message/rfc822"},
-				{".emz", "application/octet-stream"},
-				{".eot", "application/octet-stream"},
-				{".eps", "application/postscript"},
-				{".etl", "application/etl"},
-				{".etx", "text/x-setext"},
-				{".evy", "application/envoy"},
-				{".exe", "application/octet-stream"},
-				{".exe.config", "text/xml"},
-				{".fdf", "application/vnd.fdf"},
-				{".fif", "application/fractals"},
-				{".filters", "Application/xml"},
-				{".fla", "application/octet-stream"},
-				{".flr", "x-world/x-vrml"},
-				{".flv", "video/x-flv"},
-				{".fsscript", "application/fsharp-script"},
-				{".fsx", "application/fsharp-script"},
-				{".generictest", "application/xml"},
-				{".gif", "image/gif"},
-				{".group", "text/x-ms-group"},
-				{".gsm", "audio/x-gsm"},
-				{".gtar", "application/x-gtar"},
-				{".gz", "application/x-gzip"},
-				{".h", "text/plain"},
-				{".hdf", "application/x-hdf"},
-				{".hdml", "text/x-hdml"},
-				{".hhc", "application/x-oleobject"},
-				{".hhk", "application/octet-stream"},
-				{".hhp", "application/octet-stream"},
-				{".hlp", "application/winhlp"},
-				{".hpp", "text/plain"},
-				{".hqx", "application/mac-binhex40"},
-				{".hta", "application/hta"},
-				{".htc", "text/x-component"},
-				{".htm", "text/html"},
-				{".html", "text/html"},
-				{".htt", "text/webviewhtml"},
-				{".hxa", "application/xml"},
-				{".hxc", "application/xml"},
-				{".hxd", "application/octet-stream"},
-				{".hxe", "application/xml"},
-				{".hxf", "application/xml"},
-				{".hxh", "application/octet-stream"},
-				{".hxi", "application/octet-stream"},
-				{".hxk", "application/xml"},
-				{".hxq", "application/octet-stream"},
-				{".hxr", "application/octet-stream"},
-				{".hxs", "application/octet-stream"},
-				{".hxt", "text/html"},
-				{".hxv", "application/xml"},
-				{".hxw", "application/octet-stream"},
-				{".hxx", "text/plain"},
-				{".i", "text/plain"},
-				{".ico", "image/x-icon"},
-				{".ics", "application/octet-stream"},
-				{".idl", "text/plain"},
-				{".ief", "image/ief"},
-				{".iii", "application/x-iphone"},
-				{".inc", "text/plain"},
-				{".inf", "application/octet-stream"},
-				{".inl", "text/plain"},
-				{".ins", "application/x-internet-signup"},
-				{".ipa", "application/x-itunes-ipa"},
-				{".ipg", "application/x-itunes-ipg"},
-				{".ipproj", "text/plain"},
-				{".ipsw", "application/x-itunes-ipsw"},
-				{".iqy", "text/x-ms-iqy"},
-				{".isp", "application/x-internet-signup"},
-				{".ite", "application/x-itunes-ite"},
-				{".itlp", "application/x-itunes-itlp"},
-				{".itms", "application/x-itunes-itms"},
-				{".itpc", "application/x-itunes-itpc"},
-				{".IVF", "video/x-ivf"},
-				{".jar", "application/java-archive"},
-				{".java", "application/octet-stream"},
-				{".jck", "application/liquidmotion"},
-				{".jcz", "application/liquidmotion"},
-				{".jfif", "image/pjpeg"},
-				{".jnlp", "application/x-java-jnlp-file"},
-				{".jpb", "application/octet-stream"},
-				{".jpe", "image/jpeg"},
-				{".jpeg", "image/jpeg"},
-				{".jpg", "image/jpeg"},
-				{".js", "application/x-javascript"},
-				{".json", "application/json"},
-				{".jsx", "text/jscript"},
-				{".jsxbin", "text/plain"},
-				{".latex", "application/x-latex"},
-				{".library-ms", "application/windows-library+xml"},
-				{".lit", "application/x-ms-reader"},
-				{".loadtest", "application/xml"},
-				{".lpk", "application/octet-stream"},
-				{".lsf", "video/x-la-asf"},
-				{".lst", "text/plain"},
-				{".lsx", "video/x-la-asf"},
-				{".lzh", "application/octet-stream"},
-				{".m13", "application/x-msmediaview"},
-				{".m14", "application/x-msmediaview"},
-				{".m1v", "video/mpeg"},
-				{".m2t", "video/vnd.dlna.mpeg-tts"},
-				{".m2ts", "video/vnd.dlna.mpeg-tts"},
-				{".m2v", "video/mpeg"},
-				{".m3u", "audio/x-mpegurl"},
-				{".m3u8", "audio/x-mpegurl"},
-				{".m4a", "audio/m4a"},
-				{".m4b", "audio/m4b"},
-				{".m4p", "audio/m4p"},
-				{".m4r", "audio/x-m4r"},
-				{".m4v", "video/x-m4v"},
-				{".mac", "image/x-macpaint"},
-				{".mak", "text/plain"},
-				{".man", "application/x-troff-man"},
-				{".manifest", "application/x-ms-manifest"},
-				{".map", "text/plain"},
-				{".master", "application/xml"},
-				{".mda", "application/msaccess"},
-				{".mdb", "application/x-msaccess"},
-				{".mde", "application/msaccess"},
-				{".mdp", "application/octet-stream"},
-				{".me", "application/x-troff-me"},
-				{".mfp", "application/x-shockwave-flash"},
-				{".mht", "message/rfc822"},
-				{".mhtml", "message/rfc822"},
-				{".mid", "audio/mid"},
-				{".midi", "audio/mid"},
-				{".mix", "application/octet-stream"},
-				{".mk", "text/plain"},
-				{".mmf", "application/x-smaf"},
-				{".mno", "text/xml"},
-				{".mny", "application/x-msmoney"},
-				{".mod", "video/mpeg"},
-				{".mov", "video/quicktime"},
-				{".movie", "video/x-sgi-movie"},
-				{".mp2", "video/mpeg"},
-				{".mp2v", "video/mpeg"},
-				{".mp3", "audio/mpeg"},
-				{".mp4", "video/mp4"},
-				{".mp4v", "video/mp4"},
-				{".mpa", "video/mpeg"},
-				{".mpe", "video/mpeg"},
-				{".mpeg", "video/mpeg"},
-				{".mpf", "application/vnd.ms-mediapackage"},
-				{".mpg", "video/mpeg"},
-				{".mpp", "application/vnd.ms-project"},
-				{".mpv2", "video/mpeg"},
-				{".mqv", "video/quicktime"},
-				{".ms", "application/x-troff-ms"},
-				{".msi", "application/octet-stream"},
-				{".mso", "application/octet-stream"},
-				{".mts", "video/vnd.dlna.mpeg-tts"},
-				{".mtx", "application/xml"},
-				{".mvb", "application/x-msmediaview"},
-				{".mvc", "application/x-miva-compiled"},
-				{".mxp", "application/x-mmxp"},
-				{".nc", "application/x-netcdf"},
-				{".nsc", "video/x-ms-asf"},
-				{".nws", "message/rfc822"},
-				{".ocx", "application/octet-stream"},
-				{".oda", "application/oda"},
-				{".odc", "text/x-ms-odc"},
-				{".odh", "text/plain"},
-				{".odl", "text/plain"},
-				{".odp", "application/vnd.oasis.opendocument.presentation"},
-				{".ods", "application/oleobject"},
-				{".odt", "application/vnd.oasis.opendocument.text"},
-				{".one", "application/onenote"},
-				{".onea", "application/onenote"},
-				{".onepkg", "application/onenote"},
-				{".onetmp", "application/onenote"},
-				{".onetoc", "application/onenote"},
-				{".onetoc2", "application/onenote"},
-				{".orderedtest", "application/xml"},
-				{".osdx", "application/opensearchdescription+xml"},
-				{".p10", "application/pkcs10"},
-				{".p12", "application/x-pkcs12"},
-				{".p7b", "application/x-pkcs7-certificates"},
-				{".p7c", "application/pkcs7-mime"},
-				{".p7m", "application/pkcs7-mime"},
-				{".p7r", "application/x-pkcs7-certreqresp"},
-				{".p7s", "application/pkcs7-signature"},
-				{".pbm", "image/x-portable-bitmap"},
-				{".pcast", "application/x-podcast"},
-				{".pct", "image/pict"},
-				{".pcx", "application/octet-stream"},
-				{".pcz", "application/octet-stream"},
-				{".pdf", "application/pdf"},
-				{".pfb", "application/octet-stream"},
-				{".pfm", "application/octet-stream"},
-				{".pfx", "application/x-pkcs12"},
-				{".pgm", "image/x-portable-graymap"},
-				{".pic", "image/pict"},
-				{".pict", "image/pict"},
-				{".pkgdef", "text/plain"},
-				{".pkgundef", "text/plain"},
-				{".pko", "application/vnd.ms-pki.pko"},
-				{".pls", "audio/scpls"},
-				{".pma", "application/x-perfmon"},
-				{".pmc", "application/x-perfmon"},
-				{".pml", "application/x-perfmon"},
-				{".pmr", "application/x-perfmon"},
-				{".pmw", "application/x-perfmon"},
-				{".png", "image/png"},
-				{".pnm", "image/x-portable-anymap"},
-				{".pnt", "image/x-macpaint"},
-				{".pntg", "image/x-macpaint"},
-				{".pnz", "image/png"},
-				{".pot", "application/vnd.ms-powerpoint"},
-				{".potm", "application/vnd.ms-powerpoint.template.macroEnabled.12"},
-				{".potx", "application/vnd.openxmlformats-officedocument.presentationml.template"},
-				{".ppa", "application/vnd.ms-powerpoint"},
-				{".ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12"},
-				{".ppm", "image/x-portable-pixmap"},
-				{".pps", "application/vnd.ms-powerpoint"},
-				{".ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
-				{".ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
-				{".ppt", "application/vnd.ms-powerpoint"},
-				{".pptm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
-				{".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
-				{".prf", "application/pics-rules"},
-				{".prm", "application/octet-stream"},
-				{".prx", "application/octet-stream"},
-				{".ps", "application/postscript"},
-				{".psc1", "application/PowerShell"},
-				{".psd", "application/octet-stream"},
-				{".psess", "application/xml"},
-				{".psm", "application/octet-stream"},
-				{".psp", "application/octet-stream"},
-				{".pub", "application/x-mspublisher"},
-				{".pwz", "application/vnd.ms-powerpoint"},
-				{".qht", "text/x-html-insertion"},
-				{".qhtm", "text/x-html-insertion"},
-				{".qt", "video/quicktime"},
-				{".qti", "image/x-quicktime"},
-				{".qtif", "image/x-quicktime"},
-				{".qtl", "application/x-quicktimeplayer"},
-				{".qxd", "application/octet-stream"},
-				{".ra", "audio/x-pn-realaudio"},
-				{".ram", "audio/x-pn-realaudio"},
-				{".rar", "application/octet-stream"},
-				{".ras", "image/x-cmu-raster"},
-				{".rat", "application/rat-file"},
-				{".rc", "text/plain"},
-				{".rc2", "text/plain"},
-				{".rct", "text/plain"},
-				{".rdlc", "application/xml"},
-				{".resx", "application/xml"},
-				{".rf", "image/vnd.rn-realflash"},
-				{".rgb", "image/x-rgb"},
-				{".rgs", "text/plain"},
-				{".rm", "application/vnd.rn-realmedia"},
-				{".rmi", "audio/mid"},
-				{".rmp", "application/vnd.rn-rn_music_package"},
-				{".roff", "application/x-troff"},
-				{".rpm", "audio/x-pn-realaudio-plugin"},
-				{".rqy", "text/x-ms-rqy"},
-				{".rtf", "application/rtf"},
-				{".rtx", "text/richtext"},
-				{".ruleset", "application/xml"},
-				{".s", "text/plain"},
-				{".safariextz", "application/x-safari-safariextz"},
-				{".scd", "application/x-msschedule"},
-				{".sct", "text/scriptlet"},
-				{".sd2", "audio/x-sd2"},
-				{".sdp", "application/sdp"},
-				{".sea", "application/octet-stream"},
-				{".searchConnector-ms", "application/windows-search-connector+xml"},
-				{".setpay", "application/set-payment-initiation"},
-				{".setreg", "application/set-registration-initiation"},
-				{".settings", "application/xml"},
-				{".sgimb", "application/x-sgimb"},
-				{".sgml", "text/sgml"},
-				{".sh", "application/x-sh"},
-				{".shar", "application/x-shar"},
-				{".shtml", "text/html"},
-				{".sit", "application/x-stuffit"},
-				{".sitemap", "application/xml"},
-				{".skin", "application/xml"},
-				{".sldm", "application/vnd.ms-powerpoint.slide.macroEnabled.12"},
-				{".sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"},
-				{".slk", "application/vnd.ms-excel"},
-				{".sln", "text/plain"},
-				{".slupkg-ms", "application/x-ms-license"},
-				{".smd", "audio/x-smd"},
-				{".smi", "application/octet-stream"},
-				{".smx", "audio/x-smd"},
-				{".smz", "audio/x-smd"},
-				{".snd", "audio/basic"},
-				{".snippet", "application/xml"},
-				{".snp", "application/octet-stream"},
-				{".sol", "text/plain"},
-				{".sor", "text/plain"},
-				{".spc", "application/x-pkcs7-certificates"},
-				{".spl", "application/futuresplash"},
-				{".src", "application/x-wais-source"},
-				{".srf", "text/plain"},
-				{".SSISDeploymentManifest", "text/xml"},
-				{".ssm", "application/streamingmedia"},
-				{".sst", "application/vnd.ms-pki.certstore"},
-				{".stl", "application/vnd.ms-pki.stl"},
-				{".sv4cpio", "application/x-sv4cpio"},
-				{".sv4crc", "application/x-sv4crc"},
-				{".svc", "application/xml"},
-				{".swf", "application/x-shockwave-flash"},
-				{".t", "application/x-troff"},
-				{".tar", "application/x-tar"},
-				{".tcl", "application/x-tcl"},
-				{".testrunconfig", "application/xml"},
-				{".testsettings", "application/xml"},
-				{".tex", "application/x-tex"},
-				{".texi", "application/x-texinfo"},
-				{".texinfo", "application/x-texinfo"},
-				{".tgz", "application/x-compressed"},
-				{".thmx", "application/vnd.ms-officetheme"},
-				{".thn", "application/octet-stream"},
-				{".tif", "image/tiff"},
-				{".tiff", "image/tiff"},
-				{".tlh", "text/plain"},
-				{".tli", "text/plain"},
-				{".toc", "application/octet-stream"},
-				{".tr", "application/x-troff"},
-				{".trm", "application/x-msterminal"},
-				{".trx", "application/xml"},
-				{".ts", "video/vnd.dlna.mpeg-tts"},
-				{".tsv", "text/tab-separated-values"},
-				{".ttf", "application/octet-stream"},
-				{".tts", "video/vnd.dlna.mpeg-tts"},
-				{".txt", "text/plain"},
-				{".u32", "application/octet-stream"},
-				{".uls", "text/iuls"},
-				{".user", "text/plain"},
-				{".ustar", "application/x-ustar"},
-				{".vb", "text/plain"},
-				{".vbdproj", "text/plain"},
-				{".vbk", "video/mpeg"},
-				{".vbproj", "text/plain"},
-				{".vbs", "text/vbscript"},
-				{".vcf", "text/x-vcard"},
-				{".vcproj", "Application/xml"},
-				{".vcs", "text/plain"},
-				{".vcxproj", "Application/xml"},
-				{".vddproj", "text/plain"},
-				{".vdp", "text/plain"},
-				{".vdproj", "text/plain"},
-				{".vdx", "application/vnd.ms-visio.viewer"},
-				{".vml", "text/xml"},
-				{".vscontent", "application/xml"},
-				{".vsct", "text/xml"},
-				{".vsd", "application/vnd.visio"},
-				{".vsi", "application/ms-vsi"},
-				{".vsix", "application/vsix"},
-				{".vsixlangpack", "text/xml"},
-				{".vsixmanifest", "text/xml"},
-				{".vsmdi", "application/xml"},
-				{".vspscc", "text/plain"},
-				{".vss", "application/vnd.visio"},
-				{".vsscc", "text/plain"},
-				{".vssettings", "text/xml"},
-				{".vssscc", "text/plain"},
-				{".vst", "application/vnd.visio"},
-				{".vstemplate", "text/xml"},
-				{".vsto", "application/x-ms-vsto"},
-				{".vsw", "application/vnd.visio"},
-				{".vsx", "application/vnd.visio"},
-				{".vtx", "application/vnd.visio"},
-				{".wav", "audio/wav"},
-				{".wave", "audio/wav"},
-				{".wax", "audio/x-ms-wax"},
-				{".wbk", "application/msword"},
-				{".wbmp", "image/vnd.wap.wbmp"},
-				{".wcm", "application/vnd.ms-works"},
-				{".wdb", "application/vnd.ms-works"},
-				{".wdp", "image/vnd.ms-photo"},
-				{".webarchive", "application/x-safari-webarchive"},
-				{".webtest", "application/xml"},
-				{".wiq", "application/xml"},
-				{".wiz", "application/msword"},
-				{".wks", "application/vnd.ms-works"},
-				{".WLMP", "application/wlmoviemaker"},
-				{".wlpginstall", "application/x-wlpg-detect"},
-				{".wlpginstall3", "application/x-wlpg3-detect"},
-				{".wm", "video/x-ms-wm"},
-				{".wma", "audio/x-ms-wma"},
-				{".wmd", "application/x-ms-wmd"},
-				{".wmf", "application/x-msmetafile"},
-				{".wml", "text/vnd.wap.wml"},
-				{".wmlc", "application/vnd.wap.wmlc"},
-				{".wmls", "text/vnd.wap.wmlscript"},
-				{".wmlsc", "application/vnd.wap.wmlscriptc"},
-				{".wmp", "video/x-ms-wmp"},
-				{".wmv", "video/x-ms-wmv"},
-				{".wmx", "video/x-ms-wmx"},
-				{".wmz", "application/x-ms-wmz"},
-				{".wpl", "application/vnd.ms-wpl"},
-				{".wps", "application/vnd.ms-works"},
-				{".wri", "application/x-mswrite"},
-				{".wrl", "x-world/x-vrml"},
-				{".wrz", "x-world/x-vrml"},
-				{".wsc", "text/scriptlet"},
-				{".wsdl", "text/xml"},
-				{".wvx", "video/x-ms-wvx"},
-				{".x", "application/directx"},
-				{".xaf", "x-world/x-vrml"},
-				{".xaml", "application/xaml+xml"},
-				{".xap", "application/x-silverlight-app"},
-				{".xbap", "application/x-ms-xbap"},
-				{".xbm", "image/x-xbitmap"},
-				{".xdr", "text/plain"},
-				{".xht", "application/xhtml+xml"},
-				{".xhtml", "application/xhtml+xml"},
-				{".xla", "application/vnd.ms-excel"},
-				{".xlam", "application/vnd.ms-excel.addin.macroEnabled.12"},
-				{".xlc", "application/vnd.ms-excel"},
-				{".xld", "application/vnd.ms-excel"},
-				{".xlk", "application/vnd.ms-excel"},
-				{".xll", "application/vnd.ms-excel"},
-				{".xlm", "application/vnd.ms-excel"},
-				{".xls", "application/vnd.ms-excel"},
-				{".xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
-				{".xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12"},
-				{".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
-				{".xlt", "application/vnd.ms-excel"},
-				{".xltm", "application/vnd.ms-excel.template.macroEnabled.12"},
-				{".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
-				{".xlw", "application/vnd.ms-excel"},
-				{".xml", "text/xml"},
-				{".xmta", "application/xml"},
-				{".xof", "x-world/x-vrml"},
-				{".XOML", "text/plain"},
-				{".xpm", "image/x-xpixmap"},
-				{".xps", "application/vnd.ms-xpsdocument"},
-				{".xrm-ms", "text/xml"},
-				{".xsc", "application/xml"},
-				{".xsd", "text/xml"},
-				{".xsf", "text/xml"},
-				{".xsl", "text/xml"},
-				{".xslt", "text/xml"},
-				{".xsn", "application/octet-stream"},
-				{".xss", "application/xml"},
-				{".xtp", "application/octet-stream"},
-				{".xwd", "image/x-xwindowdump"},
-				{".z", "application/x-compress"},
-				{".zip", "application/x-zip-compressed"}
-			};
-
-		public static string GetMimeType (string _extension) {
-			if (_extension == null) {
-				throw new ArgumentNullException ("_extension");
-			}
-
-			if (!_extension.StartsWith (".")) {
-				_extension = "." + _extension;
-			}
-
-			string mime;
-
-			return _mappings.TryGetValue (_extension, out mime) ? mime : "application/octet-stream";
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/OpenID.cs
===================================================================
--- binary-improvements/MapRendering/Web/OpenID.cs	(revision 448)
+++ 	(revision )
@@ -1,227 +1,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.IO;
-using System.Net;
-using System.Net.Security;
-using System.Reflection;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace AllocsFixes.NetConnections.Servers.Web {
-	public static class OpenID {
-		private const string STEAM_LOGIN = "https://steamcommunity.com/openid/login";
-
-		private static readonly Regex steamIdUrlMatcher =
-			new Regex (@"^https?:\/\/steamcommunity\.com\/openid\/id\/([0-9]{17,18})");
-
-		private static readonly X509Certificate2 caCert =
-			new X509Certificate2 (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) +
-			                      "/steam-rootca.cer");
-
-		private static readonly X509Certificate2 caIntermediateCert =
-			new X509Certificate2 (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) +
-			                      "/steam-intermediate.cer");
-
-		private const bool verboseSsl = false;
-		private static bool debugOpenId => Webserver.OpenID.debugOpenId;
-
-		static OpenID () {
-			ServicePointManager.ServerCertificateValidationCallback = (_srvPoint, _certificate, _chain, _errors) => {
-				if (_errors == SslPolicyErrors.None) {
-					if (verboseSsl) {
-						Log.Out ("Steam certificate: No error (1)");
-					}
-
-					return true;
-				}
-
-				X509Chain privateChain = new X509Chain ();
-				privateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
-
-				privateChain.ChainPolicy.ExtraStore.Add (caCert);
-				privateChain.ChainPolicy.ExtraStore.Add (caIntermediateCert);
-
-				if (privateChain.Build (new X509Certificate2 (_certificate))) {
-					// No errors, immediately return
-					privateChain.Reset ();
-					if (verboseSsl) {
-						Log.Out ("Steam certificate: No error (2)");
-					}
-
-					return true;
-				}
-
-				if (privateChain.ChainStatus.Length == 0) {
-					// No errors, immediately return
-					privateChain.Reset ();
-					if (verboseSsl) {
-						Log.Out ("Steam certificate: No error (3)");
-					}
-
-					return true;
-				}
-
-				// Iterate all chain elements
-				foreach (X509ChainElement chainEl in privateChain.ChainElements) {
-					if (verboseSsl) {
-						Log.Out ("Validating cert: " + chainEl.Certificate.Subject);
-					}
-
-					// Iterate all status flags of the current cert
-					foreach (X509ChainStatus chainStatus in chainEl.ChainElementStatus) {
-						if (verboseSsl) {
-							Log.Out ("   Status: " + chainStatus.Status);
-						}
-
-						if (chainStatus.Status == X509ChainStatusFlags.NoError) {
-							// This status is not an error, skip
-							continue;
-						}
-
-						if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot && chainEl.Certificate.Equals (caCert)) {
-							// This status is about the cert being an untrusted root certificate but the certificate is one of those we added, ignore
-							continue;
-						}
-
-						// This status is an error, print information
-						Log.Warning ("Steam certificate error: " + chainEl.Certificate.Subject + " ### Error: " +
-						             chainStatus.Status);
-						privateChain.Reset ();
-						return false;
-					}
-				}
-
-				foreach (X509ChainStatus chainStatus in privateChain.ChainStatus) {
-					if (chainStatus.Status != X509ChainStatusFlags.NoError &&
-					    chainStatus.Status != X509ChainStatusFlags.UntrustedRoot) {
-						Log.Warning ("Steam certificate error: " + chainStatus.Status);
-						privateChain.Reset ();
-						return false;
-					}
-				}
-
-				// We didn't find any errors, chain is valid
-				privateChain.Reset ();
-				if (verboseSsl) {
-					Log.Out ("Steam certificate: No error (4)");
-				}
-
-				return true;
-			};
-		}
-
-		public static string GetOpenIdLoginUrl (string _returnHost, string _returnUrl) {
-			Dictionary<string, string> queryParams = new Dictionary<string, string> ();
-
-			queryParams.Add ("openid.ns", "http://specs.openid.net/auth/2.0");
-			queryParams.Add ("openid.mode", "checkid_setup");
-			queryParams.Add ("openid.return_to", _returnUrl);
-			queryParams.Add ("openid.realm", _returnHost);
-			queryParams.Add ("openid.identity", "http://specs.openid.net/auth/2.0/identifier_select");
-			queryParams.Add ("openid.claimed_id", "http://specs.openid.net/auth/2.0/identifier_select");
-
-			return STEAM_LOGIN + '?' + buildUrlParams (queryParams);
-		}
-
-		public static ulong Validate (HttpListenerRequest _req) {
-			string mode = getValue (_req, "openid.mode");
-			if (mode == "cancel") {
-				Log.Warning ("Steam OpenID login canceled");
-				return 0;
-			}
-
-			if (mode == "error") {
-				Log.Warning ("Steam OpenID login error: " + getValue (_req, "openid.error"));
-				if (debugOpenId) {
-					PrintOpenIdResponse (_req);
-				}
-
-				return 0;
-			}
-
-			string steamIdString = getValue (_req, "openid.claimed_id");
-			ulong steamId;
-			Match steamIdMatch = steamIdUrlMatcher.Match (steamIdString);
-			if (steamIdMatch.Success) {
-				steamId = ulong.Parse (steamIdMatch.Groups [1].Value);
-			} else {
-				Log.Warning ("Steam OpenID login result did not give a valid SteamID");
-				if (debugOpenId) {
-					PrintOpenIdResponse (_req);
-				}
-
-				return 0;
-			}
-
-			Dictionary<string, string> queryParams = new Dictionary<string, string> ();
-
-			queryParams.Add ("openid.ns", "http://specs.openid.net/auth/2.0");
-
-			queryParams.Add ("openid.assoc_handle", getValue (_req, "openid.assoc_handle"));
-			queryParams.Add ("openid.signed", getValue (_req, "openid.signed"));
-			queryParams.Add ("openid.sig", getValue (_req, "openid.sig"));
-			queryParams.Add ("openid.identity", "http://specs.openid.net/auth/2.0/identifier_select");
-			queryParams.Add ("openid.claimed_id", "http://specs.openid.net/auth/2.0/identifier_select");
-
-			string[] signeds = getValue (_req, "openid.signed").Split (',');
-			foreach (string s in signeds) {
-				queryParams ["openid." + s] = getValue (_req, "openid." + s);
-			}
-
-			queryParams.Add ("openid.mode", "check_authentication");
-
-			byte[] postData = Encoding.ASCII.GetBytes (buildUrlParams (queryParams));
-			HttpWebRequest request = (HttpWebRequest) WebRequest.Create (STEAM_LOGIN);
-			request.Method = "POST";
-			request.ContentType = "application/x-www-form-urlencoded";
-			request.ContentLength = postData.Length;
-			request.Headers.Add (HttpRequestHeader.AcceptLanguage, "en");
-			using (Stream st = request.GetRequestStream ()) {
-				st.Write (postData, 0, postData.Length);
-			}
-
-			HttpWebResponse response = (HttpWebResponse) request.GetResponse ();
-			string responseString;
-			using (Stream st = response.GetResponseStream ()) {
-				using (StreamReader str = new StreamReader (st)) {
-					responseString = str.ReadToEnd ();
-				}
-			}
-
-			if (responseString.ContainsCaseInsensitive ("is_valid:true")) {
-				return steamId;
-			}
-
-			Log.Warning ("Steam OpenID login failed: {0}", responseString);
-			return 0;
-		}
-
-		private static string buildUrlParams (Dictionary<string, string> _queryParams) {
-			string[] paramsArr = new string[_queryParams.Count];
-			int i = 0;
-			foreach (KeyValuePair<string, string> kvp in _queryParams) {
-				paramsArr [i++] = kvp.Key + "=" + Uri.EscapeDataString (kvp.Value);
-			}
-
-			return string.Join ("&", paramsArr);
-		}
-
-		private static string getValue (HttpListenerRequest _req, string _name) {
-			NameValueCollection nvc = _req.QueryString;
-			if (nvc [_name] == null) {
-				throw new MissingMemberException ("OpenID parameter \"" + _name + "\" missing");
-			}
-
-			return nvc [_name];
-		}
-
-		private static void PrintOpenIdResponse (HttpListenerRequest _req) {
-			NameValueCollection nvc = _req.QueryString;
-			for (int i = 0; i < nvc.Count; i++) {
-				Log.Out ("   " + nvc.GetKey (i) + " = " + nvc [i]);
-			}
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/Web.cs
===================================================================
--- binary-improvements/MapRendering/Web/Web.cs	(revision 448)
+++ 	(revision )
@@ -1,296 +1,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Reflection;
-using System.Text;
-using System.Threading;
-using AllocsFixes.NetConnections.Servers.Web.Handlers;
-using AllocsFixes.NetConnections.Servers.Web.SSE;
-using UnityEngine;
-using Webserver.FileCache;
-
-namespace AllocsFixes.NetConnections.Servers.Web {
-	public class Web : IConsoleServer {
-		private const int GUEST_PERMISSION_LEVEL = 2000;
-		public static int handlingCount;
-		public static int currentHandlers;
-		public static long totalHandlingTime = 0;
-		private readonly HttpListener listener = new HttpListener ();
-		private readonly Dictionary<string, PathHandler> handlers = new CaseInsensitiveStringDictionary<PathHandler> ();
-
-		public readonly ConnectionHandler connectionHandler;
-
-		public Web () {
-			try {
-				int webPort = GamePrefs.GetInt (EnumUtils.Parse<EnumGamePrefs> (nameof(EnumGamePrefs.WebDashboardPort)));
-				if (webPort < 1 || webPort > 65533) {
-					Log.Out ("Webserver not started (WebDashboardPort not within 1-65533)");
-					return;
-				}
-
-				if (!Directory.Exists (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) +
-				                       "/webserver_legacy")) {
-					Log.Out ("Webserver not started (folder \"webserver_legacy\" not found in WebInterface mod folder)");
-					return;
-				}
-
-				// TODO: Read from config
-				bool useStaticCache = false;
-
-				string dataFolder = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) + "/webserver_legacy";
-
-				if (!HttpListener.IsSupported) {
-					Log.Out ("Webserver not started (needs Windows XP SP2, Server 2003 or later or Mono)");
-					return;
-				}
-
-				
-				RegisterPathHandler ("/index.htm", new SimpleRedirectHandler ("/static/index.html"));
-				RegisterPathHandler ("/favicon.ico", new SimpleRedirectHandler ("/static/favicon.ico"));
-				RegisterPathHandler ("/session/", new SessionHandler (dataFolder));
-				RegisterPathHandler ("/userstatus", new UserStatusHandler ());
-				RegisterPathHandler ("/static/", new StaticHandler (
-						dataFolder,
-						useStaticCache ? (AbstractCache) new SimpleCache () : new DirectAccess (),
-						false)
-				);
-				RegisterPathHandler ("/itemicons/", new ItemIconHandler (true));
-				RegisterPathHandler ("/map/", new StaticHandler (
-						GameIO.GetSaveGameDir () + "/map",
-						MapRendering.MapRenderer.GetTileCache (),
-						false,
-						"web.map")
-				);
-				RegisterPathHandler ("/api/", new ApiHandler ());
-				RegisterPathHandler ("/sse/", new SseHandler ());
-
-				connectionHandler = new ConnectionHandler ();
-
-				listener.Prefixes.Add ($"http://*:{webPort + 2}/");
-				listener.Start ();
-
-				SdtdConsole.Instance.RegisterServer (this);
-
-				listener.BeginGetContext (HandleRequest, listener);
-
-				Log.Out ("Started Webserver on " + (webPort + 2));
-			} catch (Exception e) {
-				Log.Out ("Error in Web.ctor: " + e);
-			}
-		}
-
-		public void RegisterPathHandler (string _urlBasePath, PathHandler _handler) {
-			if (handlers.ContainsKey (_urlBasePath)) {
-				Log.Error ($"Web: Handler for relative path {_urlBasePath} already registerd.");
-				return;
-			}
-			
-			handlers.Add (_urlBasePath, _handler);
-			_handler.SetBasePathAndParent (this, _urlBasePath);
-		}
-
-		public void Disconnect () {
-			try {
-				listener.Stop ();
-				listener.Close ();
-			} catch (Exception e) {
-				Log.Out ("Error in Web.Disconnect: " + e);
-			}
-		}
-
-		public void Shutdown () {
-			foreach (KeyValuePair<string, PathHandler> kvp in handlers) {
-				kvp.Value.Shutdown ();
-			}
-		}
-
-		public void SendLine (string _line) {
-			connectionHandler.SendLine (_line);
-		}
-
-		public void SendLog (string _formattedMessage, string _plainMessage, string _trace, LogType _type, DateTime _timestamp, long _uptime) {
-			// Do nothing, handled by LogBuffer internally
-		}
-
-		public static bool IsSslRedirected (HttpListenerRequest _req) {
-			string proto = _req.Headers ["X-Forwarded-Proto"];
-			return !string.IsNullOrEmpty (proto) && proto.Equals ("https", StringComparison.OrdinalIgnoreCase);
-		}
-		
-		private readonly Version HttpProtocolVersion = new Version(1, 1);
-		
-#if ENABLE_PROFILER
-		private readonly UnityEngine.Profiling.CustomSampler authSampler = UnityEngine.Profiling.CustomSampler.Create ("Auth");
-		private readonly UnityEngine.Profiling.CustomSampler handlerSampler = UnityEngine.Profiling.CustomSampler.Create ("Handler");
-#endif
-
-		private void HandleRequest (IAsyncResult _result) {
-			if (!listener.IsListening) {
-				return;
-			}
-
-			Interlocked.Increment (ref handlingCount);
-			Interlocked.Increment (ref currentHandlers);
-
-//				MicroStopwatch msw = new MicroStopwatch ();
-#if ENABLE_PROFILER
-			UnityEngine.Profiling.Profiler.BeginThreadProfiling ("AllocsMods", "WebRequest");
-			HttpListenerContext ctx = _listener.EndGetContext (_result);
-			try {
-#else
-			HttpListenerContext ctx = listener.EndGetContext (_result);
-			listener.BeginGetContext (HandleRequest, listener);
-#endif
-			try {
-				HttpListenerRequest request = ctx.Request;
-				HttpListenerResponse response = ctx.Response;
-				response.SendChunked = false;
-
-				response.ProtocolVersion = HttpProtocolVersion;
-
-#if ENABLE_PROFILER
-				authSampler.Begin ();
-#endif
-				int permissionLevel = DoAuthentication (request, out WebConnection conn);
-#if ENABLE_PROFILER
-				authSampler.End ();
-#endif
-
-
-				//Log.Out ("Login status: conn!=null: {0}, permissionlevel: {1}", conn != null, permissionLevel);
-
-
-				if (conn != null) {
-					Cookie cookie = new Cookie ("sid", conn.SessionID, "/") {
-						Expired = false,
-						Expires = DateTime.MinValue,
-						HttpOnly = true,
-						Secure = false
-					};
-					response.AppendCookie (cookie);
-				}
-
-				// No game yet -> fail request
-				if (GameManager.Instance.World == null) {
-					response.StatusCode = (int) HttpStatusCode.ServiceUnavailable;
-					return;
-				}
-
-				if (request.Url.AbsolutePath.Length < 2) {
-					handlers ["/index.htm"].HandleRequest (request, response, conn, permissionLevel);
-					return;
-				} else {
-					foreach (KeyValuePair<string, PathHandler> kvp in handlers) {
-						if (request.Url.AbsolutePath.StartsWith (kvp.Key)) {
-							if (!kvp.Value.IsAuthorizedForHandler (conn, permissionLevel)) {
-								response.StatusCode = (int) HttpStatusCode.Forbidden;
-								if (conn != null) {
-									//Log.Out ("Web.HandleRequest: user '{0}' not allowed to access '{1}'", conn.SteamID, kvp.Value.ModuleName);
-								}
-							} else {
-#if ENABLE_PROFILER
-								handlerSampler.Begin ();
-#endif
-								kvp.Value.HandleRequest (request, response, conn, permissionLevel);
-#if ENABLE_PROFILER
-								handlerSampler.End ();
-#endif
-							}
-
-							return;
-						}
-					}
-				}
-
-				// Not really relevant for non-debugging purposes:
-				//Log.Out ("Error in Web.HandleRequest(): No handler found for path \"" + request.Url.AbsolutePath + "\"");
-				response.StatusCode = (int) HttpStatusCode.NotFound;
-			} catch (IOException e) {
-				if (e.InnerException is SocketException) {
-					Log.Out ("Error in Web.HandleRequest(): Remote host closed connection: " +
-					         e.InnerException.Message);
-				} else {
-					Log.Out ("Error (IO) in Web.HandleRequest(): " + e);
-				}
-			} catch (Exception e) {
-				Log.Error ("Error in Web.HandleRequest(): ");
-				Log.Exception (e);
-			} finally {
-				if (ctx != null && !ctx.Response.SendChunked) {
-					ctx.Response.Close ();
-				}
-
-//					msw.Stop ();
-//					totalHandlingTime += msw.ElapsedMicroseconds;
-//					Log.Out ("Web.HandleRequest(): Took {0} µs", msw.ElapsedMicroseconds);
-				Interlocked.Decrement (ref currentHandlers);
-			}
-#if ENABLE_PROFILER
-			} finally {
-				_listener.BeginGetContext (HandleRequest, _listener);
-				UnityEngine.Profiling.Profiler.EndThreadProfiling ();
-			}
-#endif
-		}
-
-		private int DoAuthentication (HttpListenerRequest _req, out WebConnection _con) {
-			_con = null;
-
-			string sessionId = null;
-			if (_req.Cookies ["sid"] != null) {
-				sessionId = _req.Cookies ["sid"].Value;
-			}
-
-			if (!string.IsNullOrEmpty (sessionId)) {
-				WebConnection con = connectionHandler.IsLoggedIn (sessionId, _req.RemoteEndPoint.Address);
-				if (con != null) {
-					_con = con;
-					return GameManager.Instance.adminTools.Users.GetUserPermissionLevel (_con.UserId);
-				}
-			}
-
-			string remoteEndpointString = _req.RemoteEndPoint.ToString ();
-
-			if (_req.QueryString ["adminuser"] != null && _req.QueryString ["admintoken"] != null) {
-				WebPermissions.AdminToken admin = WebPermissions.Instance.GetWebAdmin (_req.QueryString ["adminuser"],
-					_req.QueryString ["admintoken"]);
-				if (admin != null) {
-					return admin.permissionLevel;
-				}
-
-				Log.Warning ("Invalid Admintoken used from " + remoteEndpointString);
-			}
-
-			if (_req.Url.AbsolutePath.StartsWith ("/session/verify", StringComparison.OrdinalIgnoreCase)) {
-				try {
-					ulong id = OpenID.Validate (_req);
-					if (id > 0) {
-						WebConnection con = connectionHandler.LogIn (id, _req.RemoteEndPoint.Address);
-						_con = con;
-						int level = GameManager.Instance.adminTools.Users.GetUserPermissionLevel (con.UserId);
-						Log.Out ("Steam OpenID login from {0} with ID {1}, permission level {2}",
-							remoteEndpointString, con.UserId, level);
-						return level;
-					}
-
-					Log.Out ("Steam OpenID login failed from {0}", remoteEndpointString);
-				} catch (Exception e) {
-					Log.Error ("Error validating login:");
-					Log.Exception (e);
-				}
-			}
-
-			return GUEST_PERMISSION_LEVEL;
-		}
-
-		public static void SetResponseTextContent (HttpListenerResponse _resp, string _text) {
-			byte[] buf = Encoding.UTF8.GetBytes (_text);
-			_resp.ContentLength64 = buf.Length;
-			_resp.ContentType = "text/html";
-			_resp.ContentEncoding = Encoding.UTF8;
-			_resp.OutputStream.Write (buf, 0, buf.Length);
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/WebCommandResult.cs
===================================================================
--- binary-improvements/MapRendering/Web/WebCommandResult.cs	(revision 448)
+++ 	(revision )
@@ -1,109 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using AllocsFixes.JSON;
-using AllocsFixes.NetConnections.Servers.Web.API;
-using UnityEngine;
-
-namespace AllocsFixes.NetConnections.Servers.Web {
-	public class WebCommandResult : IConsoleConnection {
-		public enum ResultType {
-			Full,
-			ResultOnly,
-			Raw
-		}
-
-		public static int handlingCount;
-		public static int currentHandlers;
-		public static long totalHandlingTime;
-		private readonly string command;
-		private readonly string parameters;
-
-		private readonly HttpListenerResponse response;
-		private readonly ResultType responseType;
-
-		public WebCommandResult (string _command, string _parameters, ResultType _responseType,
-			HttpListenerResponse _response) {
-			Interlocked.Increment (ref handlingCount);
-			Interlocked.Increment (ref currentHandlers);
-
-			response = _response;
-			command = _command;
-			parameters = _parameters;
-			responseType = _responseType;
-		}
-
-		public void SendLines (List<string> _output) {
-//			MicroStopwatch msw = new MicroStopwatch ();
-
-			StringBuilder sb = new StringBuilder ();
-			foreach (string line in _output) {
-				sb.AppendLine (line);
-			}
-
-			try {
-				response.SendChunked = false;
-
-				if (responseType == ResultType.Raw) {
-					WebAPI.WriteText (response, sb.ToString ());
-				} else {
-					JSONNode result;
-					if (responseType == ResultType.ResultOnly) {
-						result = new JSONString (sb.ToString ());
-					} else {
-						JSONObject resultObj = new JSONObject ();
-
-						resultObj.Add ("command", new JSONString (command));
-						resultObj.Add ("parameters", new JSONString (parameters));
-						resultObj.Add ("result", new JSONString (sb.ToString ()));
-
-						result = resultObj;
-					}
-
-					WebAPI.WriteJSON (response, result);
-				}
-			} catch (IOException e) {
-				if (e.InnerException is SocketException) {
-					Log.Out ("Error in WebCommandResult.SendLines(): Remote host closed connection: " +
-					         e.InnerException.Message);
-				} else {
-					Log.Out ("Error (IO) in WebCommandResult.SendLines(): " + e);
-				}
-			} catch (Exception e) {
-				Log.Out ("Error in WebCommandResult.SendLines(): " + e);
-			} finally {
-				if (response != null) {
-					response.Close ();
-				}
-
-//				msw.Stop ();
-//				if (GamePrefs.GetInt (EnumGamePrefs.HideCommandExecutionLog) < 1) {
-//					totalHandlingTime += msw.ElapsedMicroseconds;
-//					Log.Out ("WebCommandResult.SendLines(): Took {0} µs", msw.ElapsedMicroseconds);
-//				}
-
-				Interlocked.Decrement (ref currentHandlers);
-			}
-		}
-
-		public void SendLine (string _text) {
-			//throw new NotImplementedException ();
-		}
-
-		public void SendLog (string _formattedMessage, string _plainMessage, string _trace, LogType _type, DateTime _timestamp, long _uptime) {
-			//throw new NotImplementedException ();
-		}
-
-		public void EnableLogLevel (LogType _type, bool _enable) {
-			//throw new NotImplementedException ();
-		}
-
-		public string GetDescription () {
-			return "WebCommandResult_for_" + command;
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/WebConnection.cs
===================================================================
--- binary-improvements/MapRendering/Web/WebConnection.cs	(revision 448)
+++ 	(revision )
@@ -1,58 +1,0 @@
-using System;
-using System.Collections.Generic;
-using System.Net;
-using UnityEngine;
-
-namespace AllocsFixes.NetConnections.Servers.Web {
-	public class WebConnection : ConsoleConnectionAbstract {
-		private readonly DateTime login;
-//		private readonly List<string> outputLines = new List<string> ();
-		private DateTime lastAction;
-		private readonly string conDescription;
-
-		public WebConnection (string _sessionId, IPAddress _endpoint, PlatformUserIdentifierAbs _userId) {
-			SessionID = _sessionId;
-			Endpoint = _endpoint;
-			UserId = _userId;
-			login = DateTime.Now;
-			lastAction = login;
-			conDescription = "WebPanel from " + Endpoint;
-		}
-
-		public string SessionID { get; }
-
-		public IPAddress Endpoint { get; }
-
-		public PlatformUserIdentifierAbs UserId { get; }
-
-		public TimeSpan Age => DateTime.Now - lastAction;
-
-		public static bool CanViewAllPlayers (int _permissionLevel) {
-			return WebPermissions.Instance.ModuleAllowedWithLevel ("webapi.viewallplayers", _permissionLevel);
-		}
-
-		public static bool CanViewAllClaims (int _permissionLevel) {
-			return WebPermissions.Instance.ModuleAllowedWithLevel ("webapi.viewallclaims", _permissionLevel);
-		}
-
-		public void UpdateUsage () {
-			lastAction = DateTime.Now;
-		}
-
-		public override string GetDescription () {
-			return conDescription;
-		}
-
-		public override void SendLine (string _text) {
-//			outputLines.Add (_text);
-		}
-
-		public override void SendLines (List<string> _output) {
-//			outputLines.AddRange (_output);
-		}
-
-		public override void SendLog (string _formattedMsg, string _plainMsg, string _trace, LogType _type, DateTime _timestamp, long _uptime) {
-			// Do nothing, handled by LogBuffer
-		}
-	}
-}
Index: binary-improvements/MapRendering/Web/WebPermissions.cs
===================================================================
--- binary-improvements/MapRendering/Web/WebPermissions.cs	(revision 448)
+++ 	(revision )
@@ -1,376 +1,0 @@
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Xml;
-
-namespace AllocsFixes.NetConnections.Servers.Web {
-	public class WebPermissions {
-		private const string PERMISSIONS_FILE = "webpermissions.xml";
-		private static WebPermissions instance;
-		private readonly WebModulePermission defaultModulePermission = new WebModulePermission ("", 0);
-
-		private readonly Dictionary<string, WebModulePermission> knownModules =
-			new CaseInsensitiveStringDictionary<WebModulePermission> ();
-
-		private readonly Dictionary<string, AdminToken> admintokens = new CaseInsensitiveStringDictionary<AdminToken> ();
-		private FileSystemWatcher fileWatcher;
-
-		private readonly Dictionary<string, WebModulePermission> modules = new CaseInsensitiveStringDictionary<WebModulePermission> ();
-
-		private WebPermissions () {
-			allModulesList = new List<WebModulePermission> ();
-			allModulesListRO = new ReadOnlyCollection<WebModulePermission> (allModulesList);
-			Directory.CreateDirectory (GetFilePath ());
-			InitFileWatcher ();
-			Load ();
-		}
-
-		public static WebPermissions Instance {
-			get {
-				lock (typeof (WebPermissions)) {
-					return instance ?? (instance = new WebPermissions ());
-				}
-			}
-		}
-
-		public bool ModuleAllowedWithLevel (string _module, int _level) {
-			WebModulePermission permInfo = GetModulePermission (_module);
-			return permInfo.permissionLevel >= _level;
-		}
-
-		public AdminToken GetWebAdmin (string _name, string _token) {
-			if (IsAdmin (_name) && admintokens [_name].token == _token) {
-				return admintokens [_name];
-			}
-
-			return null;
-		}
-
-		public WebModulePermission GetModulePermission (string _module) {
-			if (modules.TryGetValue (_module, out WebModulePermission result)) {
-				return result;
-			}
-
-			if (knownModules.TryGetValue (_module, out result)) {
-				return result;
-			}
-
-			return defaultModulePermission;
-		}
-
-
-		// Admins
-		public void AddAdmin (string _name, string _token, int _permissionLevel, bool _save = true) {
-			AdminToken c = new AdminToken (_name, _token, _permissionLevel);
-			lock (this) {
-				admintokens [_name] = c;
-				if (_save) {
-					Save ();
-				}
-			}
-		}
-
-		public void RemoveAdmin (string _name, bool _save = true) {
-			lock (this) {
-				admintokens.Remove (_name);
-				if (_save) {
-					Save ();
-				}
-			}
-		}
-
-		public bool IsAdmin (string _name) {
-			return admintokens.ContainsKey (_name);
-		}
-
-		public AdminToken[] GetAdmins () {
-			AdminToken[] result = new AdminToken[admintokens.Count];
-			admintokens.CopyValuesTo (result);
-			return result;
-		}
-
-
-		// Commands
-		public void AddModulePermission (string _module, int _permissionLevel, bool _save = true) {
-			WebModulePermission p = new WebModulePermission (_module, _permissionLevel);
-			lock (this) {
-				allModulesList.Clear ();
-				modules [_module] = p;
-				if (_save) {
-					Save ();
-				}
-			}
-		}
-
-		public void AddKnownModule (string _module, int _defaultPermission) {
-			if (string.IsNullOrEmpty (_module)) {
-				return;
-			}
-			
-			WebModulePermission p = new WebModulePermission (_module, _defaultPermission);
-
-			lock (this) {
-				allModulesList.Clear ();
-				knownModules [_module] = p;
-			}
-		}
-
-		public bool IsKnownModule (string _module) {
-			if (string.IsNullOrEmpty (_module)) {
-				return false;
-			}
-
-			lock (this) {
-				return knownModules.ContainsKey (_module);
-			}
-
-		}
-
-		public void RemoveModulePermission (string _module, bool _save = true) {
-			lock (this) {
-				allModulesList.Clear ();
-				modules.Remove (_module);
-				if (_save) {
-					Save ();
-				}
-			}
-		}
-
-		private readonly List<WebModulePermission> allModulesList;
-		private readonly ReadOnlyCollection<WebModulePermission> allModulesListRO; 
-
-		public IList<WebModulePermission> GetModules () {
-			if (allModulesList.Count == 0) {
-				foreach (KeyValuePair<string, WebModulePermission> kvp in knownModules) {
-					if (modules.ContainsKey (kvp.Key)) {
-						allModulesList.Add (modules [kvp.Key]);
-					} else {
-						allModulesList.Add (kvp.Value);
-					}
-				}
-			}
-
-			return allModulesListRO;
-		}
-
-
-		//IO Tasks
-
-		private void InitFileWatcher () {
-			fileWatcher = new FileSystemWatcher (GetFilePath (), GetFileName ());
-			fileWatcher.Changed += OnFileChanged;
-			fileWatcher.Created += OnFileChanged;
-			fileWatcher.Deleted += OnFileChanged;
-			fileWatcher.EnableRaisingEvents = true;
-		}
-
-		private void OnFileChanged (object _source, FileSystemEventArgs _e) {
-			Log.Out ("Reloading " + PERMISSIONS_FILE);
-			Load ();
-		}
-
-		private string GetFilePath () {
-			return GamePrefs.GetString (EnumUtils.Parse<EnumGamePrefs> (nameof(EnumGamePrefs.SaveGameFolder)));
-		}
-
-		private string GetFileName () {
-			return PERMISSIONS_FILE;
-		}
-
-		private string GetFullPath () {
-			return GetFilePath () + "/" + GetFileName ();
-		}
-
-		public void Load () {
-			admintokens.Clear ();
-			modules.Clear ();
-
-			if (!File.Exists (GetFullPath ())) {
-				Log.Out ($"Permissions file '{GetFileName ()}' not found, creating.");
-				Save ();
-				return;
-			}
-
-			Log.Out ($"Loading permissions file at '{GetFullPath ()}'");
-
-			XmlDocument xmlDoc = new XmlDocument ();
-
-			try {
-				xmlDoc.Load (GetFullPath ());
-			} catch (XmlException e) {
-				Log.Error ("Failed loading permissions file: " + e.Message);
-				return;
-			}
-
-			XmlNode adminToolsNode = xmlDoc.DocumentElement;
-
-			if (adminToolsNode == null) {
-				Log.Error ("Failed loading permissions file: No DocumentElement found");
-				return;
-			}
-			
-			foreach (XmlNode childNode in adminToolsNode.ChildNodes) {
-				if (childNode.Name == "admintokens") {
-					foreach (XmlNode subChild in childNode.ChildNodes) {
-						if (subChild.NodeType == XmlNodeType.Comment) {
-							continue;
-						}
-
-						if (subChild.NodeType != XmlNodeType.Element) {
-							Log.Warning ("Unexpected XML node found in 'admintokens' section: " + subChild.OuterXml);
-							continue;
-						}
-
-						XmlElement lineItem = (XmlElement) subChild;
-
-						if (!lineItem.HasAttribute ("name")) {
-							Log.Warning ("Ignoring admintoken-entry because of missing 'name' attribute: " +
-							             subChild.OuterXml);
-							continue;
-						}
-
-						if (!lineItem.HasAttribute ("token")) {
-							Log.Warning ("Ignoring admintoken-entry because of missing 'token' attribute: " +
-							             subChild.OuterXml);
-							continue;
-						}
-
-						if (!lineItem.HasAttribute ("permission_level")) {
-							Log.Warning ("Ignoring admintoken-entry because of missing 'permission_level' attribute: " +
-							             subChild.OuterXml);
-							continue;
-						}
-
-						string name = lineItem.GetAttribute ("name");
-						string token = lineItem.GetAttribute ("token");
-						int permissionLevel;
-						if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out permissionLevel)) {
-							Log.Warning (
-								"Ignoring admintoken-entry because of invalid (non-numeric) value for 'permission_level' attribute: " +
-								subChild.OuterXml);
-							continue;
-						}
-
-						AddAdmin (name, token, permissionLevel, false);
-					}
-				}
-
-				if (childNode.Name == "permissions") {
-					foreach (XmlNode subChild in childNode.ChildNodes) {
-						if (subChild.NodeType == XmlNodeType.Comment) {
-							continue;
-						}
-
-						if (subChild.NodeType != XmlNodeType.Element) {
-							Log.Warning ("Unexpected XML node found in 'permissions' section: " + subChild.OuterXml);
-							continue;
-						}
-
-						XmlElement lineItem = (XmlElement) subChild;
-
-						if (!lineItem.HasAttribute ("module")) {
-							Log.Warning ("Ignoring permission-entry because of missing 'module' attribute: " +
-							             subChild.OuterXml);
-							continue;
-						}
-
-						if (!lineItem.HasAttribute ("permission_level")) {
-							Log.Warning ("Ignoring permission-entry because of missing 'permission_level' attribute: " +
-							             subChild.OuterXml);
-							continue;
-						}
-
-						int permissionLevel;
-						if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out permissionLevel)) {
-							Log.Warning (
-								"Ignoring permission-entry because of invalid (non-numeric) value for 'permission_level' attribute: " +
-								subChild.OuterXml);
-							continue;
-						}
-
-						AddModulePermission (lineItem.GetAttribute ("module"), permissionLevel, false);
-					}
-				}
-			}
-
-			Log.Out ("Loading permissions file done.");
-		}
-
-		public void Save () {
-			fileWatcher.EnableRaisingEvents = false;
-
-			using (StreamWriter sw = new StreamWriter (GetFullPath ())) {
-				sw.WriteLine ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-				sw.WriteLine ("<webpermissions>");
-				sw.WriteLine ();
-				sw.WriteLine ("	<admintokens>");
-				sw.WriteLine (
-					"		<!-- <token name=\"adminuser1\" token=\"supersecrettoken\" permission_level=\"0\" /> -->");
-				foreach (KeyValuePair<string, AdminToken> kvp in admintokens) {
-					sw.WriteLine ("		<token name=\"{0}\" token=\"{1}\" permission_level=\"{2}\" />", kvp.Value.name,
-						kvp.Value.token, kvp.Value.permissionLevel);
-				}
-
-				sw.WriteLine ("	</admintokens>");
-				sw.WriteLine ();
-				sw.WriteLine ("	<permissions>");
-				foreach (KeyValuePair<string, WebModulePermission> kvp in modules) {
-					sw.WriteLine ("		<permission module=\"{0}\" permission_level=\"{1}\" />", kvp.Value.module,
-						kvp.Value.permissionLevel);
-				}
-
-				sw.WriteLine ("		<!-- <permission module=\"web.map\" permission_level=\"1000\" /> -->");
-				sw.WriteLine ();
-				sw.WriteLine ("		<!-- <permission module=\"webapi.getlog\" permission_level=\"0\" /> -->");
-				sw.WriteLine (
-					"		<!-- <permission module=\"webapi.executeconsolecommand\" permission_level=\"0\" /> -->");
-				sw.WriteLine ();
-				sw.WriteLine ("		<!-- <permission module=\"webapi.getstats\" permission_level=\"1000\" /> -->");
-				sw.WriteLine ("		<!-- <permission module=\"webapi.getplayersonline\" permission_level=\"1000\" /> -->");
-				sw.WriteLine ();
-				sw.WriteLine (
-					"		<!-- <permission module=\"webapi.getplayerslocation\" permission_level=\"1000\" /> -->");
-				sw.WriteLine ("		<!-- <permission module=\"webapi.viewallplayers\" permission_level=\"1\" /> -->");
-				sw.WriteLine ();
-				sw.WriteLine ("		<!-- <permission module=\"webapi.getlandclaims\" permission_level=\"1000\" /> -->");
-				sw.WriteLine ("		<!-- <permission module=\"webapi.viewallclaims\" permission_level=\"1\" /> -->");
-				sw.WriteLine ();
-				sw.WriteLine ("		<!-- <permission module=\"webapi.getplayerinventory\" permission_level=\"1\" /> -->");
-				sw.WriteLine ();
-				sw.WriteLine ("		<!-- <permission module=\"webapi.gethostilelocation\" permission_level=\"1\" /> -->");
-				sw.WriteLine ("		<!-- <permission module=\"webapi.getanimalslocation\" permission_level=\"1\" /> -->");
-				sw.WriteLine ("	</permissions>");
-				sw.WriteLine ();
-				sw.WriteLine ("</webpermissions>");
-
-				sw.Flush ();
-				sw.Close ();
-			}
-
-			fileWatcher.EnableRaisingEvents = true;
-		}
-
-
-		public class AdminToken {
-			public string name;
-			public int permissionLevel;
-			public string token;
-
-			public AdminToken (string _name, string _token, int _permissionLevel) {
-				name = _name;
-				token = _token;
-				permissionLevel = _permissionLevel;
-			}
-		}
-
-		public struct WebModulePermission {
-			public string module;
-			public int permissionLevel;
-
-			public WebModulePermission (string _module, int _permissionLevel) {
-				module = _module;
-				permissionLevel = _permissionLevel;
-			}
-		}
-	}
-}
