Index: binary-improvements/7dtd-binaries/README.txt
===================================================================
--- binary-improvements/7dtd-binaries/README.txt	(revision 222)
+++ binary-improvements/7dtd-binaries/README.txt	(revision 224)
@@ -1,5 +1,5 @@
 Put the Assembly-CSharp.deobf.dll (output of the Deobfuscator [1]),
-Assembly-CSharp-firstpass.dll, EasyAntiCheat.Client/Server.dll, LogLibrary.dll
-and UnityEngine.dll in this folder.
+Assembly-CSharp-firstpass.dll, EasyAntiCheat.Client/Server.dll,
+LogLibrary.dll, mscorlib.dll and UnityEngine.dll in this folder.
 
 [1]: https://github.com/DerPopo/deobfuscate-7dtd
Index: binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj
===================================================================
--- binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj	(revision 222)
+++ binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj	(revision 224)
@@ -2,5 +2,5 @@
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <ProductVersion>10.0.0</ProductVersion>
@@ -12,18 +12,8 @@
     <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <ConsolePause>false</ConsolePause>
-  </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>none</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\bin\Release</OutputPath>
+    <OutputPath>..\bin\7DaysToDie_Data\Managed</OutputPath>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
@@ -33,5 +23,5 @@
     <DebugType>none</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\bin\Release</OutputPath>
+    <OutputPath>..\bin\7DaysToDie_Data\Managed</OutputPath>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
@@ -60,4 +50,7 @@
       <HintPath>..\7dtd-binaries\LogLibrary.dll</HintPath>
     </Reference>
+    <Reference Include="mscorlib">
+      <HintPath>..\7dtd-binaries\mscorlib.dll</HintPath>
+    </Reference>
     <Reference Include="Assembly-CSharp">
       <HintPath>..\7dtd-binaries\Assembly-CSharp.dll</HintPath>
@@ -67,25 +60,7 @@
     <Compile Include="src\AssemblyInfo.cs" />
     <Compile Include="src\AllocsLogFunctions.cs" />
-    <Compile Include="src\AdminToolsStuff.cs" />
     <Compile Include="src\PlayerDataStuff.cs" />
     <Compile Include="src\CommandExtensions.cs" />
     <Compile Include="src\CommonMappingFunctions.cs" />
-    <Compile Include="src\MapRendering\MapRendering.cs" />
-    <Compile Include="src\MapRendering\MapRenderBlockBuffer.cs" />
-    <Compile Include="src\MapRendering\Constants.cs" />
-    <Compile Include="src\CustomCommands\GetTime.cs" />
-    <Compile Include="src\CustomCommands\GetGamePrefs.cs" />
-    <Compile Include="src\CustomCommands\SayToPlayer.cs" />
-    <Compile Include="src\CustomCommands\SetTimeReal.cs" />
-    <Compile Include="src\CustomCommands\ShowInventory.cs" />
-    <Compile Include="src\CustomCommands\PrivateMassageConnections.cs" />
-    <Compile Include="src\CustomCommands\Reply.cs" />
-    <Compile Include="src\CustomCommands\Kill.cs" />
-    <Compile Include="src\CustomCommands\ListLandProtection.cs" />
-    <Compile Include="src\CustomCommands\RemoveLandProtection.cs" />
-    <Compile Include="src\CustomCommands\Version.cs" />
-    <Compile Include="src\CustomCommands\RenderMap.cs" />
-    <Compile Include="src\CustomCommands\Give.cs" />
-    <Compile Include="src\CustomCommands\ListItems.cs" />
     <Compile Include="src\NetConnections\ConsoleOutputSeparator.cs" />
     <Compile Include="src\NetConnections\NetTelnetServer.cs" />
@@ -94,10 +69,4 @@
     <Compile Include="src\NetConnections\Servers\Telnet\Telnet.cs" />
     <Compile Include="src\NetConnections\Servers\Telnet\TelnetConnection.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\Web.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\PathHandler.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\StaticHandler.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\SimpleRedirectHandler.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\MimeType.cs" />
-    <Compile Include="src\CustomCommands\EnableRendering.cs" />
     <Compile Include="src\PersistentData\PersistentContainer.cs" />
     <Compile Include="src\StateManager.cs" />
@@ -106,8 +75,4 @@
     <Compile Include="src\PersistentData\Players.cs" />
     <Compile Include="src\PersistentData\Player.cs" />
-    <Compile Include="src\CustomCommands\ListKnownPlayers.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\ApiHandler.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\API\GetPlayersOnline.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\API\WebAPI.cs" />
     <Compile Include="src\JSON\JSONNode.cs" />
     <Compile Include="src\JSON\JSONArray.cs" />
@@ -116,13 +81,8 @@
     <Compile Include="src\JSON\JSONString.cs" />
     <Compile Include="src\JSON\JSONBoolean.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\API\GetPlayersLocation.cs" />
-    <Compile Include="src\CustomCommands\TeleportPlayer.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\API\GetPlayerInventory.cs" />
-    <Compile Include="src\NetConnections\Servers\Web\API\GetLandClaims.cs" />
     <Compile Include="src\BlockingQueue.cs" />
     <Compile Include="src\JSON\Parser.cs" />
     <Compile Include="src\JSON\JSONNull.cs" />
     <Compile Include="src\JSON\MalformedJSONException.cs" />
-    <Compile Include="src\CustomCommands\Unban.cs" />
     <Compile Include="src\ItemList.cs" />
     <Compile Include="src\FileCache\AbstractCache.cs" />
@@ -130,18 +90,16 @@
     <Compile Include="src\FileCache\SimpleCache.cs" />
     <Compile Include="src\FileCache\MapTileCache.cs" />
-    <Compile Include="src\CustomCommands\webstat.cs" />
-    <Compile Include="src\CustomCommands\ListPlayerIds.cs" />
+    <Compile Include="src\Mods.cs" />
+    <Compile Include="src\ModAPI.cs" />
+    <Compile Include="src\Version.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
     <Folder Include="src\" />
-    <Folder Include="src\MapRendering\" />
     <Folder Include="src\CustomCommands\" />
     <Folder Include="src\NetConnections\" />
     <Folder Include="src\NetConnections\Servers\" />
     <Folder Include="src\NetConnections\Servers\Telnet\" />
-    <Folder Include="src\NetConnections\Servers\Web\" />
     <Folder Include="src\PersistentData\" />
-    <Folder Include="src\NetConnections\Servers\Web\API\" />
     <Folder Include="src\JSON\Parser\" />
     <Folder Include="src\FileCache\" />
Index: binary-improvements/7dtd-server-fixes/src/AdminToolsStuff.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/AdminToolsStuff.cs	(revision 222)
+++ 	(revision )
@@ -1,85 +1,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace AllocsFixes
-{
-	public class AdminToolsStuff
-	{
-		public static string[] GetAllowedCommandsList (AdminTools admTools, string _steamID)
-		{
-			List<string> allowed = new List<string> ();
-
-			try {
-				AdminToolsClientInfo tmpInfo = admTools.GetClientCommandInfo (_steamID);
-				if (tmpInfo.SteamID == null || tmpInfo.SteamID.Length == 0) {
-					tmpInfo.PermissionLevel = 1000;
-				}
-
-				List<AdminToolsCommandPermissions> perms = admTools.commandPermissions;
-				ConsoleSdtd console = CommonMappingFunctions.GetGameManager ().m_GUIConsole;
-
-				foreach (AdminToolsCommandPermissions atcp in perms) {
-					if (tmpInfo.SteamID != null && tmpInfo.SteamID.Length > 0) {
-						if ((atcp.PermissionLevel >= tmpInfo.PermissionLevel) || (atcp.PermissionLevel >= 1000)) {
-							addAllowed (console, allowed, atcp.Command);
-						}
-					} else {
-						if (atcp.PermissionLevel >= 1000) {
-							addAllowed (console, allowed, atcp.Command);
-						}
-					}
-				}
-
-				if (tmpInfo.PermissionLevel <= 0) {
-					List<ConsoleCommand> commands = console.commands;
-					foreach (ConsoleCommand c in commands) {
-						if (!allowed.Contains (c.Names () [0])) {
-							if (!hasPermissionLevel (admTools, c.Names () [0])) {
-								addAllowed (console, allowed, c.Names () [0]);
-							}
-						}
-					}
-				}
-
-			} catch (Exception e) {
-				Log.Out ("Error in GetAllowedCommandsList: " + e);
-			}
-
-
-			return allowed.ToArray ();
-		}
-
-		private static bool hasPermissionLevel (AdminTools admTools, string cmd)
-		{
-			List<AdminToolsCommandPermissions> perms = admTools.commandPermissions;
-
-			foreach (AdminToolsCommandPermissions atcp in perms) {
-				foreach (string ccName in getAlternativeNames(cmd)) {
-					if (atcp.Command.ToLower ().Equals (ccName)) {
-						return true;
-					}
-				}
-			}
-			return false;
-		}
-
-		private static void addAllowed (ConsoleSdtd console, List<string> list, string cmd)
-		{
-			foreach (string ccName in getAlternativeNames(cmd)) {
-				if (!list.Contains (ccName)) {
-					list.Add (ccName);
-				}
-			}
-		}
-
-		private static string[] getAlternativeNames (string cmd)
-		{
-			ConsoleCommand cc = CommonMappingFunctions.GetGameManager ().m_GUIConsole.getCommand (cmd);
-			if (cc != null) {
-				return cc.Names ();
-			} else {
-				return new string[]{cmd};
-			}
-		}
-	}
-}
Index: binary-improvements/7dtd-server-fixes/src/AllocsLogFunctions.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/AllocsLogFunctions.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/AllocsLogFunctions.cs	(revision 224)
@@ -31,4 +31,6 @@
 				PersistentContainer.Instance.Players [steamId].SetOnline (ci);
 				PersistentData.PersistentContainer.Instance.Save ();
+
+				Mods.CallRequestToSpawnPlayer (_clientId, _name, _chunkViewDim, _playerProfile);
 			} catch (Exception e) {
 				Log.Out ("Error in AllocsLogFunctions.RequestToSpawnPlayer: " + e);
@@ -36,8 +38,8 @@
 		}
 
-		public static void PlayerDisconnected (ConnectionManager manager, int _clientId, bool _bShutdown)
+		public static void PlayerDisconnected (ConnectionManager manager, ClientInfo _cInfo, bool _bShutdown)
 		{
 			try {
-				Player p = PersistentContainer.Instance.Players.GetPlayerByClientId (_clientId);
+				Player p = PersistentContainer.Instance.Players [_cInfo.playerId];
 				if (p != null) {
 					p.SetOffline ();
@@ -46,4 +48,6 @@
 				}
 				PersistentData.PersistentContainer.Instance.Save ();
+
+				Mods.CallPlayerDisconnected (_cInfo, _bShutdown);
 			} catch (Exception e) {
 				Log.Out ("Error in AllocsLogFunctions.PlayerDisconnected: " + e);
Index: binary-improvements/7dtd-server-fixes/src/AssemblyInfo.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/AssemblyInfo.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/AssemblyInfo.cs	(revision 224)
@@ -18,5 +18,5 @@
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
 
-[assembly: AssemblyVersion("0.104.*")]
+[assembly: AssemblyVersion("0.110.*")]
 
 // The following attributes are used to specify the signing key for the assembly, 
Index: binary-improvements/7dtd-server-fixes/src/CommandExtensions.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/CommandExtensions.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/CommandExtensions.cs	(revision 224)
@@ -12,14 +12,21 @@
 			try {
 				ConsoleSdtd cons = manager.m_GUIConsole;
-				string ns = "AllocsFixes.CustomCommands";
-				string basetype = "ConsoleCommand";
+				Type commandType = typeof (ConsoleCommand);
 
-				foreach (Type t in Assembly.GetExecutingAssembly ().GetTypes()) {
-					if (t.IsClass && t.Namespace.Equals (ns) && t.BaseType.Name.Equals (basetype)) {
-						try {
-							ConstructorInfo ctor = t.GetConstructor (new Type[] {typeof(ConsoleSdtd)});
-							cons.AddCommand ((ConsoleCommand)ctor.Invoke (new object[] {cons}));
-						} catch (Exception e) {
-							Log.Out ("Could not register custom command \"" + t.Name + "\": " + e);
+				Mods.ModData thisMd = new Mods.ModData ();
+				thisMd.assembly = Assembly.GetExecutingAssembly ();
+
+				List<Mods.ModData> mods = Mods.LoadedMods ();
+				mods.Add (thisMd);
+
+				foreach (Mods.ModData md in mods) {
+					foreach (Type t in md.assembly.GetTypes()) {
+						if (t.IsClass && commandType.IsAssignableFrom (t)) {
+							try {
+								ConstructorInfo ctor = t.GetConstructor (new Type[] {typeof(ConsoleSdtd)});
+								cons.AddCommand ((ConsoleCommand)ctor.Invoke (new object[] {cons}));
+							} catch (Exception e) {
+								Log.Out ("Could not register custom command \"" + t.Name + "\": " + e);
+							}
 						}
 					}
Index: binary-improvements/7dtd-server-fixes/src/CommonMappingFunctions.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/CommonMappingFunctions.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/CommonMappingFunctions.cs	(revision 224)
@@ -15,5 +15,5 @@
 		public static GameManager GetGameManager ()
 		{
-			return GetConnectionManager ().gameManager;
+			return GameManager.Instance;
 		}
 
@@ -25,5 +25,5 @@
 		public static EntityPlayer GetEntityPlayer (ClientInfo _ci)
 		{
-			return GetGameManager ().World.playerEntities.dict [_ci.entityId];
+			return GetGameManager ().World.Players.dict [_ci.entityId];
 		}
 
Index: binary-improvements/7dtd-server-fixes/src/ItemList.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/ItemList.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/ItemList.cs	(revision 224)
@@ -27,13 +27,13 @@
 		}
 
-		public Nullable<ItemValue> GetItemValue (string itemName)
+		public ItemValue GetItemValue (string itemName)
 		{
 			if (items.ContainsKey (itemName)) {
-				return items [itemName];
+				return items [itemName].Clone ();
 			} else {
 				itemName = itemName.ToLower ();
 				foreach (KeyValuePair<string, ItemValue> kvp in items) {
 					if (kvp.Key.ToLower ().Equals (itemName)) {
-						return kvp.Value;
+						return kvp.Value.Clone ();
 					}
 				}
@@ -47,5 +47,5 @@
 			foreach (InventoryField invF in cm.GetAllItems()) {
 				ItemBase ib = ItemBase.list [invF.itemValue.type];
-				string name = ib.GetItemName (invF.itemValue);
+				string name = ib.GetItemName ();
 				if (name != null && name.Length > 0) {
 					if (!items.ContainsKey (name)) {
@@ -58,5 +58,5 @@
 			foreach (InventoryField invF in cm.GetAllBlocks()) {
 				ItemBase ib = ItemBase.list [invF.itemValue.type];
-				string name = ib.GetItemName (invF.itemValue);
+				string name = ib.GetItemName ();
 				if (name != null && name.Length > 0) {
 					if (!items.ContainsKey (name)) {
Index: binary-improvements/7dtd-server-fixes/src/ModAPI.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/ModAPI.cs	(revision 224)
+++ binary-improvements/7dtd-server-fixes/src/ModAPI.cs	(revision 224)
@@ -0,0 +1,32 @@
+using System;
+
+namespace AllocsFixes
+{
+	public abstract class ModAPI {
+		public ModAPI () {
+		}
+
+		public abstract string ModName ();
+
+		public abstract string ModVersion ();
+
+		public virtual void GameAwake () {
+		}
+
+		public virtual void GameShutdown () {
+		}
+
+		public virtual void SavePlayerData (int _clientId, PlayerDataFile _playerDataFile) {
+		}
+
+		public virtual void RequestToSpawnPlayer (int _clientId, string _name, int _chunkViewDim, PlayerProfile _playerProfile) {
+		}
+
+		public virtual void PlayerDisconnected (ClientInfo _cInfo, bool _bShutdown) {
+		}
+
+		public virtual void CalcMapColors (Chunk _chunk) {
+		}
+	}
+}
+
Index: binary-improvements/7dtd-server-fixes/src/Mods.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/Mods.cs	(revision 224)
+++ binary-improvements/7dtd-server-fixes/src/Mods.cs	(revision 224)
@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using UnityEngine;
+
+namespace AllocsFixes
+{
+	public static class Mods {
+		public class ModData {
+			public Assembly assembly;
+			public string name;
+			public string version;
+			public ModAPI apiInstance;
+		}
+
+		private static readonly string MOD_PATH = Application.dataPath + "/../Mods";
+		private static Dictionary<string, ModData> loadedMods = new Dictionary<string, ModData> ();
+
+		public static void LoadMods () {
+			if (Directory.Exists (MOD_PATH)) {
+				Log.Out ("Loading mods");
+
+				foreach (string modDir in Directory.GetDirectories (MOD_PATH)) {
+					foreach (string modDll in Directory.GetFiles (modDir, "*.dll")) {
+						try {
+							Assembly assemblyInstance = Assembly.LoadFrom (modDll);
+
+							ModData md = new ModData ();
+							md.assembly = assemblyInstance;
+
+							md.apiInstance = CreateApiInstance (md);
+							if (md.apiInstance == null) {
+								Log.Warning ("DLL does not declare a class of type ModAPI, ignoring");
+								continue;
+							}
+							if (string.IsNullOrEmpty (md.apiInstance.ModName ())) {
+								Log.Warning ("DLL's ModAPI does not override ModName(), ignoring");
+								continue;
+							}
+							if (loadedMods.ContainsKey (md.apiInstance.ModName ())) {
+								Log.Warning ("DLL's ModAPI.ModName() returns name that's already loaded, ignoring");
+								continue;
+							}
+							md.name = md.apiInstance.ModName ();
+							md.version = md.apiInstance.ModVersion ();
+
+							loadedMods.Add (md.name, md);
+
+							Log.Out ("Loaded mod: " + md.name + " (" + md.version + ")");
+						} catch (Exception e) {
+							Log.Error ("Failed loading DLL");
+							Log.Exception (e);
+						}
+					}
+				}
+
+				Log.Out ("Loading mods done");
+			} else {
+				Log.Out ("No mods folder found");
+			}
+		}
+
+		public static bool ModLoaded (string _modName) {
+			return loadedMods.ContainsKey (_modName);
+		}
+
+		public static Assembly GetModAssembly (string _modName) {
+			if (ModLoaded (_modName)) {
+				return loadedMods [_modName].assembly;
+			}
+			return null;
+		}
+
+		public static List<ModData> LoadedMods () {
+			List<ModData> res = new List<ModData> ();
+			foreach (ModData md in loadedMods.Values) {
+				res.Add (md);
+			}
+			return res;
+		}
+
+		private static ModAPI CreateApiInstance (ModData _md) {
+			Type modApiType = typeof (ModAPI);
+			foreach (Type t in _md.assembly.GetTypes ()) {
+				if (modApiType.IsAssignableFrom (t)) {
+					Log.Out ("Found ModAPI");
+
+					return Activator.CreateInstance(t) as ModAPI;
+				}
+			}
+			return null;
+		}
+
+		public static void CallGameAwake () {
+			foreach (ModData md in loadedMods.Values) {
+				if (md.apiInstance != null) {
+					md.apiInstance.GameAwake ();
+				}
+			}
+		}
+
+		public static void CallGameShutdown () {
+			foreach (ModData md in loadedMods.Values) {
+				if (md.apiInstance != null) {
+					md.apiInstance.GameShutdown ();
+				}
+			}
+		}
+
+		public static void CallSavePlayerData (int _clientId, PlayerDataFile _playerDataFile) {
+			foreach (ModData md in loadedMods.Values) {
+				if (md.apiInstance != null) {
+					md.apiInstance.SavePlayerData (_clientId, _playerDataFile);
+				}
+			}
+		}
+
+		public static void CallRequestToSpawnPlayer (int _clientId, string _name, int _chunkViewDim, PlayerProfile _playerProfile) {
+			foreach (ModData md in loadedMods.Values) {
+				if (md.apiInstance != null) {
+					md.apiInstance.RequestToSpawnPlayer (_clientId, _name, _chunkViewDim, _playerProfile);
+				}
+			}
+		}
+
+		public static void CallPlayerDisconnected (ClientInfo _cInfo, bool _bShutdown) {
+			foreach (ModData md in loadedMods.Values) {
+				if (md.apiInstance != null) {
+					md.apiInstance.PlayerDisconnected (_cInfo, _bShutdown);
+				}
+			}
+		}
+
+		public static void CallCalcMapColors (Chunk _chunk) {
+			foreach (ModData md in loadedMods.Values) {
+				if (md.apiInstance != null) {
+					md.apiInstance.CalcMapColors (_chunk);
+				}
+			}
+		}
+
+	
+	}
+}
Index: binary-improvements/7dtd-server-fixes/src/NetConnections/ConsoleOutputSeparator.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/NetConnections/ConsoleOutputSeparator.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/NetConnections/ConsoleOutputSeparator.cs	(revision 224)
@@ -22,7 +22,8 @@
 		private static List<NetCommand> netCommandQueue = new List<NetCommand> ();
 		private static bool isCurrentCommandFromClient = false;
+		private static int issuerOfCurrentClientCommand = -1;
 		private static IConnection issuerOfCurrentCommand;
 
-		public static void C_ExecuteCmdFromClient (ConsoleSdtd console, NetworkPlayer _networkPlayer, string _playerName, string _playerID, string _command)
+		public static void C_ExecuteCmdFromClient (ConsoleSdtd console, int _entityId, string _playerName, string _playerID, string _command)
 		{
 			Log.Out ("Executed command \"" + _command + "\" from player \"" + _playerName + "\"");
@@ -30,6 +31,22 @@
 			lock (netCommandQueue) {
 				isCurrentCommandFromClient = true;
-				console.issuerOfCurrentClientCommand = _networkPlayer;
-				console.ExecuteClientCmdInternal (_playerName, _playerID, _command);
+				issuerOfCurrentClientCommand = _entityId;
+
+				string[] array = _command.Split (' ');
+				if (array.Length == 0) {
+					C_SendResult (console, "*** ERROR: empty command '" + _command + "'");
+				} else {
+					ConsoleCommand cmd = console.getCommand (_command);
+					if (cmd != null) {
+						string[] array2 = new string[array.Length - 1];
+						for (int i = 1; i < array.Length; i++) {
+							array2 [i - 1] = array [i];
+						}
+						cmd.ExecuteRemote (_playerID, array2);
+					} else {
+						C_SendResult (console, "*** ERROR: unknown command '" + array [0] + "'");
+					}
+				}
+
 				isCurrentCommandFromClient = false;
 			}
@@ -40,10 +57,5 @@
 		{
 			if (isCurrentCommandFromClient) {
-				console.gameManager.GetRPCNetworkView ().RPC ("RPC_Console", console.issuerOfCurrentClientCommand, new object[]
-			{
-				_line,
-				false
-			}
-				);
+				CommonMappingFunctions.GetConnectionManager ().SendPackage (new NetPackage_ConsoleCmdClient (_line, false), new PackageDestinationSingleEntityID (issuerOfCurrentClientCommand));
 			} else {
 				if (console.telnetServer != null && issuerOfCurrentCommand != null)
Index: binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/TelnetConnection.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/TelnetConnection.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/TelnetConnection.cs	(revision 224)
@@ -13,6 +13,4 @@
 		private readonly BlockingQueue<string> toClientQueue = new BlockingQueue<string> ();
 		private readonly Telnet telnet;
-		private readonly Thread receiveThread = null;
-		private readonly Thread sendThread = null;
 		private bool authenticated = false;
 		private readonly bool authEnabled;
@@ -44,8 +42,6 @@
 			Log.Out ("Telnet connection from: " + endpoint);
 
-			receiveThread = ThreadMaster.Create ("TelnetClientReceive_" + endpoint.ToString (), new ThreadStart (ReceiveThread));
-			receiveThread.Start ();
-			sendThread = ThreadMaster.Create ("TelnetClientSend" + endpoint.ToString (), new ThreadStart (SendThread));
-			sendThread.Start ();
+			ThreadManager.StartThread ("TelnetClientReceive_" + endpoint.ToString (), new ThreadManager.ThreadFunctionDelegate (ReceiveThread), System.Threading.ThreadPriority.BelowNormal);
+			ThreadManager.StartThread ("TelnetClientSend_" + endpoint.ToString (), new ThreadManager.ThreadFunctionDelegate (SendThread), System.Threading.ThreadPriority.BelowNormal);
 
 			if (authEnabled) {
@@ -77,5 +73,5 @@
 		}
 
-		private void ReceiveThread ()
+		private void ReceiveThread (ThreadManager.ThreadInfo _tInfo)
 		{
 			try {
@@ -116,8 +112,7 @@
 			if (!closed)
 				Close ();
-			ThreadMaster.Remove (Thread.CurrentThread.Name);
 		}
 
-		private void SendThread ()
+		private void SendThread (ThreadManager.ThreadInfo _tInfo)
 		{
 			try {
@@ -140,5 +135,4 @@
 			if (!closed)
 				Close ();
-			ThreadMaster.Remove (Thread.CurrentThread.Name);
 		}
 
Index: binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs	(revision 224)
@@ -32,5 +32,5 @@
 					if (sourceFields [i].count > 0) {
 						int count = sourceFields [i].count;
-						int maxAllowed = ItemBase.list [sourceFields [i].itemValue.type].StackNumber;
+						int maxAllowed = ItemBase.list [sourceFields [i].itemValue.type].Stacknumber.Value;
 						string name = getInvFieldName (sourceFields [i]);
 
@@ -48,5 +48,5 @@
 		{
 			ItemBase iBase = ItemBase.list [item.itemValue.type];
-			return iBase.GetItemName (item.itemValue);
+			return iBase.GetItemName ();
 		}
 
Index: binary-improvements/7dtd-server-fixes/src/PlayerDataStuff.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/PlayerDataStuff.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/PlayerDataStuff.cs	(revision 224)
@@ -14,4 +14,5 @@
 				string steamId = CommonMappingFunctions.GetSteamID(ci);
 				PersistentContainer.Instance.Players[steamId].Inventory.Update(_playerDataFile);
+				Mods.CallSavePlayerData (_clientId, _playerDataFile);
 			} catch (Exception e) {
 				Log.Out ("Error in GM_SavePlayerData: " + e);
Index: binary-improvements/7dtd-server-fixes/src/StateManager.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/StateManager.cs	(revision 222)
+++ binary-improvements/7dtd-server-fixes/src/StateManager.cs	(revision 224)
@@ -1,4 +1,3 @@
 using AllocsFixes.NetConnections.Servers.Telnet;
-using AllocsFixes.NetConnections.Servers.Web;
 using System;
 using System.Reflection;
@@ -12,9 +11,12 @@
 			try {
 				Log.Out ("[7dtd-server-fixes by Alloc] Version: " + Assembly.GetExecutingAssembly ().GetName ().Version);
-				new Web ();
+
+				Mods.LoadMods ();
+				Mods.CallGameAwake ();
+				CommandExtensions.InitCommandExtensions (manager);
+
 				new Telnet ();
 
 				ItemList.Instance.Init ();
-				CommandExtensions.InitCommandExtensions (manager);
 
 				PersistentData.PersistentContainer.Load ();
@@ -28,4 +30,5 @@
 			try {
 				Log.Out ("Server shutting down!");
+				Mods.CallGameShutdown ();
 				PersistentData.PersistentContainer.Instance.Save ();
 			} catch (Exception e) {
Index: binary-improvements/7dtd-server-fixes/src/Version.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/Version.cs	(revision 224)
+++ binary-improvements/7dtd-server-fixes/src/Version.cs	(revision 224)
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class Version : ConsoleCommand
+	{
+		public Version (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "get the currently running version of the server fixes and loaded mods";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "version", string.Empty };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				m_Console.SendResult ("Versions:");
+				m_Console.SendResult ("Server fixes: " + Assembly.GetExecutingAssembly ().GetName ().Version);
+				foreach (Mods.ModData md in Mods.LoadedMods ()) {
+					m_Console.SendResult ("Mod " + md.name + ": " + md.version);
+				}
+			} catch (Exception e) {
+				Log.Out ("Error in Version.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/API.cs
===================================================================
--- binary-improvements/AllocsCommands/API.cs	(revision 224)
+++ binary-improvements/AllocsCommands/API.cs	(revision 224)
@@ -0,0 +1,15 @@
+using System;
+
+namespace AllocsCommands
+{
+	public class API : AllocsFixes.ModAPI {
+		public override string ModName () {
+			return "AllocsCommands";
+		}
+
+		public override string ModVersion () {
+			return "1.0 for A11";
+		}
+	}
+}
+
Index: binary-improvements/AllocsCommands/AllocsCommands.csproj
===================================================================
--- binary-improvements/AllocsCommands/AllocsCommands.csproj	(revision 224)
+++ binary-improvements/AllocsCommands/AllocsCommands.csproj	(revision 224)
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E273D042-57F9-4E2E-8268-5053527E5287}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>AllocsCommands</RootNamespace>
+    <AssemblyName>AllocsCommands</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Mods\AllocsCommands\</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="Assembly-CSharp">
+      <HintPath>..\7dtd-binaries\Assembly-CSharp.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="UnityEngine">
+      <HintPath>..\7dtd-binaries\UnityEngine.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="LogLibrary">
+      <HintPath>..\7dtd-binaries\LogLibrary.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="mscorlib">
+      <HintPath>..\7dtd-binaries\mscorlib.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="Commands\GetGamePrefs.cs" />
+    <Compile Include="Commands\GetTime.cs" />
+    <Compile Include="Commands\Give.cs" />
+    <Compile Include="Commands\Kill.cs" />
+    <Compile Include="Commands\ListItems.cs" />
+    <Compile Include="Commands\ListKnownPlayers.cs" />
+    <Compile Include="Commands\ListLandProtection.cs" />
+    <Compile Include="Commands\ListPlayerIds.cs" />
+    <Compile Include="Commands\PrivateMassageConnections.cs" />
+    <Compile Include="Commands\RemoveLandProtection.cs" />
+    <Compile Include="Commands\Reply.cs" />
+    <Compile Include="Commands\SayToPlayer.cs" />
+    <Compile Include="Commands\SetTimeReal.cs" />
+    <Compile Include="Commands\ShowInventory.cs" />
+    <Compile Include="Commands\TeleportPlayer.cs" />
+    <Compile Include="Commands\Unban.cs" />
+    <Compile Include="API.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\7dtd-server-fixes\7dtd-server-fixes.csproj">
+      <Project>{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}</Project>
+      <Name>7dtd-server-fixes</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Commands\" />
+  </ItemGroup>
+</Project>
Index: binary-improvements/AllocsCommands/AssemblyInfo.cs
===================================================================
--- binary-improvements/AllocsCommands/AssemblyInfo.cs	(revision 224)
+++ binary-improvements/AllocsCommands/AssemblyInfo.cs	(revision 224)
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("AllocsCommands")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("ci")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
Index: binary-improvements/AllocsCommands/Commands/GetGamePrefs.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/GetGamePrefs.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/GetGamePrefs.cs	(revision 224)
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class GetGamePrefs : ConsoleCommand
+	{
+		private string[] forbiddenPrefs = new string[] {
+			"telnet",
+			"adminfilename",
+			"controlpanel",
+			"password",
+			"savegamefolder",
+			"options",
+			"last"
+		};
+
+		private bool prefAccessAllowed (EnumGamePrefs gp)
+		{
+			string gpName = gp.ToString ().ToLower ();
+			foreach (string s in forbiddenPrefs) {
+				if (gpName.Contains (s)) {
+					return false;
+				}
+			}
+			return true;
+		}
+
+		public GetGamePrefs (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "gets a game pref";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[]
+		{
+			"getgamepref",
+			"gg"
+		};
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				EnumGamePrefs enumGamePrefs = EnumGamePrefs.Last;
+
+				if (_params.Length > 0) {
+					try {
+						enumGamePrefs = (EnumGamePrefs)((int)Enum.Parse (typeof(EnumGamePrefs), _params [0]));
+					} catch (Exception) {
+					}
+				}
+
+				if (enumGamePrefs == EnumGamePrefs.Last) {
+					SortedList<string, string> sortedList = new SortedList<string, string> ();
+					foreach (EnumGamePrefs gp in Enum.GetValues(typeof(EnumGamePrefs))) {
+						if ((_params.Length == 0) || (gp.ToString ().ToLower ().Contains (_params [0].ToLower ()))) {
+							if (prefAccessAllowed (gp)) {
+								sortedList.Add (gp.ToString (), string.Format ("{0} = {1}", gp.ToString (), GamePrefs.GetObject (gp)));
+							}
+						}
+					}
+					foreach (string s in sortedList.Keys) {
+						m_Console.SendResult (sortedList [s]);
+					}
+				} else {
+					if (prefAccessAllowed (enumGamePrefs))
+						m_Console.SendResult (string.Format ("{0} = {1}", enumGamePrefs, GamePrefs.GetObject (enumGamePrefs)));
+					else
+						m_Console.SendResult ("Access to requested preference is forbidden");
+				}
+			} catch (Exception e) {
+				Log.Out ("Error in GetGamePrefs.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/GetTime.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/GetTime.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/GetTime.cs	(revision 224)
@@ -0,0 +1,38 @@
+using System;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class GetTime : ConsoleCommand
+	{
+		public GetTime (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "retrieves current ingame time";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "gettime", "gt" };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				ulong time = CommonMappingFunctions.GetGameManager ().World.gameTime;
+				int day = (int)(time / 24000) + 1;
+				int hour = (int)(time % 24000) / 1000 + 8;
+				if (hour > 23) {
+					day++;
+					hour -= 24;
+				}
+				int min = (int)(time % 1000) * 60 / 1000;
+				m_Console.SendResult (String.Format ("Day {0}, {1:00}:{2:00} ", day, hour, min));
+			} catch (Exception e) {
+				Log.Out ("Error in GetTime.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/Give.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/Give.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/Give.cs	(revision 224)
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class Give : ConsoleCommand
+	{
+		public Give (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "give an item to a player (entity id or name)";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "give", string.Empty };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length != 3) {
+					m_Console.SendResult ("Usage: give <playername|entityid> <itemname> <amount>");
+					return;
+				}
+
+				ClientInfo ci = CommonMappingFunctions.GetClientInfoFromNameOrID (_params [0], false);
+
+				if (ci == null) {
+					m_Console.SendResult ("Playername or entity id not found.");
+					return;
+				}
+
+				ItemValue iv = ItemList.Instance.GetItemValue(_params[1]);
+				if (iv == null) {
+					m_Console.SendResult ("Item not found.");
+					return;
+				}
+
+				int n = int.MinValue;
+				if (!int.TryParse (_params [2], out n) || n <= 0) {
+					m_Console.SendResult ("Amount is not an integer or not greater than zero.");
+					return;
+				}
+
+				EntityPlayer p = CommonMappingFunctions.GetEntityPlayer (ci);
+
+				InventoryField invField = new InventoryField (iv, n);
+
+				CommonMappingFunctions.GetGameManager ().ItemDropServer (invField, p.GetPosition (), Vector3.zero, -1, 50);
+
+				m_Console.SendResult ("Dropped item");
+			} catch (Exception e) {
+				Log.Out ("Error in Give.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/Kill.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/Kill.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/Kill.cs	(revision 224)
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class Kill : ConsoleCommand
+	{
+		public Kill (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "kill a given player (entity id or name)";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "kill", string.Empty };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length != 1) {
+					m_Console.SendResult ("Usage: kill <playername|entityid>");
+					return;
+				}
+
+				ClientInfo ci = CommonMappingFunctions.GetClientInfoFromNameOrID (_params [0], false);
+
+				if (ci == null) {
+					m_Console.SendResult ("Playername or entity id not found.");
+					return;
+				}
+
+				EntityPlayer p = CommonMappingFunctions.GetEntityPlayer (ci);
+				p.DamageEntity (new DamageSource (EnumDamageSourceType.Bullet), 9999, false);
+				m_Console.SendResult ("Killed player " + _params [0]);
+			} catch (Exception e) {
+				Log.Out ("Error in Kill.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/ListItems.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/ListItems.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/ListItems.cs	(revision 224)
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class ListItems : ConsoleCommand
+	{
+		public ListItems (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "lists all items that contain the given substring";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "listitems", "li" };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length != 1 || _params [0].Length == 0) {
+					m_Console.SendResult ("Usage: listitems <searchString>");
+					return;
+				}
+
+				int n = 0;
+				foreach (string s in ItemList.Instance.ItemNames) {
+					if (s.ToLower ().Contains (_params [0].ToLower ())) {
+						m_Console.SendResult ("    " + s);
+						n++;
+					}
+				}
+
+				m_Console.SendResult ("Listed " + n + " matching items.");
+			} catch (Exception e) {
+				Log.Out ("Error in ListItems.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/ListKnownPlayers.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/ListKnownPlayers.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/ListKnownPlayers.cs	(revision 224)
@@ -0,0 +1,64 @@
+using AllocsFixes.PersistentData;
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class ListKnownPlayers : ConsoleCommand
+	{
+		public ListKnownPlayers (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "lists all players that were ever online (optionally filtered)";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "listknownplayers", "lkp" };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				AdminTools admTools = CommonMappingFunctions.GetGameManager ().adminTools;
+
+				bool onlineOnly = false;
+				bool notBannedOnly = false;
+				string nameFilter = string.Empty;
+
+				if (_params.Length == 1) {
+					if (_params [0].ToLower ().Equals ("-online")) {
+						onlineOnly = true;
+					} else if (_params [0].ToLower ().Equals ("-notbanned")) {
+						notBannedOnly = true;
+					} else {
+						nameFilter = _params [0].ToLower ();
+					}
+				}
+
+				int num = 0;
+				foreach (string sid in PersistentContainer.Instance.Players.SteamIDs) {
+					Player p = PersistentContainer.Instance.Players [sid];
+
+					if (
+						(!onlineOnly || p.IsOnline)
+						&& (!notBannedOnly || !admTools.IsBanned (sid))
+						&& (nameFilter.Length == 0 || p.Name.ToLower ().Contains (nameFilter))
+					) {
+						m_Console.SendResult (String.Format ("{0}. {1}, id={2}, steamid={3}, online={4}, ip={5}, playtime={6} m, seen={7}",
+						                                    ++num, p.Name, p.EntityID, sid, p.IsOnline, p.IP,
+						                                    p.TotalPlayTime / 60,
+						                                    p.LastOnline.ToString ("yyyy-MM-dd HH:mm"))
+						);
+					}
+				}
+				m_Console.SendResult ("Total of " + PersistentContainer.Instance.Players.Count + " known");
+			} catch (Exception e) {
+				Log.Out ("Error in ListKnownPlayers.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/ListLandProtection.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/ListLandProtection.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/ListLandProtection.cs	(revision 224)
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class ListLandProtection : ConsoleCommand
+	{
+		public ListLandProtection (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "lists all land protection blocks and owners";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "listlandprotection", "llp" };
+		}
+
+		public override void ExecuteRemote (string _sender, string[] _params)
+		{
+			try {
+				if (_params.Length >= 1 && _params [0].ToLower ().Equals ("nearby")) {
+					string[] params2 = new string[_params.Length + 1];
+					for (int i = 0; i < _params.Length; i++)
+						params2 [i] = _params [i];
+					params2 [_params.Length] = _sender;
+					_params = params2;
+				}
+				Run (_params);
+			} catch (Exception e) {
+				Log.Out ("Error in ListLandProtection.ExecuteRemote: " + e);
+			}
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				World w = CommonMappingFunctions.GetGameManager ().World;
+				PersistentPlayerList ppl = CommonMappingFunctions.GetGameManager ().GetPersistentPlayerList ();
+
+				bool summaryOnly = false;
+				string steamIdFilter = string.Empty;
+				Vector3i closeTo = default(Vector3i);
+				bool onlyCloseToPlayer = false;
+				int closeToDistance = 32;
+
+				if (_params.Length == 1) {
+					long tempLong;
+
+					if (_params [0].ToLower ().Equals ("summary")) {
+						summaryOnly = true;
+					} else if (_params [0].Length == 17 && long.TryParse (_params [0], out tempLong)) {
+						steamIdFilter = _params [0];
+					} else {
+						ClientInfo ci = CommonMappingFunctions.GetClientInfoFromNameOrID (_params [0], true);
+						if (ci != null) {
+							steamIdFilter = CommonMappingFunctions.GetSteamID (ci);
+						} else {
+							m_Console.SendResult ("Player name or entity id \"" + _params [0] + "\" not found.");
+							return;
+						}
+					}
+				} else if (_params.Length >= 2) {
+					if (_params [0].ToLower ().Equals ("nearby")) {
+						try {
+							if (_params.Length == 3) {
+								if (!int.TryParse (_params[1], out closeToDistance)) {
+									m_Console.SendResult ("Given radius is not an integer!");
+								}
+							}
+							ClientInfo ci = CommonMappingFunctions.GetClientInfoFromSteamID (_params [_params.Length - 1]);
+							EntityPlayer ep = CommonMappingFunctions.GetEntityPlayer (ci);
+							closeTo = new Vector3i (ep.GetPosition ());
+							onlyCloseToPlayer = true;
+						} catch (Exception e) {
+							m_Console.SendResult ("Error getting current player's position");
+							Log.Out ("Error in ListLandProtection.Run: " + e);
+						}
+					} else {
+						m_Console.SendResult ("Illegal parameter list");
+						return;
+					}
+				}
+
+				Dictionary<Vector3i, PersistentPlayerData> d = ppl.positionToLPBlockOwner;
+				if (d != null) {
+					Dictionary<PersistentPlayerData, List<Vector3i>> owners = new Dictionary<PersistentPlayerData, List<Vector3i>> ();
+					foreach (KeyValuePair<Vector3i, PersistentPlayerData> kvp in d) {
+						if (!onlyCloseToPlayer || (Math.Abs (kvp.Key.x - closeTo.x) <= closeToDistance && Math.Abs (kvp.Key.z - closeTo.z) <= closeToDistance)) {
+							if (!owners.ContainsKey (kvp.Value)) {
+								owners.Add (kvp.Value, new List<Vector3i> ());
+							}
+							owners [kvp.Value].Add (kvp.Key);
+						}
+					}
+
+					foreach (KeyValuePair<PersistentPlayerData, List<Vector3i>> kvp in owners) {
+						if (steamIdFilter.Length == 0 || kvp.Key.PlayerId.Equals (steamIdFilter)) {
+							string name = PersistentData.PersistentContainer.Instance.Players [kvp.Key.PlayerId].Name;
+							name += " (" + kvp.Key.PlayerId + ")";
+
+							m_Console.SendResult (String.Format ("Player \"{0}\" owns {3} keystones (protected: {1}, current hardness multiplier: {2})", name, w.LandClaimIsActive (kvp.Key), w.LandClaimPower (kvp.Key), kvp.Value.Count));
+							if (!summaryOnly) {
+								foreach (Vector3i v in kvp.Value) {
+									m_Console.SendResult ("   (" + v.ToString () + ")");
+								}
+							}
+						}
+					}
+				}
+
+				if (steamIdFilter.Length == 0)
+					m_Console.SendResult ("Total of " + d.Count + " keystones in the game");
+			} catch (Exception e) {
+				Log.Out ("Error in ListLandProtection.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/ListPlayerIds.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/ListPlayerIds.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/ListPlayerIds.cs	(revision 224)
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class ListPlayerIds : ConsoleCommand
+	{
+		public ListPlayerIds (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "lists all players with their IDs for ingame commands";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "listplayerids", "lpi" };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				World w = CommonMappingFunctions.GetGameManager ().World;
+				int num = 0;
+				foreach (KeyValuePair<int, EntityPlayer> current in w.Players.dict) {
+					m_Console.SendResult (string.Concat (new object[]
+						{
+							string.Empty,
+							++num,
+							". id=",
+							current.Value.entityId,
+							", ",
+							current.Value.EntityName,
+						}
+					)
+					);
+				}
+				m_Console.SendResult ("Total of " + w.Players.list.Count + " in the game");
+			} catch (Exception e) {
+				Log.Out ("Error in ListPlayerIds.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/PrivateMassageConnections.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/PrivateMassageConnections.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/PrivateMassageConnections.cs	(revision 224)
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class PrivateMassageConnections
+	{
+		private static Dictionary<ClientInfo, ClientInfo> senderOfLastPM = new Dictionary<ClientInfo, ClientInfo> ();
+
+		public static void SetLastPMSender (ClientInfo _sender, ClientInfo _receiver)
+		{
+			if (senderOfLastPM.ContainsKey (_receiver))
+				senderOfLastPM [_receiver] = _sender;
+			else
+				senderOfLastPM.Add (_receiver, _sender);
+		}
+
+		public static ClientInfo GetLastPMSenderForPlayer (ClientInfo _player)
+		{
+			if (senderOfLastPM.ContainsKey (_player))
+				return senderOfLastPM [_player];
+			return null;
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/RemoveLandProtection.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/RemoveLandProtection.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/RemoveLandProtection.cs	(revision 224)
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class RemoveLandProtection : ConsoleCommand
+	{
+		public RemoveLandProtection (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "removes the association of a land protection block to the owner";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "removelandprotection", "rlp" };
+		}
+
+		private void removeById (string _id)
+		{
+			try {
+				PersistentPlayerList ppl = CommonMappingFunctions.GetGameManager ().GetPersistentPlayerList ();
+
+				if (_id.Length < 1 || !ppl.Players.ContainsKey (_id)) {
+					m_Console.SendResult ("Not a valid Steam ID or user has never logged on. Use \"listlandprotection\" to get a list of keystones.");
+					return;
+				}
+				if (ppl.Players [_id].LPBlocks == null || ppl.Players [_id].LPBlocks.Count == 0) {
+					m_Console.SendResult ("Player does not own any keystones. Use \"listlandprotection\" to get a list of keystones.");
+					return;
+				}
+
+				List<BlockChangeInfo> changes = new List<BlockChangeInfo> ();
+				foreach (Vector3i pos in ppl.Players[_id].LPBlocks) {
+					BlockChangeInfo bci = new BlockChangeInfo (pos, 0, true);
+					changes.Add (bci);
+				}
+				CommonMappingFunctions.GetGameManager ().SetBlocksRPC (changes);
+
+				m_Console.SendResult ("Tried to remove #" + changes.Count + " land protection blocks for player \"" + _id + "\". Note "+
+				                      "that only blocks in chunks that are currently loaded (close to any player) could be removed. "+
+				                      "Please check for remaining blocks by running:");
+				m_Console.SendResult("  listlandprotection " + _id);
+			} catch (Exception e) {
+				Log.Out ("Error in RemoveLandProtection.removeById: " + e);
+			}
+		}
+
+		private void removeByPosition (string[] _coords)
+		{
+			try {
+				int x = int.MinValue;
+				int.TryParse (_coords [0], out x);
+				int y = int.MinValue;
+				int.TryParse (_coords [1], out y);
+				int z = int.MinValue;
+				int.TryParse (_coords [2], out z);
+
+				if (x == int.MinValue || y == int.MinValue || z == int.MinValue) {
+					m_Console.SendResult ("At least one of the given coordinates is not a valid integer");
+					return;
+				}
+
+				Vector3i v = new Vector3i (x, y, z);
+
+				PersistentPlayerList ppl = CommonMappingFunctions.GetGameManager ().GetPersistentPlayerList ();
+
+				Dictionary<Vector3i, PersistentPlayerData> d = ppl.positionToLPBlockOwner;
+				if (d == null || !d.ContainsKey (v)) {
+					m_Console.SendResult ("No land protection block at the given position or not a valid position. Use \"listlandprotection\" to get a list of keystones.");
+					return;
+				}
+
+				BlockChangeInfo bci = new BlockChangeInfo (v, 0, true);
+
+				List<BlockChangeInfo> changes = new List<BlockChangeInfo> ();
+				changes.Add (bci);
+
+				CommonMappingFunctions.GetGameManager ().SetBlocksRPC (changes);
+
+				m_Console.SendResult ("Land protection block at (" + v.ToString () + ") removed");
+			} catch (Exception e) {
+				Log.Out ("Error in RemoveLandProtection.removeByPosition: " + e);
+			}
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length == 1) {
+					removeById (_params [0]);
+				} else if (_params.Length == 3) {
+					removeByPosition (_params);
+				} else {
+					m_Console.SendResult ("Usage: removelandprotection <x> <y> <z>  OR  removelandprotection <steamid>");
+				}
+			} catch (Exception e) {
+				Log.Out ("Error in RemoveLandProtection.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/Reply.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/Reply.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/Reply.cs	(revision 224)
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class Reply : ConsoleCommand
+	{
+		public Reply (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "send a message to  the player who last sent you a PM";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "reply", "re" };
+		}
+
+		private void SendMessage (ClientInfo _receiver, ClientInfo _sender, string _message)
+		{
+			PrivateMassageConnections.SetLastPMSender (_sender, _receiver);
+			string senderName = CommonMappingFunctions.GetPlayerName (_sender);
+
+			_receiver.netConnection [0].AddToSendQueue (new NetPackage_GameInfoMessage (_message, senderName + " (PM)"));
+			string receiverName = CommonMappingFunctions.GetPlayerName (_receiver);
+			m_Console.SendResult ("Message to player " + (receiverName != null ? "\"" + receiverName + "\"" : "unknownName") + " sent with sender \"" + senderName + "\"");
+		}
+
+		private void RunInternal (ClientInfo _sender, string[] _params)
+		{
+			if (_params.Length < 1) {
+				m_Console.SendResult ("Usage: reply <message>");
+				return;
+			}
+
+			string message = _params [0];
+			for (int i = 1; i < _params.Length; i++) {
+				message += " " + _params [i];
+			}
+
+			ClientInfo receiver = PrivateMassageConnections.GetLastPMSenderForPlayer (_sender);
+			if (receiver != null && CommonMappingFunctions.GetClientID (receiver) >= 0) {
+				SendMessage (receiver, _sender, message);
+			} else {
+				if (receiver != null) {
+					m_Console.SendResult ("The sender of the PM you last received is currently not online.");
+				} else {
+					m_Console.SendResult ("You have not received a PM so far.");
+				}
+			}
+		}
+
+		public override void ExecuteRemote (string _sender, string[] _params)
+		{
+			try {
+				m_Console.SendResult (string.Format ("{0} executing remote command '{1}' {2}", _sender, this.Names () [0], string.Join (" ", _params)));
+				ClientInfo ci = CommonMappingFunctions.GetClientInfoFromSteamID (_sender);
+				RunInternal (ci, _params);
+			} catch (Exception e) {
+				Log.Out ("Error in Reply.ExecuteRemote: " + e);
+			}
+		}
+
+		public override void Run (string[] _params)
+		{
+			Log.Out ("Command \"reply\" can only be used on clients!");
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/SayToPlayer.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/SayToPlayer.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/SayToPlayer.cs	(revision 224)
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class SayToPlayer : ConsoleCommand
+	{
+		public SayToPlayer (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "send a message to a single player";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "sayplayer", "pm" };
+		}
+
+		private void SendMessage (ClientInfo _receiver, ClientInfo _sender, string _message)
+		{
+			string senderName;
+			if (_sender != null) {
+				PrivateMassageConnections.SetLastPMSender (_sender, _receiver);
+				senderName = CommonMappingFunctions.GetPlayerName (_sender);
+			} else {
+				senderName = "Server";
+			}
+			ConnectionManager.Instance.SendPackage (new NetPackage_GameInfoMessage (_message, senderName + " (PM)"), new PackageDestinationSingleEntityID (_receiver.entityId));
+			string receiverName = CommonMappingFunctions.GetPlayerName (_receiver);
+			m_Console.SendResult ("Message to player " + (receiverName != null ? "\"" + receiverName + "\"" : "unknownName") + " sent with sender \"" + senderName + "\"");
+		}
+
+		private void RunInternal (ClientInfo _sender, string[] _params)
+		{
+			if (_params.Length < 2) {
+				m_Console.SendResult ("Usage: sayplayer <playername|entityid> <message>");
+				return;
+			}
+
+			string message = _params [1];
+			for (int i = 2; i < _params.Length; i++) {
+				message += " " + _params [i];
+			}
+
+			ClientInfo receiver = CommonMappingFunctions.GetClientInfoFromNameOrID (_params [0], true);
+			if (receiver != null) {
+				SendMessage (receiver, _sender, message);
+			} else {
+				m_Console.SendResult ("Playername or entity ID not found.");
+			}
+		}
+
+		public override void ExecuteRemote (string _sender, string[] _params)
+		{
+			try {
+				this.m_Console.SendResult (string.Format ("{0} executing remote command '{1}' {2}", _sender, this.Names () [0], string.Join (" ", _params)));
+				ClientInfo ci = CommonMappingFunctions.GetClientInfoFromSteamID (_sender);
+				RunInternal (ci, _params);
+			} catch (Exception e) {
+				Log.Out ("Error in SayToPlayer.ExecuteRemote: " + e);
+			}
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				RunInternal (null, _params);
+			} catch (Exception e) {
+				Log.Out ("Error in SayToPlayer.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/SetTimeReal.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/SetTimeReal.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/SetTimeReal.cs	(revision 224)
@@ -0,0 +1,67 @@
+using System;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class SetTimeReal : ConsoleCommand
+	{
+		public SetTimeReal (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "set current ingame time, params: <day> <hour> <min>";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "settimereal", "str" };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length != 3) {
+					m_Console.SendResult ("Usage: settimereal <day> <hour> <min>");
+					return;
+				}
+
+				int day, hour, min;
+				if (!int.TryParse (_params [0], out day)) {
+					m_Console.SendResult ("Could not parse day number \"" + _params [0] + "\"");
+					return;
+				}
+				if (day < 1) {
+					m_Console.SendResult ("Day must be >= 1");
+					return;
+				}
+				if (!int.TryParse (_params [1], out hour)) {
+					m_Console.SendResult ("Could not parse hour \"" + _params [1] + "\"");
+					return;
+				}
+				if (hour > 23) {
+					m_Console.SendResult ("Hour must be <= 23");
+					return;
+				}
+				if (!int.TryParse (_params [2], out min)) {
+					m_Console.SendResult ("Could not parse minute \"" + _params [2] + "\"");
+					return;
+				}
+				if (min > 59) {
+					m_Console.SendResult ("Minute must be <= 59");
+					return;
+				}
+				if ((day < 1) || (hour < 8 && day < 1)) {
+					m_Console.SendResult ("Time may not be prior to day 1, 8:00");
+					return;
+				}
+
+				ulong time = ((ulong)(day - 1) * 24000) + ((ulong)hour * 1000) + ((ulong)min * 1000 / 60) - 8000;
+				CommonMappingFunctions.GetGameManager ().World.gameTime = time;
+				m_Console.SendResult (String.Format ("Set time to Day {0}, {1:00}:{2:00} = {3}", day, hour, min, time));
+			} catch (Exception e) {
+				Log.Out ("Error in SetTimeReal.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/ShowInventory.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/ShowInventory.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/ShowInventory.cs	(revision 224)
@@ -0,0 +1,57 @@
+using AllocsFixes.PersistentData;
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class ShowInventory : ConsoleCommand
+	{
+		public ShowInventory (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "list inventory of a given player (steam id, entity id or name)";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "showinventory", "si" };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length < 1) {
+					m_Console.SendResult ("Usage: showinventory <steamid|playername|entityid>");
+					return;
+				}
+
+				string steamid = PersistentContainer.Instance.Players.GetSteamID (_params [0], true);
+				if (steamid == null) {
+					m_Console.SendResult ("Playername or entity/steamid id not found or no inventory saved (first saved after a player has been online for 30s).");
+					return;
+				}
+
+				Player p = PersistentContainer.Instance.Players [steamid];
+				PersistentData.Inventory inv = p.Inventory;
+
+				m_Console.SendResult ("Belt of player " + p.Name + ":");
+				for (int i = 0; i < inv.belt.Count; i++) {
+					if (inv.belt [i] != null)
+						m_Console.SendResult (string.Format ("    Slot {0}: {1:000} * {2}", i, inv.belt [i].count, inv.belt [i].itemName));
+				}
+				m_Console.SendResult (string.Empty);
+				m_Console.SendResult ("Bagpack of player " + p.Name + ":");
+				for (int i = 0; i < inv.bag.Count; i++) {
+					if (inv.bag [i] != null)
+						m_Console.SendResult (string.Format ("    Slot {0}: {1:000} * {2}", i, inv.bag [i].count, inv.bag [i].itemName));
+				}
+				m_Console.SendResult (string.Empty);
+			} catch (Exception e) {
+				Log.Out ("Error in ShowInventory.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/TeleportPlayer.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/TeleportPlayer.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/TeleportPlayer.cs	(revision 224)
@@ -0,0 +1,97 @@
+using AllocsFixes.PersistentData;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class TeleportPlayer : ConsoleCommand
+	{
+		private MethodInfo NetConnection_SendPackage = null;
+
+		public TeleportPlayer (ConsoleSdtd cons) : base(cons)
+		{
+			Type typeClientInfo = Assembly.GetAssembly (typeof(ClientInfo)).GetType ("ClientInfo");
+			Type typeNetConnection = typeClientInfo.GetField ("netConnection").FieldType.GetElementType ();
+			MethodInfo[] mis = typeNetConnection.GetMethods ();
+			foreach (MethodInfo mi in mis) {
+				ParameterInfo[] pis = mi.GetParameters ();
+				if (pis.Length == 1) {
+					if (typeof (Package).Equals (pis[0].ParameterType)) {
+						NetConnection_SendPackage = mi;
+					}
+				}
+			}
+		}
+
+		public override string Description ()
+		{
+			return "teleport a player to a given location";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "teleportplayer", "tele" };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length != 4 && _params.Length != 2) {
+					m_Console.SendResult ("Usage: teleportplayer <entityid|playername|steamid> <x> <y> <z>");
+					m_Console.SendResult ("   or: teleportplayer <entityid|playername|steamid> <target entityid|playername|steamid>");
+				} else {
+					Player p1 = PersistentContainer.Instance.Players.GetPlayerByNameOrId (_params [0], true);
+					if (p1 == null) {
+						m_Console.SendResult ("Playername or entity/steamid id not found.");
+						return;
+					}
+					if (!p1.IsOnline) {
+						m_Console.SendResult ("Player not online.");
+						return;
+					}
+
+					if (_params.Length == 4) {
+						int x = int.MinValue;
+						int y = int.MinValue;
+						int z = int.MinValue;
+
+						int.TryParse (_params [1], out x);
+						int.TryParse (_params [2], out y);
+						int.TryParse (_params [3], out z);
+
+						if (x == int.MinValue || y == int.MinValue || z == int.MinValue) {
+							m_Console.SendResult ("At least one of the given coordinates is not a valid integer");
+							return;
+						}
+
+						p1.Entity.position.x = x;
+						p1.Entity.position.y = y;
+						p1.Entity.position.z = z;
+					} else {
+						Player p2 = PersistentContainer.Instance.Players.GetPlayerByNameOrId (_params [1], true);
+						if (p2 == null) {
+							m_Console.SendResult ("Target playername or entity/steamid id not found.");
+							return;
+						}
+						if (!p2.IsOnline) {
+							m_Console.SendResult ("Target player not online.");
+							return;
+						}
+
+						p1.Entity.position = p2.Entity.GetPosition();
+					}
+
+					NetPackage_EntityPosAndRot pkg = new NetPackage_EntityPosAndRot (p1.Entity);
+
+					if (NetConnection_SendPackage != null) {
+						NetConnection_SendPackage.Invoke (p1.ClientInfo.netConnection [0], new object[] {pkg});
+					}
+				}
+			} catch (Exception e) {
+				Log.Out ("Error in TeleportPlayer.Run: " + e);
+			}
+		}
+
+	}
+}
Index: binary-improvements/AllocsCommands/Commands/Unban.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/Unban.cs	(revision 224)
+++ binary-improvements/AllocsCommands/Commands/Unban.cs	(revision 224)
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class Unban : ConsoleCommand
+	{
+		public Unban (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "unban a player";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "unban", string.Empty };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length != 1) {
+					m_Console.SendResult ("Usage: unban <steamid>");
+					return;
+				}
+
+				long tempLong;
+				if (_params [0].Length != 17 || !long.TryParse (_params [0], out tempLong)) {
+					m_Console.SendResult ("Not a valid Steam ID.");
+					return;
+				}
+
+				AdminTools at = CommonMappingFunctions.GetGameManager ().adminTools;
+				if (!at.IsBanned (_params [0])) {
+					m_Console.SendResult ("Steam ID is not banned.");
+					return;
+				}
+
+				at.RemoveBan (_params [0]);
+				m_Console.SendResult ("Removed ban for Steam ID " + _params [0]);
+			} catch (Exception e) {
+				Log.Out ("Error in Unban.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/MapRendering/API.cs
===================================================================
--- binary-improvements/MapRendering/API.cs	(revision 224)
+++ binary-improvements/MapRendering/API.cs	(revision 224)
@@ -0,0 +1,19 @@
+using System;
+
+namespace MapRendering
+{
+	public class API : AllocsFixes.ModAPI {
+		public override string ModName () {
+			return "AllocsMapRendering";
+		}
+
+		public override string ModVersion () {
+			return "1.0 for A11";
+		}
+
+		public override void CalcMapColors (Chunk _chunk) {
+			AllocsFixes.MapRendering.MapRendering.RenderSingleChunk (_chunk);
+		}
+	}
+}
+
Index: binary-improvements/MapRendering/AssemblyInfo.cs
===================================================================
--- binary-improvements/MapRendering/AssemblyInfo.cs	(revision 224)
+++ binary-improvements/MapRendering/AssemblyInfo.cs	(revision 224)
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("MapRendering")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("ci")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
Index: binary-improvements/MapRendering/Commands/EnableRendering.cs
===================================================================
--- binary-improvements/MapRendering/Commands/EnableRendering.cs	(revision 224)
+++ binary-improvements/MapRendering/Commands/EnableRendering.cs	(revision 224)
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class EnableRendering : ConsoleCommand
+	{
+		public EnableRendering (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "enable/disable live map rendering";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "enablerendering", string.Empty };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				if (_params.Length != 1) {
+					m_Console.SendResult ("Current state: " + AllocsFixes.MapRendering.MapRendering.renderingEnabled);
+					return;
+				}
+
+				AllocsFixes.MapRendering.MapRendering.renderingEnabled = _params[0].Equals("1");
+				m_Console.SendResult ("Set live map rendering to " + _params [0].Equals ("1"));
+			} catch (Exception e) {
+				Log.Out ("Error in EnableRendering.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/MapRendering/Commands/RenderMap.cs
===================================================================
--- binary-improvements/MapRendering/Commands/RenderMap.cs	(revision 224)
+++ binary-improvements/MapRendering/Commands/RenderMap.cs	(revision 224)
@@ -0,0 +1,35 @@
+using AllocsFixes.MapRendering;
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class RenderMap : ConsoleCommand
+	{
+		public RenderMap (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "render the current map to a file";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "rendermap", "rm" };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				AllocsFixes.MapRendering.MapRendering.Instance.RenderFullMap ();
+
+				m_Console.SendResult ("Render map done");
+			} catch (Exception e) {
+				Log.Out ("Error in RenderMap.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/MapRendering/MapRendering.csproj
===================================================================
--- binary-improvements/MapRendering/MapRendering.csproj	(revision 224)
+++ binary-improvements/MapRendering/MapRendering.csproj	(revision 224)
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A1847B5F-7BFC-4BCD-94AA-A6C9FB7E7C54}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>MapRendering</RootNamespace>
+    <AssemblyName>MapRendering</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Mods\AllocsMapRendering\</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="LogLibrary">
+      <HintPath>..\7dtd-binaries\LogLibrary.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="UnityEngine">
+      <HintPath>..\7dtd-binaries\UnityEngine.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Assembly-CSharp">
+      <HintPath>..\7dtd-binaries\Assembly-CSharp.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="mscorlib">
+      <HintPath>..\7dtd-binaries\mscorlib.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="MapRendering\MapRendering.cs" />
+    <Compile Include="MapRendering\MapRenderBlockBuffer.cs" />
+    <Compile Include="MapRendering\Constants.cs" />
+    <Compile Include="Commands\RenderMap.cs" />
+    <Compile Include="Commands\EnableRendering.cs" />
+    <Compile Include="API.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\7dtd-server-fixes\7dtd-server-fixes.csproj">
+      <Project>{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}</Project>
+      <Name>7dtd-server-fixes</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Commands\" />
+  </ItemGroup>
+</Project>
Index: binary-improvements/MapRendering/MapRendering/Constants.cs
===================================================================
--- binary-improvements/MapRendering/MapRendering/Constants.cs	(revision 224)
+++ binary-improvements/MapRendering/MapRendering/Constants.cs	(revision 224)
@@ -0,0 +1,16 @@
+using System;
+
+namespace AllocsFixes.MapRendering
+{
+	public class Constants
+	{
+		public static int MAP_BLOCK_SIZE = 128;
+		public static int MAP_CHUNK_SIZE = 16;
+		public static int MAP_REGION_SIZE = 512;
+		public static int MAP_BLOCK_TO_CHUNK_DIV { get { return MAP_BLOCK_SIZE / MAP_CHUNK_SIZE; } }
+		public static int MAP_REGION_TO_CHUNK_DIV { get { return MAP_REGION_SIZE / MAP_CHUNK_SIZE; } }
+		public static int ZOOMLEVELS = 5;
+		public static string MAP_DIRECTORY = string.Empty;
+	}
+}
+
Index: binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs
===================================================================
--- binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs	(revision 224)
+++ binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs	(revision 224)
@@ -0,0 +1,101 @@
+using System;
+using System.IO;
+using System.Threading;
+using UnityEngine;
+
+namespace AllocsFixes.MapRendering
+{
+	public class MapRenderBlockBuffer
+	{
+		private int zoomLevel;
+		private string currentBlockMap = string.Empty;
+		private Texture2D blockMap = new Texture2D (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
+		private Texture2D zoomBuffer = new Texture2D (1, 1);
+		private Color nullColor = new Color (0, 0, 0, 0);
+		private AllocsFixes.FileCache.MapTileCache cache;
+
+		public MapRenderBlockBuffer (int level, AllocsFixes.FileCache.MapTileCache cache)
+		{
+			zoomLevel = level;
+			this.cache = cache;
+		}
+
+		public void ResetBlock ()
+		{
+			currentBlockMap = string.Empty;
+		}
+
+		public void SaveBlock ()
+		{
+			try {
+				if (currentBlockMap.Length > 0)
+					saveTextureToFile (currentBlockMap);
+			} catch (Exception e) {
+				Log.Out ("Exception in MapRenderBlockBuffer.SaveBlock(): " + e);
+			}
+		}
+
+		public bool LoadBlock (Vector2i block)
+		{
+			bool res = false;
+			lock (blockMap) {
+				string folder = Constants.MAP_DIRECTORY + "/" + (zoomLevel) + "/" + block.x;
+				string fileName = folder + "/" + block.y + ".png";
+				Directory.CreateDirectory (folder);
+				if (!fileName.Equals (currentBlockMap)) {
+					res = true;
+					SaveBlock ();
+					loadTextureFromFile (fileName);
+				}
+				currentBlockMap = fileName;
+			}
+			return res;
+		}
+
+		public void SetPart (Vector2i offset, int partSize, Color[] pixels)
+		{
+			blockMap.SetPixels (offset.x, offset.y, partSize, partSize, pixels);
+		}
+
+		public Color[] GetHalfScaled ()
+		{
+			zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
+			zoomBuffer.SetPixels (blockMap.GetPixels ());
+
+			TextureScale.Point (zoomBuffer, Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2);
+
+			return zoomBuffer.GetPixels ();
+		}
+
+		private void loadTextureFromFile (string _fileName)
+		{
+			byte[] array = cache.LoadTile (zoomLevel, _fileName);
+			if (array != null) {
+				blockMap.LoadImage (array);
+			} else {
+				//try {
+				//byte[] array = File.ReadAllBytes (_fileName);
+				//blockMap.LoadImage (array);
+				//} catch (Exception) {
+				for (int x = 0; x < Constants.MAP_BLOCK_SIZE; x++) {
+					for (int y = 0; y < Constants.MAP_BLOCK_SIZE; y++) {
+						blockMap.SetPixel (x, y, nullColor);
+					}
+				}
+			}
+		}
+
+		private void saveTextureToFile (string _fileName)
+		{
+			byte[] array = blockMap.EncodeToPNG ();
+			cache.SaveTile (zoomLevel, array);
+//			try {
+//				byte[] array = blockMap.EncodeToPNG ();
+//				File.WriteAllBytes (_fileName, array);
+//			} catch (Exception e) {
+//				Log.Out ("Exception in MapRenderBlockBuffer.saveTextureToFile(): " + e);
+//			}
+		}
+
+	}
+}
Index: binary-improvements/MapRendering/MapRendering/MapRendering.cs
===================================================================
--- binary-improvements/MapRendering/MapRendering/MapRendering.cs	(revision 224)
+++ binary-improvements/MapRendering/MapRendering/MapRendering.cs	(revision 224)
@@ -0,0 +1,337 @@
+using AllocsFixes.JSON;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using UnityEngine;
+
+namespace AllocsFixes.MapRendering
+{
+	public class MapRendering
+	{
+		private static MapRendering instance;
+
+		public static MapRendering Instance {
+			get {
+				if (instance == null) {
+					instance = new MapRendering ();
+				}
+				return instance;
+			}
+		}
+
+		private static object lockObject = new object ();
+		private MapRenderBlockBuffer[] zoomLevelBuffers;
+		private Dictionary<Vector2i, Color[]> dirtyChunks = new Dictionary<Vector2i, Color[]> ();
+		private System.Timers.Timer chunkSaveTimer = new System.Timers.Timer (500);
+		private bool renderingFullMap = false;
+		public static bool renderingEnabled = true;
+		private MicroStopwatch msw = new MicroStopwatch ();
+		private AllocsFixes.FileCache.MapTileCache cache = new AllocsFixes.FileCache.MapTileCache ();
+
+		public static AllocsFixes.FileCache.MapTileCache GetTileCache() {
+			return Instance.cache;
+		}
+
+		private MapRendering ()
+		{
+			Constants.MAP_DIRECTORY = StaticDirectories.GetSaveGameDir () + "/map";
+
+			lock (lockObject) {
+				if (!LoadMapInfo ())
+					WriteMapInfo ();
+			}
+
+			cache.SetZoomCount (Constants.ZOOMLEVELS);
+
+			zoomLevelBuffers = new MapRenderBlockBuffer[Constants.ZOOMLEVELS];
+			for (int i = 0; i < Constants.ZOOMLEVELS; i++) {
+				zoomLevelBuffers [i] = new MapRenderBlockBuffer (i, cache);
+			}
+
+			chunkSaveTimer.AutoReset = false;
+			chunkSaveTimer.Elapsed += new System.Timers.ElapsedEventHandler (TimedRendering);
+		}
+
+		public static void RenderSingleChunk (Chunk chunk)
+		{
+			if (renderingEnabled) {
+				ThreadPool.QueueUserWorkItem ((o) =>
+				{
+					try {
+						if (!Instance.renderingFullMap) {
+							lock (lockObject) {
+								Chunk c = (Chunk)o;
+								Vector3i cPos = c.GetWorldPos ();
+								Vector2i cPos2 = new Vector2i (cPos.x / Constants.MAP_CHUNK_SIZE, cPos.z / Constants.MAP_CHUNK_SIZE);
+
+								ushort[] mapColors = c.GetMapColors ();
+								if (mapColors != null) {
+									Color[] realColors = new Color[Constants.MAP_CHUNK_SIZE * Constants.MAP_CHUNK_SIZE];
+									for (int i_colors = 0; i_colors < mapColors.Length; i_colors++) {
+										realColors [i_colors] = shortColorToColor (mapColors [i_colors]);
+									}
+									Instance.dirtyChunks [cPos2] = realColors;
+									//Log.Out ("Add Dirty: " + cPos2);
+									Instance.chunkSaveTimer.Stop ();
+									Instance.chunkSaveTimer.Start ();
+								}
+							}
+						}
+					} catch (Exception e) {
+						Log.Out ("Exception in MapRendering.RenderSingleChunk(): " + e);
+					}
+				}, chunk);
+			}
+		}
+
+		public void RenderFullMap ()
+		{
+			MicroStopwatch microStopwatch = new MicroStopwatch ();
+
+			string regionSaveDir = StaticDirectories.GetSaveGameRegionDir ();
+			RegionFileManager rfm = new RegionFileManager (regionSaveDir, regionSaveDir, 0, false);
+			Texture2D fullMapTexture = null;
+
+			Vector2i minChunk = default(Vector2i), maxChunk = default(Vector2i);
+			Vector2i minPos = default(Vector2i), maxPos = default(Vector2i);
+			int widthChunks, heightChunks, widthPix, heightPix;
+			getWorldExtent (rfm, out minChunk, out maxChunk, out minPos, out maxPos, out widthChunks, out heightChunks, out widthPix, out heightPix);
+
+			Log.Out (String.Format ("RenderMap: min: {0}, max: {1}, minPos: {2}, maxPos: {3}, w/h: {4}/{5}, wP/hP: {6}/{7}",
+			                        minChunk.ToString (), maxChunk.ToString (),
+			                        minPos.ToString (), maxPos.ToString (),
+			                        widthChunks, heightChunks,
+			                        widthPix, heightPix)
+			);
+
+			lock (lockObject) {
+				for (int i = 0; i < Constants.ZOOMLEVELS; i++) {
+					zoomLevelBuffers [i].ResetBlock ();
+				}
+
+				if (Directory.Exists (Constants.MAP_DIRECTORY)) {
+					Directory.Delete (Constants.MAP_DIRECTORY, true);
+				}
+				WriteMapInfo ();
+
+				renderingFullMap = true;
+
+				if (widthPix <= 8000 && heightPix <= 8000)
+					fullMapTexture = new Texture2D (widthPix, heightPix);
+
+				Vector2i curFullMapPos = default(Vector2i);
+				Vector2i curChunkPos = default(Vector2i);
+				for (curFullMapPos.x = 0; curFullMapPos.x < widthPix; curFullMapPos.x += Constants.MAP_CHUNK_SIZE) {
+					for (curFullMapPos.y = 0; curFullMapPos.y < heightPix; curFullMapPos.y += Constants.MAP_CHUNK_SIZE) {
+						curChunkPos.x = (curFullMapPos.x / Constants.MAP_CHUNK_SIZE) + minChunk.x;
+						curChunkPos.y = (curFullMapPos.y / Constants.MAP_CHUNK_SIZE) + minChunk.y;
+
+						try {
+							long chunkKey = WorldChunkCache.MakeChunkKey (curChunkPos.x, curChunkPos.y);
+							if (rfm.ContainsChunkSync (chunkKey)) {
+								Chunk c = rfm.GetChunkSync (chunkKey);
+								ushort[] mapColors = c.GetMapColors ();
+								if (mapColors != null) {
+									Color[] realColors = new Color[Constants.MAP_CHUNK_SIZE * Constants.MAP_CHUNK_SIZE];
+									for (int i_colors = 0; i_colors < mapColors.Length; i_colors++) {
+										realColors [i_colors] = shortColorToColor (mapColors [i_colors]);
+									}
+									dirtyChunks [curChunkPos] = realColors;
+									if (fullMapTexture != null)
+										fullMapTexture.SetPixels (curFullMapPos.x, curFullMapPos.y, Constants.MAP_CHUNK_SIZE, Constants.MAP_CHUNK_SIZE, realColors);
+								}
+							}
+						} catch (Exception e) {
+							Log.Out ("Exception: " + e);
+						}
+					}
+
+					while (dirtyChunks.Count > 0) {
+						RenderDirtyChunks ();
+					}
+
+					Log.Out (String.Format ("RenderMap: {0}/{1} ({2}%)", curFullMapPos.x, widthPix, (int)((float)curFullMapPos.x / widthPix * 100)));
+				}
+			}
+
+			if (fullMapTexture != null) {
+				byte[] array = fullMapTexture.EncodeToPNG ();
+				File.WriteAllBytes (Constants.MAP_DIRECTORY + "/map.png", array);
+				Texture2D.Destroy (fullMapTexture);
+				fullMapTexture = null;
+			}
+
+			renderingFullMap = false;
+
+			Log.Out ("Generating map took: " + microStopwatch.ElapsedMilliseconds + " ms");
+			Log.Out ("World extent: " + minPos + " - " + maxPos);
+		}
+
+		private void SaveAllBlockMaps (object source, System.Timers.ElapsedEventArgs e)
+		{
+			for (int i = 0; i < Constants.ZOOMLEVELS; i++) {
+				zoomLevelBuffers [i].SaveBlock ();
+			}
+		}
+
+		private void TimedRendering (object source, System.Timers.ElapsedEventArgs e)
+		{
+			lock (lockObject) {
+				RenderDirtyChunks ();
+				if (dirtyChunks.Count > 0)
+					Instance.chunkSaveTimer.Start ();
+			}
+		}
+
+		private void RenderDirtyChunks ()
+		{
+			msw.ResetAndRestart ();
+
+			if (dirtyChunks.Count > 0) {
+				List<Vector2i> keys = new List<Vector2i> (dirtyChunks.Keys);
+				List<Vector2i> chunksDone = new List<Vector2i> ();
+
+				Vector2i chunkPos = keys [0];
+				chunksDone.Add (chunkPos);
+
+				//Log.Out ("Start Dirty: " + chunkPos);
+
+				Vector2i block = default(Vector2i), blockOffset = default(Vector2i);
+				getBlockNumber (chunkPos, out block, out blockOffset, Constants.MAP_BLOCK_TO_CHUNK_DIV, Constants.MAP_CHUNK_SIZE);
+
+				zoomLevelBuffers [Constants.ZOOMLEVELS - 1].LoadBlock (block);
+
+				Vector2i v_block = default(Vector2i), v_blockOffset = default(Vector2i);
+				foreach (Vector2i v in keys) {
+					getBlockNumber (v, out v_block, out v_blockOffset, Constants.MAP_BLOCK_TO_CHUNK_DIV, Constants.MAP_CHUNK_SIZE);
+					if (v_block.Equals (block)) {
+						//Log.Out ("Dirty: " + v + " render: true");
+						chunksDone.Add (v);
+						zoomLevelBuffers [Constants.ZOOMLEVELS - 1].SetPart (v_blockOffset, Constants.MAP_CHUNK_SIZE, dirtyChunks [v]);
+					} else {
+						//Log.Out ("Dirty: " + v + " render: false");
+					}
+				}
+
+				foreach (Vector2i v in chunksDone)
+					dirtyChunks.Remove (v);
+
+				RenderZoomLevel (Constants.ZOOMLEVELS - 1, block);
+
+				SaveAllBlockMaps (null, null);
+			}
+		}
+
+		private void RenderZoomLevel (int level, Vector2i innerBlock)
+		{
+			if (level > 0) {
+				Vector2i block = default(Vector2i), blockOffset = default(Vector2i);
+				getBlockNumber (innerBlock, out block, out blockOffset, 2, Constants.MAP_BLOCK_SIZE / 2);
+
+				zoomLevelBuffers [level - 1].LoadBlock (block);
+				zoomLevelBuffers [level - 1].SetPart (blockOffset, Constants.MAP_BLOCK_SIZE / 2, zoomLevelBuffers [level].GetHalfScaled ());
+
+				RenderZoomLevel (level - 1, block);
+			}
+		}
+
+		private void getBlockNumber (Vector2i innerPos, out Vector2i block, out Vector2i blockOffset, int scaleFactor, int offsetSize)
+		{
+			block = default(Vector2i);
+			blockOffset = default(Vector2i);
+			block.x = ((innerPos.x + 16777216) / scaleFactor) - (16777216 / scaleFactor);
+			block.y = ((innerPos.y + 16777216) / scaleFactor) - (16777216 / scaleFactor);
+			blockOffset.x = ((innerPos.x + 16777216) % scaleFactor) * offsetSize;
+			blockOffset.y = ((innerPos.y + 16777216) % scaleFactor) * offsetSize;
+		}
+
+		private void WriteMapInfo ()
+		{
+			JSONObject mapInfo = new JSONObject ();
+			mapInfo.Add ("blockSize", new JSONNumber (Constants.MAP_BLOCK_SIZE));
+			mapInfo.Add ("maxZoom", new JSONNumber (Constants.ZOOMLEVELS - 1));
+
+			Directory.CreateDirectory (Constants.MAP_DIRECTORY);
+			File.WriteAllText (Constants.MAP_DIRECTORY + "/mapinfo.json", mapInfo.ToString (), Encoding.UTF8);
+		}
+
+		private bool LoadMapInfo ()
+		{
+			if (File.Exists (Constants.MAP_DIRECTORY + "/mapinfo.json")) {
+				string json = File.ReadAllText (Constants.MAP_DIRECTORY + "/mapinfo.json", Encoding.UTF8);
+				try {
+					JSONNode node = Parser.Parse (json);
+					if (node is JSONObject) {
+						JSONObject jo = (JSONObject)node;
+						if (jo.ContainsKey ("blockSize"))
+							Constants.MAP_BLOCK_SIZE = ((JSONNumber)jo ["blockSize"]).GetInt ();
+						if (jo.ContainsKey ("maxZoom"))
+							Constants.ZOOMLEVELS = ((JSONNumber)jo ["maxZoom"]).GetInt () + 1;
+						return true;
+					}
+				} catch (MalformedJSONException e) {
+					Log.Out ("Exception in LoadMapInfo: " + e);
+				} catch (InvalidCastException e) {
+					Log.Out ("Exception in LoadMapInfo: " + e);
+				}
+			}
+			return false;
+		}
+
+		private void getWorldExtent (RegionFileManager rfm, out Vector2i minChunk, out Vector2i maxChunk,
+	                                    out Vector2i minPos, out Vector2i maxPos,
+	                                    out int widthChunks, out int heightChunks,
+	                                    out int widthPix, out int heightPix)
+		{
+			minChunk = default(Vector2i);
+			maxChunk = default(Vector2i);
+			minPos = default(Vector2i);
+			maxPos = default(Vector2i);
+
+			long[] keys = rfm.GetAllChunkKeys ();
+			int minX = Int32.MaxValue;
+			int minY = Int32.MaxValue;
+			int maxX = Int32.MinValue;
+			int maxY = Int32.MinValue;
+			foreach (long key in keys) {
+				int x = WorldChunkCache.extractX (key);
+				int y = WorldChunkCache.extractZ (key);
+
+				if (x < minX)
+					minX = x;
+				if (x > maxX)
+					maxX = x;
+				if (y < minY)
+					minY = y;
+				if (y > maxY)
+					maxY = y;
+			}
+
+			minChunk.x = minX;
+			minChunk.y = minY;
+
+			maxChunk.x = maxX;
+			maxChunk.y = maxY;
+
+			minPos.x = minX * Constants.MAP_CHUNK_SIZE;
+			minPos.y = minY * Constants.MAP_CHUNK_SIZE;
+
+			maxPos.x = maxX * Constants.MAP_CHUNK_SIZE;
+			maxPos.y = maxY * Constants.MAP_CHUNK_SIZE;
+
+			widthChunks = maxX - minX + 1;
+			heightChunks = maxY - minY + 1;
+
+			widthPix = widthChunks * Constants.MAP_CHUNK_SIZE;
+			heightPix = heightChunks * Constants.MAP_CHUNK_SIZE;
+		}
+
+		private static Color shortColorToColor (ushort col)
+		{
+			return new Color (((float)(col >> 10 & 31) / 31f), ((float)(col >> 5 & 31) / 31f), ((float)(col & 31) / 31f), 255);
+		}
+
+	}
+}
Index: binary-improvements/WebInterface/API.cs
===================================================================
--- binary-improvements/WebInterface/API.cs	(revision 224)
+++ binary-improvements/WebInterface/API.cs	(revision 224)
@@ -0,0 +1,19 @@
+using System;
+
+namespace WebInterface
+{
+	public class API : AllocsFixes.ModAPI {
+		public override string ModName () {
+			return "AllocsWebInterface";
+		}
+
+		public override string ModVersion () {
+			return "1.0 for A11";
+		}
+
+		public override void GameAwake () {
+			new AllocsFixes.NetConnections.Servers.Web.Web ();
+		}
+	}
+}
+
Index: binary-improvements/WebInterface/AssemblyInfo.cs
===================================================================
--- binary-improvements/WebInterface/AssemblyInfo.cs	(revision 224)
+++ binary-improvements/WebInterface/AssemblyInfo.cs	(revision 224)
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("WebInterface")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("ci")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
Index: binary-improvements/WebInterface/Commands/webstat.cs
===================================================================
--- binary-improvements/WebInterface/Commands/webstat.cs	(revision 224)
+++ binary-improvements/WebInterface/Commands/webstat.cs	(revision 224)
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class webstat : ConsoleCommand
+	{
+		public webstat (ConsoleSdtd cons) : base(cons)
+		{
+		}
+
+		public override string Description ()
+		{
+			return "DEBUG PURPOSES ONLY";
+		}
+
+		public override string[] Names ()
+		{
+			return new string[] { "webstat", string.Empty };
+		}
+
+		public override void Run (string[] _params)
+		{
+			try {
+				m_Console.SendResult ("Current handlers: " + AllocsFixes.NetConnections.Servers.Web.Web.currentHandlers + " - total: " + AllocsFixes.NetConnections.Servers.Web.Web.handlingCount);
+			} catch (Exception e) {
+				Log.Out ("Error in webstat.Run: " + e);
+			}
+		}
+	}
+}
Index: binary-improvements/WebInterface/Web/API/GetLandClaims.cs
===================================================================
--- binary-improvements/WebInterface/Web/API/GetLandClaims.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/API/GetLandClaims.cs	(revision 224)
@@ -0,0 +1,74 @@
+using AllocsFixes.JSON;
+using AllocsFixes.PersistentData;
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+	public class GetLandClaims : WebAPI
+	{
+		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user)
+		{
+			string steamid = string.Empty;
+
+			if (req.QueryString ["steamid"] != null) {
+				long tempLong;
+				steamid = req.QueryString ["steamid"];
+				if (steamid.Length != 17 || !long.TryParse (steamid, out tempLong)) {
+					resp.StatusCode = (int)HttpStatusCode.InternalServerError;
+					Web.SetResponseTextContent (resp, "Invalid SteamID given");
+					return;
+				}
+			}
+
+			JSONObject result = new JSONObject ();
+			result.Add ("claimsize", new JSONNumber (GamePrefs.GetInt (EnumGamePrefs.LandClaimSize)));
+
+			JSONArray claimOwners = new JSONArray ();
+			result.Add ("claimowners", claimOwners);
+
+			Dictionary<Vector3i, PersistentPlayerData> d = CommonMappingFunctions.GetGameManager ().GetPersistentPlayerList ().positionToLPBlockOwner;
+			if (d != null) {
+				World w = CommonMappingFunctions.GetGameManager ().World;
+				Dictionary<PersistentPlayerData, List<Vector3i>> owners = new Dictionary<PersistentPlayerData, List<Vector3i>> ();
+				foreach (KeyValuePair<Vector3i, PersistentPlayerData> kvp in d) {
+					if (steamid.Length == 0 || kvp.Value.PlayerId.Equals (steamid)) {
+						if (!owners.ContainsKey (kvp.Value)) {
+							owners.Add (kvp.Value, new List<Vector3i> ());
+						}
+						owners [kvp.Value].Add (kvp.Key);
+					}
+				}
+
+				foreach (KeyValuePair<PersistentPlayerData, List<Vector3i>> kvp in owners) {
+					if (steamid.Length == 0 || kvp.Key.PlayerId.Equals (steamid)) {
+						string curID = kvp.Key.PlayerId;
+						bool isActive = w.LandClaimIsActive (kvp.Key);
+
+						JSONObject owner = new JSONObject ();
+						claimOwners.Add (owner);
+
+						owner.Add ("steamid", new JSONString (curID));
+						owner.Add ("claimactive", new JSONBoolean (isActive));
+
+						JSONArray claims = new JSONArray ();
+						owner.Add ("claims", claims);
+
+						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));
+
+							claims.Add (claim);
+						}
+					}
+				}
+			}
+
+			WriteJSON (resp, result);
+		}
+	}
+}
+
Index: binary-improvements/WebInterface/Web/API/GetPlayerInventory.cs
===================================================================
--- binary-improvements/WebInterface/Web/API/GetPlayerInventory.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/API/GetPlayerInventory.cs	(revision 224)
@@ -0,0 +1,63 @@
+using AllocsFixes.JSON;
+using AllocsFixes.PersistentData;
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+	public class GetPlayerInventory : WebAPI
+	{
+		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user)
+		{
+			if (req.QueryString ["steamid"] == null) {
+				resp.StatusCode = (int)HttpStatusCode.InternalServerError;
+				Web.SetResponseTextContent (resp, "No SteamID given");
+				return;
+			}
+
+			Player p = PersistentContainer.Instance.Players [req.QueryString ["steamid"]];
+			if (p == null) {
+				resp.StatusCode = (int)HttpStatusCode.InternalServerError;
+				Web.SetResponseTextContent (resp, "Invalid or unknown SteamID given");
+				return;
+			}
+
+			PersistentData.Inventory inv = p.Inventory;
+
+
+			JSONObject result = new JSONObject ();
+
+			JSONArray bag = new JSONArray ();
+			JSONArray belt = new JSONArray ();
+			result.Add ("bag", bag);
+			result.Add ("belt", belt);
+
+			for (int i = 0; i < inv.belt.Count; i++) {
+				JSONObject item = new JSONObject();
+				if (inv.belt [i] != null) {
+					item.Add ("count", new JSONNumber(inv.belt[i].count));
+					item.Add ("name", new JSONString(inv.belt[i].itemName));
+				} else {
+					item.Add ("count", new JSONNumber(0));
+					item.Add ("name", new JSONString(string.Empty));
+				}
+				belt.Add(item);
+			}
+			for (int i = 0; i < inv.bag.Count; i++) {
+				JSONObject item = new JSONObject();
+				if (inv.bag [i] != null) {
+					item.Add ("count", new JSONNumber(inv.bag[i].count));
+					item.Add ("name", new JSONString(inv.bag[i].itemName));
+				} else {
+					item.Add ("count", new JSONNumber(0));
+					item.Add ("name", new JSONString(string.Empty));
+				}
+				bag.Add(item);
+			}
+
+			WriteJSON (resp, result);
+		}
+	}
+}
+
Index: binary-improvements/WebInterface/Web/API/GetPlayersLocation.cs
===================================================================
--- binary-improvements/WebInterface/Web/API/GetPlayersLocation.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/API/GetPlayersLocation.cs	(revision 224)
@@ -0,0 +1,39 @@
+using AllocsFixes.JSON;
+using AllocsFixes.PersistentData;
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+	public class GetPlayersLocation : WebAPI
+	{
+		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user)
+		{
+			JSONArray playersJsResult = new JSONArray ();
+
+			Players playersList = PersistentContainer.Instance.Players;
+
+			foreach (string sid in playersList.SteamIDs) {
+				Player p = playersList[sid];
+
+				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(sid));
+				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);
+
+				playersJsResult.Add(pJson);
+			}
+
+			WriteJSON(resp, playersJsResult);
+		}
+	}
+}
+
Index: binary-improvements/WebInterface/Web/API/GetPlayersOnline.cs
===================================================================
--- binary-improvements/WebInterface/Web/API/GetPlayersOnline.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/API/GetPlayersOnline.cs	(revision 224)
@@ -0,0 +1,41 @@
+using AllocsFixes.JSON;
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+	public class GetPlayersOnline : WebAPI
+	{
+		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user)
+		{
+			JSONArray players = new JSONArray();
+
+			World w = CommonMappingFunctions.GetGameManager ().World;
+			foreach (KeyValuePair<int, EntityPlayer> current in w.Players.dict) {
+				ClientInfo ci = CommonMappingFunctions.GetClientInfoFromEntityID (current.Key);
+				string ip = string.Empty;
+				if (ci != null) {
+					ip = ci.networkPlayer.ipAddress;
+				}
+
+				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(CommonMappingFunctions.GetSteamID (ci)));
+				p.Add("ip", new JSONString(ip));
+				p.Add("name", new JSONString(current.Value.EntityName));
+				p.Add("online", new JSONBoolean(true));
+				p.Add("position", pos);
+
+				players.Add(p);
+			}
+
+			WriteJSON(resp, players);
+		}
+	}
+}
+
Index: binary-improvements/WebInterface/Web/API/WebAPI.cs
===================================================================
--- binary-improvements/WebInterface/Web/API/WebAPI.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/API/WebAPI.cs	(revision 224)
@@ -0,0 +1,21 @@
+using System;
+using System.Net;
+using System.Text;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+	public abstract class WebAPI
+	{
+		public void WriteJSON (HttpListenerResponse resp, JSON.JSONNode root)
+		{
+			byte[] buf = Encoding.UTF8.GetBytes (root.ToString());
+			resp.ContentLength64 = buf.Length;
+			resp.ContentType = "application/json";
+			resp.ContentEncoding = Encoding.UTF8;
+			resp.OutputStream.Write (buf, 0, buf.Length);
+		}
+
+		public abstract void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user);
+	}
+}
+
Index: binary-improvements/WebInterface/Web/ApiHandler.cs
===================================================================
--- binary-improvements/WebInterface/Web/ApiHandler.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/ApiHandler.cs	(revision 224)
@@ -0,0 +1,56 @@
+using AllocsFixes.NetConnections.Servers.Web.API;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Threading;
+
+namespace AllocsFixes.NetConnections.Servers.Web
+{
+	public class ApiHandler : PathHandler
+	{
+		private string staticPart;
+		private Dictionary<String, WebAPI> apis = new Dictionary<string, WebAPI> ();
+
+		public ApiHandler (string staticPart)
+		{
+			this.staticPart = staticPart;
+			apis.Add ("getlandclaims", new GetLandClaims ());
+			apis.Add ("getplayersonline", new GetPlayersOnline ());
+			apis.Add ("getplayerslocation", new GetPlayersLocation ());
+			apis.Add ("getplayerinventory", new GetPlayerInventory ());
+		}
+
+		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user)
+		{
+			string apiName = req.Url.AbsolutePath.Remove (0, staticPart.Length);
+			if (!AuthorizeForCommand (apiName, user)) {
+				resp.StatusCode = (int)HttpStatusCode.Forbidden;
+			} else {
+				foreach (KeyValuePair<string, WebAPI> kvp in apis) {
+					try {
+						if (apiName.StartsWith (kvp.Key)) {
+							kvp.Value.HandleRequest (req, resp, user);
+							return;
+						}
+					} catch (Exception e) {
+						Log.Out ("Error in ApiHandler.HandleRequest(): Handler threw an exception: " + e);
+						resp.StatusCode = (int)HttpStatusCode.InternalServerError;
+						return;
+					}
+				}
+			}
+	
+			Log.Out ("Error in ApiHandler.HandleRequest(): No handler found for API \"" + apiName + "\"");
+			resp.StatusCode = (int)HttpStatusCode.NotFound;
+		}
+
+		private bool AuthorizeForCommand (string apiName, HttpListenerBasicIdentity user)
+		{
+			return true;
+		}
+
+	}
+
+}
+
Index: binary-improvements/WebInterface/Web/MimeType.cs
===================================================================
--- binary-improvements/WebInterface/Web/MimeType.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/MimeType.cs	(revision 224)
@@ -0,0 +1,587 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.NetConnections.Servers.Web
+{
+	public class MimeType
+	{
+		private static IDictionary<string, string> _mappings = new Dictionary<string, string> (StringComparer.InvariantCultureIgnoreCase) {
+        {".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/WebInterface/Web/PathHandler.cs
===================================================================
--- binary-improvements/WebInterface/Web/PathHandler.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/PathHandler.cs	(revision 224)
@@ -0,0 +1,11 @@
+using System;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web
+{
+	public abstract class PathHandler
+	{
+		public abstract void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user);
+	}
+}
+
Index: binary-improvements/WebInterface/Web/SimpleRedirectHandler.cs
===================================================================
--- binary-improvements/WebInterface/Web/SimpleRedirectHandler.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/SimpleRedirectHandler.cs	(revision 224)
@@ -0,0 +1,21 @@
+using System;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web
+{
+	public class SimpleRedirectHandler : PathHandler
+	{
+		string target;
+
+		public SimpleRedirectHandler (string target)
+		{
+			this.target = target;
+		}
+
+		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user)
+		{
+			resp.Redirect (target);
+		}
+	}
+}
+
Index: binary-improvements/WebInterface/Web/StaticHandler.cs
===================================================================
--- binary-improvements/WebInterface/Web/StaticHandler.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/StaticHandler.cs	(revision 224)
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Threading;
+
+namespace AllocsFixes.NetConnections.Servers.Web
+{
+	public class StaticHandler : PathHandler
+	{
+		private string datapath;
+		private string staticPart;
+		private AllocsFixes.FileCache.AbstractCache cache;
+		private bool logMissingFiles;
+
+		public StaticHandler (string staticPart, string filePath, AllocsFixes.FileCache.AbstractCache cache, bool logMissingFiles)
+		{
+			this.staticPart = staticPart;
+			this.datapath = filePath;
+			this.cache = cache;
+			this.logMissingFiles = logMissingFiles;
+		}
+
+		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, HttpListenerBasicIdentity user)
+		{
+			string fn = req.Url.AbsolutePath.Remove (0, staticPart.Length);
+
+			byte[] content = cache.GetFileContent (datapath + "/" + fn);
+			if (content != null) {
+				resp.ContentType = MimeType.GetMimeType (Path.GetExtension (fn));
+				resp.ContentLength64 = content.Length;
+				resp.OutputStream.Write (content, 0, content.Length);
+			} else {
+				resp.StatusCode = (int)HttpStatusCode.NotFound;
+				if (logMissingFiles)
+					Log.Out ("Web:Static:FileNotFound: \"" + req.Url.AbsolutePath + "\" @ \"" + datapath + "/" + req.Url.AbsolutePath.Remove (0, staticPart.Length) + "\"");
+				return;
+			}
+		}
+	}
+}
+
Index: binary-improvements/WebInterface/Web/Web.cs
===================================================================
--- binary-improvements/WebInterface/Web/Web.cs	(revision 224)
+++ binary-improvements/WebInterface/Web/Web.cs	(revision 224)
@@ -0,0 +1,182 @@
+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 UnityEngine;
+
+namespace AllocsFixes.NetConnections.Servers.Web
+{
+	public class Web : IServer {
+		private readonly HttpListener _listener = new HttpListener ();
+		private Dictionary<string, PathHandler> handlers = new Dictionary<string, PathHandler> ();
+		private bool authEnabled = false;
+		private string realm = "7dtd Admin Panel";
+		public static int handlingCount = 0;
+		public static int currentHandlers = 0;
+		private string dataFolder;
+		private bool mapEnabled = false;
+
+		public Web () {
+			try {
+				int webPort = GamePrefs.GetInt (EnumGamePrefs.ControlPanelPort);
+				if (webPort < 1 || webPort > 65533) {
+					Log.Out ("Webserver not started (ControlPanelPort not within 1-65534)");
+					return;
+				}
+				if (!Directory.Exists (Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) + "/webserver")) {
+					Log.Out ("Webserver not started (folder \"webserver\" not found in WebInterface mod folder)");
+					return;
+				}
+
+				dataFolder = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location) + "/webserver";
+
+				if (!HttpListener.IsSupported) {
+					Log.Out ("Webserver not started (needs Windows XP SP2, Server 2003 or later or Mono)");
+					return;
+				}
+ 
+				handlers.Add (
+						"/index.htm",
+						new SimpleRedirectHandler ("/static/index.html"));
+				handlers.Add (
+						"/favicon.ico",
+						new SimpleRedirectHandler ("/static/favicon.ico"));
+				handlers.Add (
+						"/static/",
+						new StaticHandler (
+								"/static/",
+								dataFolder,
+								new AllocsFixes.FileCache.DirectAccess (),
+								true)
+				); // TODO: Enable cache
+
+				{
+					if (AllocsFixes.Mods.ModLoaded ("AllocsMapRendering")) {
+						Assembly renderAssembly = AllocsFixes.Mods.GetModAssembly ("AllocsMapRendering");
+						foreach (Type t in renderAssembly.GetTypes ()) {
+							foreach (MethodInfo mi in t.GetMethods ()) {
+								if (mi.Name == "GetTileCache") {
+									handlers.Add (
+										"/map/",
+										new StaticHandler (
+											"/map/",
+											StaticDirectories.GetSaveGameDir () + "/map",
+											mi.Invoke (null, new object[0]) as AllocsFixes.FileCache.AbstractCache,
+											false)
+									);
+									mapEnabled = true;
+								}
+							}
+						}
+					}
+				}
+				handlers.Add ("/api/", new ApiHandler ("/api/"));
+
+				_listener.Prefixes.Add (String.Format ("http://*:{0}/", webPort + 2));
+				authEnabled = File.Exists (dataFolder + "/protect");
+				if (authEnabled) {
+					_listener.AuthenticationSchemes = AuthenticationSchemes.Basic;
+				}
+				_listener.Start ();
+				_listener.Realm = realm;
+
+				NetTelnetServer.RegisterServer (this);
+
+				_listener.BeginGetContext (new AsyncCallback (HandleRequest), _listener);
+
+				Log.Out ("Started Webserver on " + (webPort + 2) + " (authentication " + (authEnabled ? "enabled" : "disabled") + ")");
+			} catch (Exception e) {
+				Log.Out ("Error in Web.ctor: " + e);
+			}
+		}
+
+		private void HandleRequest (IAsyncResult result) {
+			if (_listener.IsListening) {
+				Interlocked.Increment (ref handlingCount);
+				Interlocked.Increment (ref currentHandlers);
+				HttpListenerContext ctx = _listener.EndGetContext (result);
+				_listener.BeginGetContext (new AsyncCallback (HandleRequest), _listener);
+				try {
+					ctx.Response.ProtocolVersion = new Version ("1.0");
+
+					HttpListenerBasicIdentity user = Authorize (ctx);
+
+					if (!authEnabled || (user.Name.ToLower ().Equals ("admin") && user.Password.Equals (GamePrefs.GetString (EnumGamePrefs.ControlPanelPassword)))) {
+						if (ctx.Request.Url.AbsolutePath.Length < 2) {
+							handlers ["/index.htm"].HandleRequest (ctx.Request, ctx.Response, user);
+							return;
+						} else {
+							foreach (KeyValuePair<string, PathHandler> kvp in handlers) {
+								if (ctx.Request.Url.AbsolutePath.StartsWith (kvp.Key)) {
+									kvp.Value.HandleRequest (ctx.Request, ctx.Response, user);
+									return;
+								}
+							}
+						}
+
+						Log.Out ("Error in Web.HandleRequest(): No handler found for path \"" + ctx.Request.Url.AbsolutePath + "\"");
+						ctx.Response.StatusCode = (int)HttpStatusCode.NotFound;
+					} else {
+						ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
+						ctx.Response.Headers ["WWW-Authenticate"] = "Basic realm=\"" + realm + "\"";
+					}
+				} 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.Out ("Error in Web.HandleRequest(): " + e);
+				} finally {
+					if (ctx != null) {
+						ctx.Response.OutputStream.Close ();
+					}
+					Interlocked.Decrement (ref currentHandlers);
+				}
+			}
+		}
+
+		private HttpListenerBasicIdentity Authorize (HttpListenerContext ctx) {
+			try {
+				return (HttpListenerBasicIdentity)ctx.User.Identity;
+			} catch (NullReferenceException) {
+				return null;
+			}
+		}
+
+		public void Disconnect () {
+			try {
+				_listener.Stop ();
+				_listener.Close ();
+			} catch (Exception e) {
+				Log.Out ("Error in Web.Disconnect: " + e);
+			}
+		}
+
+		public void SendLine (string line) {
+			try {
+				//Log.Out ("NOT IMPLEMENTED: Web.WriteToClient");
+			} catch (Exception e) {
+				Log.Out ("Error in Web.WriteToClient: " + e);
+			}
+		}
+
+		public void SendLog (string text, string trace, UnityEngine.LogType type) {
+			throw new System.NotImplementedException ();
+		}
+
+		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/WebInterface/WebInterface.csproj
===================================================================
--- binary-improvements/WebInterface/WebInterface.csproj	(revision 224)
+++ binary-improvements/WebInterface/WebInterface.csproj	(revision 224)
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{5D85493E-D928-42E6-943D-1B6B47186E08}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>WebInterface</RootNamespace>
+    <AssemblyName>WebInterface</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Mods\AllocsWebInterface\</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="Assembly-CSharp">
+      <HintPath>..\7dtd-binaries\Assembly-CSharp.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="LogLibrary">
+      <HintPath>..\7dtd-binaries\LogLibrary.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="UnityEngine">
+      <HintPath>..\7dtd-binaries\UnityEngine.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="mscorlib">
+      <HintPath>..\7dtd-binaries\mscorlib.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="Web\Web.cs" />
+    <Compile Include="Web\PathHandler.cs" />
+    <Compile Include="Web\StaticHandler.cs" />
+    <Compile Include="Web\SimpleRedirectHandler.cs" />
+    <Compile Include="Web\MimeType.cs" />
+    <Compile Include="Web\ApiHandler.cs" />
+    <Compile Include="Web\API\GetPlayersOnline.cs" />
+    <Compile Include="Web\API\WebAPI.cs" />
+    <Compile Include="Web\API\GetPlayersLocation.cs" />
+    <Compile Include="Web\API\GetPlayerInventory.cs" />
+    <Compile Include="Web\API\GetLandClaims.cs" />
+    <Compile Include="Commands\webstat.cs" />
+    <Compile Include="API.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\7dtd-server-fixes\7dtd-server-fixes.csproj">
+      <Project>{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}</Project>
+      <Name>7dtd-server-fixes</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Commands\" />
+  </ItemGroup>
+</Project>
Index: binary-improvements/assembly-patcher/Assembly-Patcher.csproj
===================================================================
--- binary-improvements/assembly-patcher/Assembly-Patcher.csproj	(revision 222)
+++ binary-improvements/assembly-patcher/Assembly-Patcher.csproj	(revision 224)
@@ -2,5 +2,5 @@
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
     <ProductVersion>10.0.0</ProductVersion>
@@ -11,30 +11,13 @@
     <AssemblyName>7dtd-fixer</AssemblyName>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>true</DebugSymbols>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
     <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <ConsolePause>false</ConsolePause>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <DebugType>none</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\bin\Release</OutputPath>
+    <OutputPath>..\bin\7DaysToDie_Data\Managed</OutputPath>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <PlatformTarget>x86</PlatformTarget>
     <Externalconsole>true</Externalconsole>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_Version|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\bin\Release</OutputPath>
-    <WarningLevel>4</WarningLevel>
-    <Externalconsole>true</Externalconsole>
+    <DebugSymbols>true</DebugSymbols>
   </PropertyGroup>
   <ItemGroup>
Index: binary-improvements/assembly-patcher/Main.cs
===================================================================
--- binary-improvements/assembly-patcher/Main.cs	(revision 222)
+++ binary-improvements/assembly-patcher/Main.cs	(revision 224)
@@ -7,8 +7,6 @@
 namespace dtdfixer
 {
-	class MainClass
-	{
-		public static void Main (string[] args)
-		{
+	class MainClass {
+		public static void Main (string[] args) {
 			ModuleDefinition module = ModuleDefinition.ReadModule ("Assembly-CSharp.dll");
 
@@ -24,5 +22,4 @@
 			telnetPatch (module);
 			connectLogPatch (module);
-			publicCommandPermissionsPatch (module);
 			playerDataPatch (module);
 
@@ -32,12 +29,10 @@
 		}
 
-		private static void mappingPatch (ModuleDefinition module)
-		{
+		private static void mappingPatch (ModuleDefinition module) {
 			TypeDefinition type = module.GetType ("Chunk");
-			addHook (type, "CalcMapColors", true, 0, true, typeof(AllocsFixes.MapRendering.MapRendering).GetMethod ("RenderSingleChunk"));
+			addHook (type, "CalcMapColors", true, 0, true, typeof(AllocsFixes.Mods).GetMethod ("CallCalcMapColors"));
 		}
 
-		private static void consoleOutputPatch (ModuleDefinition module)
-		{
+		private static void consoleOutputPatch (ModuleDefinition module) {
 			TypeDefinition type = module.GetType ("ConsoleSdtd");
 			replaceMethod (type, "ExecuteCmdFromClient", true, 4, typeof(AllocsFixes.NetConnections.ConsoleOutputSeparator).GetMethod ("C_ExecuteCmdFromClient"));
@@ -46,28 +41,19 @@
 		}
 
-		private static void playerDataPatch (ModuleDefinition module)
-		{
+		private static void playerDataPatch (ModuleDefinition module) {
 			TypeDefinition type = module.GetType ("GameManager");
 			addHook (type, "SavePlayerData", true, 2, true, typeof(AllocsFixes.PlayerDataStuff).GetMethod ("GM_SavePlayerData"));
 			addHook (type, "Awake", true, 0, true, typeof(AllocsFixes.StateManager).GetMethod ("Awake"));
-			addHook (type, "Shutdown", true, 0, false, typeof(AllocsFixes.StateManager).GetMethod ("Shutdown"));
+			addHook (type, "Cleanup", true, 0, false, typeof(AllocsFixes.StateManager).GetMethod ("Shutdown"));
 		}
 
-		private static void publicCommandPermissionsPatch (ModuleDefinition module)
-		{
-			TypeDefinition type = module.GetType ("AdminTools");
-			replaceMethod (type, "GetAllowedCommandsList", true, 1, typeof(AllocsFixes.AdminToolsStuff).GetMethod ("GetAllowedCommandsList"));
-		}
-
-		private static void connectLogPatch (ModuleDefinition module)
-		{
+		private static void connectLogPatch (ModuleDefinition module) {
 			TypeDefinition type = module.GetType ("GameManager");
 			addHook (type, "RequestToSpawnPlayer", true, 4, true, typeof(AllocsFixes.AllocsLogFunctions).GetMethod ("RequestToSpawnPlayer"));
 			type = module.GetType ("ConnectionManager");
-			addHook (type, "RemovePlayer", true, 2, false, typeof(AllocsFixes.AllocsLogFunctions).GetMethod ("PlayerDisconnected"));
+			addHook (type, "DisconnectClient", true, 2, false, typeof(AllocsFixes.AllocsLogFunctions).GetMethod ("PlayerDisconnected"));
 		}
 
-		private static void telnetPatch (ModuleDefinition module)
-		{
+		private static void telnetPatch (ModuleDefinition module) {
 			TypeDefinition type = module.GetType ("NetTelnetServer");
 			replaceMethod (type, ".ctor", false, 1, typeof(AllocsFixes.NetConnections.NetTelnetServer).GetMethod ("init"));
@@ -77,62 +63,67 @@
 		}
 
-		private static void markTypePatched (ModuleDefinition module, TypeDefinition type)
-		{
+		private static void markTypePatched (ModuleDefinition module, TypeDefinition type) {
 			type.Fields.Add (new FieldDefinition ("AllocsPatch", Mono.Cecil.FieldAttributes.Private | Mono.Cecil.FieldAttributes.SpecialName, module.Import (typeof(int))));
 		}
 
-		private static void addHook (TypeDefinition type, string methodName, bool addThisRef, int opCount, bool atEnd, MethodBase targetMethod)
-		{
-			foreach (MethodDefinition method in type.Methods) {
-				if (method.Name.Equals (methodName)) {
-					var il = method.Body.GetILProcessor ();
-					var call = il.Create (OpCodes.Call, method.Module.Import (targetMethod));
-					if (atEnd) {
-						int insBefore = method.Body.Instructions.Count;
-						if (addThisRef)
-							il.Append (il.Create (OpCodes.Ldarg, 0));
-						for (int op = 0; op < opCount; op++) {
-							il.Append (il.Create (OpCodes.Ldarg, op + 1));
-						}
-						il.Append (call);
-						il.Remove (method.Body.Instructions [insBefore - 1]);
-						il.Append (il.Create (OpCodes.Ret));
-					} else {
-						var i = 0;
-						if (addThisRef)
-							il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, 0));
-						for (int op = 0; op < opCount; op++) {
-							il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, op + 1));
-						}
-						il.InsertBefore (method.Body.Instructions [i++], call);
+		private static void addHook (TypeDefinition type, string methodName, bool addThisRef, int opCount, bool atEnd, MethodBase targetMethod) {
+			MethodDefinition method = findMethod (type, methodName, opCount);
+			if (method != null) {
+				var il = method.Body.GetILProcessor ();
+				var call = il.Create (OpCodes.Call, method.Module.Import (targetMethod));
+				if (atEnd) {
+					int insBefore = method.Body.Instructions.Count;
+					if (addThisRef) {
+						il.Append (il.Create (OpCodes.Ldarg, 0));
 					}
-					return;
-				}
-			}
-			Console.WriteLine ("ERROR: Did not find " + type.Name + "." + methodName + "()");
-		}
-
-		private static void replaceMethod (TypeDefinition type, string methodName, bool addThisRef, int opCount, MethodBase targetMethod)
-		{
-			foreach (MethodDefinition method in type.Methods) {
-				if (method.Name.Equals (methodName)) {
-					var il = method.Body.GetILProcessor ();
-					var call = il.Create (OpCodes.Call, method.Module.Import (targetMethod));
+					for (int op = 0; op < opCount; op++) {
+						il.Append (il.Create (OpCodes.Ldarg, op + 1));
+					}
+					il.Append (call);
+					il.Remove (method.Body.Instructions [insBefore - 1]);
+					il.Append (il.Create (OpCodes.Ret));
+				} else {
 					var i = 0;
-					if (addThisRef)
+					if (addThisRef) {
 						il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, 0));
+					}
 					for (int op = 0; op < opCount; op++) {
 						il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, op + 1));
 					}
 					il.InsertBefore (method.Body.Instructions [i++], call);
-					il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ret));
-					return;
+				}
+				return;
+			}
+		}
+
+		private static void replaceMethod (TypeDefinition type, string methodName, bool addThisRef, int opCount, MethodBase targetMethod) {
+			MethodDefinition method = findMethod (type, methodName, opCount);
+			if (method != null) {
+				var il = method.Body.GetILProcessor ();
+				var call = il.Create (OpCodes.Call, method.Module.Import (targetMethod));
+				var i = 0;
+				if (addThisRef) {
+					il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, 0));
+				}
+				for (int op = 0; op < opCount; op++) {
+					il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, op + 1));
+				}
+				il.InsertBefore (method.Body.Instructions [i++], call);
+				il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ret));
+				return;
+			}
+		}
+
+		private static MethodDefinition findMethod (TypeDefinition type, string methodName, int opCount) {
+			foreach (MethodDefinition method in type.Methods) {
+				if (method.Name.Equals (methodName) && method.Parameters.Count == opCount) {
+					return method;
 				}
 			}
-			Console.WriteLine ("ERROR: Did not find " + type.Name + "." + methodName + "()");
+			Console.WriteLine ("ERROR: Did not find " + type.Name + "." + methodName + "() with " + opCount + " parameters");
+			return null;
 		}
 
-		private static bool isPatched (TypeDefinition type)
-		{
+		private static bool isPatched (TypeDefinition type) {
 			foreach (FieldDefinition fd in type.Fields) {
 				if (fd.Name.Equals ("AllocsPatch")) {
Index: binary-improvements/bundle_creation/makefile
===================================================================
--- binary-improvements/bundle_creation/makefile	(revision 224)
+++ binary-improvements/bundle_creation/makefile	(revision 224)
@@ -0,0 +1,41 @@
+HOST=178.63.97.203
+PORT=51010
+SERVERPATH=/srv/www/illy.bz/http/fi/7dtd/
+
+VERSIONFILE=../bin/7DaysToDie_Data/Managed/7dtd-server-fixes_version.txt
+VERSION=$(shell cat ${VERSIONFILE} | grep "Version" | cut -d\  -f8)
+ARCHIVENAME=server_fixes_v${VERSION}.tar.gz
+
+build: CONTENTS ${ARCHIVENAME}
+	@echo Bundle built successfully
+
+all: build upload
+	@echo Bundle built and uploaded
+
+upload: ${ARCHIVENAME}
+	@echo Uploading files...
+	@scp -P ${PORT} ${ARCHIVENAME} ${VERSIONFILE} ${HOST}:${SERVERPATH}
+	@ssh -p ${PORT} ${HOST} "cd ${SERVERPATH}; rm -f server_fixes.tar.gz; ln -s ${ARCHIVENAME} server_fixes.tar.gz"
+
+${ARCHIVENAME}: CONTENTS
+	@echo Creating archive...
+	@tar -czf ${ARCHIVENAME} 7DaysToDie_Data Mods
+
+CONTENTS: SERVERFIXES
+
+SERVERFIXES:
+	@echo Copying server fixes...
+	@mkdir -p 7DaysToDie_Data/Managed
+	@cp ../bin/7DaysToDie_Data/Managed/Assembly-CSharp.patched.dll 7DaysToDie_Data/Managed/Assembly-CSharp.dll
+	@cp ../bin/7DaysToDie_Data/Managed/7dtd-server-fixes.dll 7DaysToDie_Data/Managed/
+	@cp ../bin/7DaysToDie_Data/Managed/7dtd-server-fixes_version.txt 7DaysToDie_Data/Managed/
+	@mkdir -p Mods
+	@cp ../bin/Mods/* Mods/ -R
+	@mkdir -p Mods/AllocsWebInterface/webserver
+	@cp ../webserver/* Mods/AllocsWebInterface/webserver/ -R
+	@find . -name "*~" -exec rm {} \;
+
+clean:
+	@echo Cleaning intermediate stuff...
+	@rm -Rf 7DaysToDie_Data Mods server_fixes_v*.tar.gz
+
Index: binary-improvements/server-fixes.sln
===================================================================
--- binary-improvements/server-fixes.sln	(revision 222)
+++ binary-improvements/server-fixes.sln	(revision 224)
@@ -6,29 +6,36 @@
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-Patcher", "assembly-patcher\Assembly-Patcher.csproj", "{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AllocsCommands", "AllocsCommands\AllocsCommands.csproj", "{E273D042-57F9-4E2E-8268-5053527E5287}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapRendering", "MapRendering\MapRendering.csproj", "{A1847B5F-7BFC-4BCD-94AA-A6C9FB7E7C54}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebInterface", "WebInterface\WebInterface.csproj", "{5D85493E-D928-42E6-943D-1B6B47186E08}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
 		Release|Any CPU = Release|Any CPU
-		Debug|x86 = Debug|x86
-		Release|x86 = Release|x86
 		Release_Version|Any CPU = Release_Version|Any CPU
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5D85493E-D928-42E6-943D-1B6B47186E08}.Release_Version|Any CPU.ActiveCfg = Release|Any CPU
+		{5D85493E-D928-42E6-943D-1B6B47186E08}.Release_Version|Any CPU.Build.0 = Release|Any CPU
+		{5D85493E-D928-42E6-943D-1B6B47186E08}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5D85493E-D928-42E6-943D-1B6B47186E08}.Release|Any CPU.Build.0 = Release|Any CPU
 		{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}.Release_Version|Any CPU.ActiveCfg = Release_Version|Any CPU
 		{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}.Release_Version|Any CPU.Build.0 = Release_Version|Any CPU
 		{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{81DA7F87-1A66-4920-AADA-6EAF1971F8D0}.Release|Any CPU.Build.0 = Release|Any CPU
-		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Debug|Any CPU.ActiveCfg = Debug|x86
-		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Debug|Any CPU.Build.0 = Debug|x86
-		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Debug|x86.ActiveCfg = Debug|x86
-		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Debug|x86.Build.0 = Debug|x86
-		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Release_Version|Any CPU.ActiveCfg = Release_Version|Any CPU
-		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Release_Version|Any CPU.Build.0 = Release_Version|Any CPU
+		{A1847B5F-7BFC-4BCD-94AA-A6C9FB7E7C54}.Release_Version|Any CPU.ActiveCfg = Release|Any CPU
+		{A1847B5F-7BFC-4BCD-94AA-A6C9FB7E7C54}.Release_Version|Any CPU.Build.0 = Release|Any CPU
+		{A1847B5F-7BFC-4BCD-94AA-A6C9FB7E7C54}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A1847B5F-7BFC-4BCD-94AA-A6C9FB7E7C54}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E273D042-57F9-4E2E-8268-5053527E5287}.Release_Version|Any CPU.ActiveCfg = Release|Any CPU
+		{E273D042-57F9-4E2E-8268-5053527E5287}.Release_Version|Any CPU.Build.0 = Release|Any CPU
+		{E273D042-57F9-4E2E-8268-5053527E5287}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E273D042-57F9-4E2E-8268-5053527E5287}.Release|Any CPU.Build.0 = Release|Any CPU
+		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Release_Version|Any CPU.ActiveCfg = Release|x86
+		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Release_Version|Any CPU.Build.0 = Release|x86
 		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Release|Any CPU.ActiveCfg = Release|x86
 		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Release|Any CPU.Build.0 = Release|x86
-		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Release|x86.ActiveCfg = Release|x86
-		{FFDBEC4C-E28E-4BF5-A271-33D9368F7F6D}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(MonoDevelopProperties) = preSolution
Index: binary-improvements/server-fixes.userprefs
===================================================================
--- binary-improvements/server-fixes.userprefs	(revision 222)
+++ binary-improvements/server-fixes.userprefs	(revision 224)
@@ -1,20 +1,15 @@
 ﻿<Properties>
   <MonoDevelop.Ide.Workspace ActiveConfiguration="Release_Version" />
-  <MonoDevelop.Ide.Workbench ActiveDocument="7dtd-server-fixes/src/CommonMappingFunctions.cs">
+  <MonoDevelop.Ide.Workbench ActiveDocument="WebInterface/Web/Web.cs">
     <Files>
-      <File FileName="7dtd-server-fixes/src/PersistentData/Players.cs" Line="40" Column="70" />
-      <File FileName="7dtd-server-fixes/src/NetConnections/NetTelnetServer.cs" Line="34" Column="1" />
-      <File FileName="7dtd-server-fixes/src/NetConnections/Servers/Web/Web.cs" Line="89" Column="1" />
-      <File FileName="7dtd-server-fixes/src/NetConnections/Servers/Telnet/Telnet.cs" Line="67" Column="34" />
-      <File FileName="7dtd-server-fixes/src/NetConnections/Servers/Telnet/TelnetConnection.cs" Line="65" Column="45" />
-      <File FileName="7dtd-server-fixes/src/MapRendering/MapRenderBlockBuffer.cs" Line="91" Column="37" />
-      <File FileName="7dtd-server-fixes/src/MapRendering/MapRendering.cs" Line="31" Column="1" />
-      <File FileName="7dtd-server-fixes/src/CustomCommands/webstat.cs" Line="6" Column="22" />
-      <File FileName="7dtd-server-fixes/src/CustomCommands/ListLandProtection.cs" Line="70" Column="44" />
-      <File FileName="7dtd-server-fixes/src/CommonMappingFunctions.cs" Line="163" Column="47" />
-      <File FileName="7dtd-server-fixes/src/AllocsLogFunctions.cs" Line="24" Column="33" />
-      <File FileName="7dtd-server-fixes/src/CustomCommands/ListPlayerIds.cs" Line="47" Column="1" />
-      <File FileName="7dtd-server-fixes/src/CustomCommands/TeleportPlayer.cs" Line="20" Column="27" />
       <File FileName="7dtd-server-fixes/src/AssemblyInfo.cs" Line="20" Column="34" />
+      <File FileName="assembly-patcher/Main.cs" Line="33" Column="105" />
+      <File FileName="7dtd-server-fixes/src/CommandExtensions.cs" Line="24" Column="1" />
+      <File FileName="7dtd-server-fixes/src/Mods.cs" Line="95" Column="3" />
+      <File FileName="7dtd-server-fixes/src/ModAPI.cs" Line="11" Column="40" />
+      <File FileName="7dtd-server-fixes/src/StateManager.cs" Line="15" Column="14" />
+      <File FileName="WebInterface/Web/Web.cs" Line="45" Column="6" />
+      <File FileName="MapRendering/MapRendering/MapRendering.cs" Line="34" Column="20" />
+      <File FileName="WebInterface/API.cs" Line="20" Column="1" />
     </Files>
     <Pads>
