Index: binary-improvements/AllocsCommands/API.cs
===================================================================
--- binary-improvements/AllocsCommands/API.cs	(revision 228)
+++ 	(revision )
@@ -1,15 +1,0 @@
-using System;
-
-namespace AllocsCommands
-{
-	public class API : AllocsFixes.ModAPI {
-		public override string ModName () {
-			return "AllocsCommands";
-		}
-
-		public override string ModVersion () {
-			return "1.2 for A11.2";
-		}
-	}
-}
-
Index: binary-improvements/AllocsCommands/AllocsCommands.csproj
===================================================================
--- binary-improvements/AllocsCommands/AllocsCommands.csproj	(revision 228)
+++ binary-improvements/AllocsCommands/AllocsCommands.csproj	(revision 230)
@@ -15,5 +15,5 @@
     <DebugType>none</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\bin\Mods\AllocsCommands\</OutputPath>
+    <OutputPath>..\bin\Mods\Allocs_CommandExtensions\</OutputPath>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
@@ -41,21 +41,15 @@
   <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" />
+    <Compile Include="PrivateMassageConnections.cs" />
+    <Compile Include="Chat.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
@@ -70,3 +64,8 @@
     <Folder Include="Commands\" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="ModInfo.xml">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
 </Project>
Index: binary-improvements/AllocsCommands/Chat.cs
===================================================================
--- binary-improvements/AllocsCommands/Chat.cs	(revision 230)
+++ binary-improvements/AllocsCommands/Chat.cs	(revision 230)
@@ -0,0 +1,23 @@
+using System;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class Chat {
+
+		public static void SendMessage (ClientInfo _receiver, ClientInfo _sender, string _message) {
+			string senderName;
+			if (_sender != null) {
+				PrivateMassageConnections.SetLastPMSender (_sender, _receiver);
+				senderName = _sender.playerName;
+			} else {
+				senderName = "Server";
+			}
+			_receiver.netConnection [0].AddToSendQueue (new NetPackage_GameInfoMessage (_message, senderName + " (PM)"));
+			string receiverName = _receiver.playerName;
+			SdtdConsole.Instance.Output ("Message to player " + (receiverName != null ? "\"" + receiverName + "\"" : "unknownName") + " sent with sender \"" + senderName + "\"");
+		}
+
+
+	}
+}
+
Index: binary-improvements/AllocsCommands/Commands/GetGamePrefs.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/GetGamePrefs.cs	(revision 228)
+++ 	(revision )
@@ -1,82 +1,0 @@
-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 228)
+++ 	(revision )
@@ -1,38 +1,0 @@
-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 228)
+++ binary-improvements/AllocsCommands/Commands/Give.cs	(revision 230)
@@ -5,38 +5,34 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class Give : ConsoleCommand
+	public class Give : ConsoleCmdAbstract
 	{
-		public Give (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "give an item to a player (entity id or name)";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "give", string.Empty };
 		}
 
-		public override void Run (string[] _params)
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
 			try {
-				if (_params.Length != 3) {
-					m_Console.SendResult ("Usage: give <playername|entityid> <itemname> <amount>");
+				if (_params.Count != 3) {
+					SdtdConsole.Instance.Output ("Usage: give <playername|entityid> <itemname> <amount>");
 					return;
 				}
 
-				ClientInfo ci = CommonMappingFunctions.GetClientInfoFromNameOrID (_params [0], false);
+				ClientInfo ci = ConsoleHelper.ParseParamIdOrName (_params [0]);
 
 				if (ci == null) {
-					m_Console.SendResult ("Playername or entity id not found.");
+					SdtdConsole.Instance.Output ("Playername or entity id not found.");
 					return;
 				}
 
-				ItemValue iv = ItemList.Instance.GetItemValue(_params[1]);
+				ItemValue iv = ItemList.Instance.GetItemValue (_params[1]);
 				if (iv == null) {
-					m_Console.SendResult ("Item not found.");
+					SdtdConsole.Instance.Output ("Item not found.");
 					return;
 				}
@@ -44,15 +40,15 @@
 				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.");
+					SdtdConsole.Instance.Output ("Amount is not an integer or not greater than zero.");
 					return;
 				}
 
-				EntityPlayer p = CommonMappingFunctions.GetEntityPlayer (ci);
+				EntityPlayer p = GameManager.Instance.World.Players.dict [ci.entityId];
 
 				InventoryField invField = new InventoryField (iv, n);
 
-				CommonMappingFunctions.GetGameManager ().ItemDropServer (invField, p.GetPosition (), Vector3.zero, -1, 50);
+				GameManager.Instance.ItemDropServer (invField, p.GetPosition (), Vector3.zero, -1, 50);
 
-				m_Console.SendResult ("Dropped item");
+				SdtdConsole.Instance.Output ("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 228)
+++ 	(revision )
@@ -1,45 +1,0 @@
-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 228)
+++ binary-improvements/AllocsCommands/Commands/ListItems.cs	(revision 230)
@@ -4,25 +4,21 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class ListItems : ConsoleCommand
+	public class ListItems : ConsoleCmdAbstract
 	{
-		public ListItems (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "lists all items that contain the given substring";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "listitems", "li" };
 		}
 
-		public override void Run (string[] _params)
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
 			try {
-				if (_params.Length != 1 || _params [0].Length == 0) {
-					m_Console.SendResult ("Usage: listitems <searchString>");
+				if (_params.Count != 1 || _params [0].Length == 0) {
+					SdtdConsole.Instance.Output ("Usage: listitems <searchString>");
 					return;
 				}
@@ -31,10 +27,10 @@
 				foreach (string s in ItemList.Instance.ItemNames) {
 					if (s.ToLower ().Contains (_params [0].ToLower ())) {
-						m_Console.SendResult ("    " + s);
+						SdtdConsole.Instance.Output ("    " + s);
 						n++;
 					}
 				}
 
-				m_Console.SendResult ("Listed " + n + " matching items.");
+				SdtdConsole.Instance.Output ("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 228)
+++ binary-improvements/AllocsCommands/Commands/ListKnownPlayers.cs	(revision 230)
@@ -5,24 +5,20 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class ListKnownPlayers : ConsoleCommand
+	public class ListKnownPlayers : ConsoleCmdAbstract
 	{
-		public ListKnownPlayers (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "lists all players that were ever online (optionally filtered)";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "listknownplayers", "lkp" };
 		}
 
-		public override void Run (string[] _params)
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
 			try {
-				AdminTools admTools = CommonMappingFunctions.GetGameManager ().adminTools;
+				AdminTools admTools = GameManager.Instance.adminTools;
 
 				bool onlineOnly = false;
@@ -30,5 +26,5 @@
 				string nameFilter = string.Empty;
 
-				if (_params.Length == 1) {
+				if (_params.Count == 1) {
 					if (_params [0].ToLower ().Equals ("-online")) {
 						onlineOnly = true;
@@ -49,5 +45,5 @@
 						&& (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}",
+						SdtdConsole.Instance.Output (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,
@@ -56,5 +52,5 @@
 					}
 				}
-				m_Console.SendResult ("Total of " + PersistentContainer.Instance.Players.Count + " known");
+				SdtdConsole.Instance.Output ("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 228)
+++ binary-improvements/AllocsCommands/Commands/ListLandProtection.cs	(revision 230)
@@ -4,41 +4,27 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class ListLandProtection : ConsoleCommand
+	public class ListLandProtection : ConsoleCmdAbstract
 	{
-		public ListLandProtection (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "lists all land protection blocks and owners";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "listlandprotection", "llp" };
 		}
 
-		public override void ExecuteRemote (string _sender, string[] _params)
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
 			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;
+				if (_senderInfo.RemoteClientInfo != null) {
+					if (_params.Count >= 1 && _params [0].ToLower ().Equals ("nearby")) {
+						_params.Add (_senderInfo.RemoteClientInfo.playerId);
+					}
 				}
-				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 ();
+				World w = GameManager.Instance.World;
+				PersistentPlayerList ppl = GameManager.Instance.GetPersistentPlayerList ();
 
 				bool summaryOnly = false;
@@ -48,5 +34,5 @@
 				int closeToDistance = 32;
 
-				if (_params.Length == 1) {
+				if (_params.Count == 1) {
 					long tempLong;
 
@@ -56,30 +42,30 @@
 						steamIdFilter = _params [0];
 					} else {
-						ClientInfo ci = CommonMappingFunctions.GetClientInfoFromNameOrID (_params [0], true);
+						ClientInfo ci = ConsoleHelper.ParseParamIdOrName (_params [0]);
 						if (ci != null) {
-							steamIdFilter = CommonMappingFunctions.GetSteamID (ci);
+							steamIdFilter = ci.playerId;
 						} else {
-							m_Console.SendResult ("Player name or entity id \"" + _params [0] + "\" not found.");
+							SdtdConsole.Instance.Output ("Player name or entity id \"" + _params [0] + "\" not found.");
 							return;
 						}
 					}
-				} else if (_params.Length >= 2) {
+				} else if (_params.Count >= 2) {
 					if (_params [0].ToLower ().Equals ("nearby")) {
 						try {
-							if (_params.Length == 3) {
+							if (_params.Count == 3) {
 								if (!int.TryParse (_params[1], out closeToDistance)) {
-									m_Console.SendResult ("Given radius is not an integer!");
+									SdtdConsole.Instance.Output ("Given radius is not an integer!");
 								}
 							}
-							ClientInfo ci = CommonMappingFunctions.GetClientInfoFromSteamID (_params [_params.Length - 1]);
-							EntityPlayer ep = CommonMappingFunctions.GetEntityPlayer (ci);
+							ClientInfo ci = ConsoleHelper.ParseParamSteamIdOnline (_params [_params.Count - 1]);
+							EntityPlayer ep = w.Players.dict [ci.entityId];
 							closeTo = new Vector3i (ep.GetPosition ());
 							onlyCloseToPlayer = true;
 						} catch (Exception e) {
-							m_Console.SendResult ("Error getting current player's position");
+							SdtdConsole.Instance.Output ("Error getting current player's position");
 							Log.Out ("Error in ListLandProtection.Run: " + e);
 						}
 					} else {
-						m_Console.SendResult ("Illegal parameter list");
+						SdtdConsole.Instance.Output ("Illegal parameter list");
 						return;
 					}
@@ -103,8 +89,8 @@
 							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));
+							SdtdConsole.Instance.Output (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 () + ")");
+									SdtdConsole.Instance.Output ("   (" + v.ToString () + ")");
 								}
 							}
@@ -114,5 +100,5 @@
 
 				if (steamIdFilter.Length == 0)
-					m_Console.SendResult ("Total of " + d.Count + " keystones in the game");
+					SdtdConsole.Instance.Output ("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 228)
+++ 	(revision )
@@ -1,46 +1,0 @@
-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 228)
+++ 	(revision )
@@ -1,25 +1,0 @@
-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 228)
+++ binary-improvements/AllocsCommands/Commands/RemoveLandProtection.cs	(revision 230)
@@ -4,16 +4,12 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class RemoveLandProtection : ConsoleCommand
+	public class RemoveLandProtection : ConsoleCmdAbstract
 	{
-		public RemoveLandProtection (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "removes the association of a land protection block to the owner";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "removelandprotection", "rlp" };
@@ -23,12 +19,12 @@
 		{
 			try {
-				PersistentPlayerList ppl = CommonMappingFunctions.GetGameManager ().GetPersistentPlayerList ();
+				PersistentPlayerList ppl = GameManager.Instance.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.");
+					SdtdConsole.Instance.Output ("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.");
+					SdtdConsole.Instance.Output ("Player does not own any keystones. Use \"listlandprotection\" to get a list of keystones.");
 					return;
 				}
@@ -39,10 +35,10 @@
 					changes.Add (bci);
 				}
-				CommonMappingFunctions.GetGameManager ().SetBlocksRPC (changes);
+				GameManager.Instance.SetBlocksRPC (changes);
 
-				m_Console.SendResult ("Tried to remove #" + changes.Count + " land protection blocks for player \"" + _id + "\". Note "+
+				SdtdConsole.Instance.Output ("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);
+				SdtdConsole.Instance.Output("  listlandprotection " + _id);
 			} catch (Exception e) {
 				Log.Out ("Error in RemoveLandProtection.removeById: " + e);
@@ -50,5 +46,5 @@
 		}
 
-		private void removeByPosition (string[] _coords)
+		private void removeByPosition (List<string> _coords)
 		{
 			try {
@@ -61,5 +57,5 @@
 
 				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");
+					SdtdConsole.Instance.Output ("At least one of the given coordinates is not a valid integer");
 					return;
 				}
@@ -67,9 +63,9 @@
 				Vector3i v = new Vector3i (x, y, z);
 
-				PersistentPlayerList ppl = CommonMappingFunctions.GetGameManager ().GetPersistentPlayerList ();
+				PersistentPlayerList ppl = GameManager.Instance.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.");
+					SdtdConsole.Instance.Output ("No land protection block at the given position or not a valid position. Use \"listlandprotection\" to get a list of keystones.");
 					return;
 				}
@@ -80,7 +76,7 @@
 				changes.Add (bci);
 
-				CommonMappingFunctions.GetGameManager ().SetBlocksRPC (changes);
+				GameManager.Instance.SetBlocksRPC (changes);
 
-				m_Console.SendResult ("Land protection block at (" + v.ToString () + ") removed");
+				SdtdConsole.Instance.Output ("Land protection block at (" + v.ToString () + ") removed");
 			} catch (Exception e) {
 				Log.Out ("Error in RemoveLandProtection.removeByPosition: " + e);
@@ -88,13 +84,13 @@
 		}
 
-		public override void Run (string[] _params)
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
 			try {
-				if (_params.Length == 1) {
+				if (_params.Count == 1) {
 					removeById (_params [0]);
-				} else if (_params.Length == 3) {
+				} else if (_params.Count == 3) {
 					removeByPosition (_params);
 				} else {
-					m_Console.SendResult ("Usage: removelandprotection <x> <y> <z>  OR  removelandprotection <steamid>");
+					SdtdConsole.Instance.Output ("Usage: removelandprotection <x> <y> <z>  OR  removelandprotection <steamid>");
 				}
 			} catch (Exception e) {
Index: binary-improvements/AllocsCommands/Commands/Reply.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/Reply.cs	(revision 228)
+++ binary-improvements/AllocsCommands/Commands/Reply.cs	(revision 230)
@@ -4,68 +4,43 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class Reply : ConsoleCommand
+	public class Reply : ConsoleCmdAbstract
 	{
-		public Reply (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "send a message to  the player who last sent you a PM";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "reply", "re" };
 		}
 
-		private void SendMessage (ClientInfo _receiver, ClientInfo _sender, string _message)
+		private void RunInternal (ClientInfo _sender, List<string> _params)
 		{
-			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>");
+			if (_params.Count < 1) {
+				SdtdConsole.Instance.Output ("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);
+			if (receiver != null && receiver.clientId >= 0) {
+				Chat.SendMessage (receiver, _sender, message);
 			} else {
 				if (receiver != null) {
-					m_Console.SendResult ("The sender of the PM you last received is currently not online.");
+					SdtdConsole.Instance.Output ("The sender of the PM you last received is currently not online.");
 				} else {
-					m_Console.SendResult ("You have not received a PM so far.");
+					SdtdConsole.Instance.Output ("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 Execute (List<string> _params, CommandSenderInfo _senderInfo) {
+			if (_senderInfo.RemoteClientInfo == null) {
+				Log.Out ("Command \"reply\" can only be used on clients!");
+			} else {
+				RunInternal (_senderInfo.RemoteClientInfo, _params);
 			}
-		}
-
-		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 228)
+++ binary-improvements/AllocsCommands/Commands/SayToPlayer.cs	(revision 230)
@@ -4,69 +4,41 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class SayToPlayer : ConsoleCommand
+	public class SayToPlayer : ConsoleCmdAbstract
 	{
-		public SayToPlayer (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "send a message to a single player";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "sayplayer", "pm" };
 		}
 
-		private void SendMessage (ClientInfo _receiver, ClientInfo _sender, string _message)
+		private void RunInternal (ClientInfo _sender, List<string> _params)
 		{
-			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>");
+			if (_params.Count < 2) {
+				SdtdConsole.Instance.Output ("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);
+			ClientInfo receiver = ConsoleHelper.ParseParamIdOrName (_params [0]);
 			if (receiver != null) {
-				SendMessage (receiver, _sender, message);
+				Chat.SendMessage (receiver, _sender, message);
 			} else {
-				m_Console.SendResult ("Playername or entity ID not found.");
+				SdtdConsole.Instance.Output ("Playername or entity ID not found.");
 			}
 		}
 
-		public override void ExecuteRemote (string _sender, string[] _params)
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
 			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);
+				if (_senderInfo.RemoteClientInfo != null) {
+					RunInternal (_senderInfo.RemoteClientInfo, _params);
+				} else {
+					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 228)
+++ 	(revision )
@@ -1,67 +1,0 @@
-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 228)
+++ binary-improvements/AllocsCommands/Commands/ShowInventory.cs	(revision 230)
@@ -5,25 +5,21 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class ShowInventory : ConsoleCommand
+	public class ShowInventory : ConsoleCmdAbstract
 	{
-		public ShowInventory (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "list inventory of a given player (steam id, entity id or name)";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "showinventory", "si" };
 		}
 
-		public override void Run (string[] _params)
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
 			try {
-				if (_params.Length < 1) {
-					m_Console.SendResult ("Usage: showinventory <steamid|playername|entityid>");
+				if (_params.Count < 1) {
+					SdtdConsole.Instance.Output ("Usage: showinventory <steamid|playername|entityid>");
 					return;
 				}
@@ -31,5 +27,5 @@
 				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).");
+					SdtdConsole.Instance.Output ("Playername or entity/steamid id not found or no inventory saved (first saved after a player has been online for 30s).");
 					return;
 				}
@@ -38,16 +34,16 @@
 				PersistentData.Inventory inv = p.Inventory;
 
-				m_Console.SendResult ("Belt of player " + p.Name + ":");
+				SdtdConsole.Instance.Output ("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));
+						SdtdConsole.Instance.Output (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 + ":");
+				SdtdConsole.Instance.Output (string.Empty);
+				SdtdConsole.Instance.Output ("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));
+						SdtdConsole.Instance.Output (string.Format ("    Slot {0}: {1:000} * {2}", i, inv.bag [i].count, inv.bag [i].itemName));
 				}
-				m_Console.SendResult (string.Empty);
+				SdtdConsole.Instance.Output (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 228)
+++ binary-improvements/AllocsCommands/Commands/TeleportPlayer.cs	(revision 230)
@@ -1,3 +1,2 @@
-using AllocsFixes.PersistentData;
 using System;
 using System.Collections.Generic;
@@ -6,38 +5,31 @@
 namespace AllocsFixes.CustomCommands
 {
-	public class TeleportPlayer : ConsoleCommand
+	public class TeleportPlayer : ConsoleCmdAbstract
 	{
-		public TeleportPlayer (ConsoleSdtd cons) : base(cons)
-		{
-		}
-
-		public override string Description ()
+		public override string GetDescription ()
 		{
 			return "teleport a player to a given location";
 		}
 
-		public override string[] Names ()
+		public override string[] GetCommands ()
 		{
 			return new string[] { "teleportplayer", "tele" };
 		}
 
-		public override void Run (string[] _params)
+		public override void Execute (List<string> _params, CommandSenderInfo _senderInfo)
 		{
 			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>");
+				if (_params.Count != 4 && _params.Count != 2) {
+					SdtdConsole.Instance.Output ("Usage: teleportplayer <entityid|playername|steamid> <x> <y> <z>");
+					SdtdConsole.Instance.Output ("   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.");
+					ClientInfo ci1 = ConsoleHelper.ParseParamIdOrName (_params [0]);
+					if (ci1 == null) {
+						SdtdConsole.Instance.Output ("Playername or entity/steamid id not found.");
 						return;
 					}
-					if (!p1.IsOnline) {
-						m_Console.SendResult ("Player not online.");
-						return;
-					}
+					EntityPlayer ep1 = GameManager.Instance.World.Players.dict [ci1.entityId];
 
-					if (_params.Length == 4) {
+					if (_params.Count == 4) {
 						int x = int.MinValue;
 						int y = int.MinValue;
@@ -49,30 +41,27 @@
 
 						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");
+							SdtdConsole.Instance.Output ("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;
+						ep1.position.x = x;
+						ep1.position.y = y;
+						ep1.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.");
+						ClientInfo ci2 = ConsoleHelper.ParseParamIdOrName (_params [1]);
+						if (ci2 == null) {
+							SdtdConsole.Instance.Output ("Target playername or entity/steamid id not found.");
 							return;
 						}
-						if (!p2.IsOnline) {
-							m_Console.SendResult ("Target player not online.");
-							return;
-						}
+						EntityPlayer ep2 = GameManager.Instance.World.Players.dict [ci2.entityId];
 
-						p1.Entity.position = p2.Entity.GetPosition();
-						p1.Entity.position.y += 1;
-						p1.Entity.position.z += 1;
+						ep1.position = ep2.GetPosition();
+						ep1.position.y += 1;
+						ep1.position.z += 1;
 					}
 
-					NetPackage_EntityTeleport pkg = new NetPackage_EntityTeleport (p1.Entity);
+					NetPackage_EntityTeleport pkg = new NetPackage_EntityTeleport (ep1);
 
-					ConnectionManager.Instance.SendPackage (pkg, new PackageDestinationSingleEntityID (p1.ClientInfo.entityId));
+					ci1.netConnection [0].AddToSendQueue (pkg);
 				}
 			} catch (Exception e) {
Index: binary-improvements/AllocsCommands/Commands/Unban.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/Unban.cs	(revision 228)
+++ 	(revision )
@@ -1,49 +1,0 @@
-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/AllocsCommands/ModInfo.xml
===================================================================
--- binary-improvements/AllocsCommands/ModInfo.xml	(revision 230)
+++ binary-improvements/AllocsCommands/ModInfo.xml	(revision 230)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<xml>
+	<ModInfo>
+		<Name value="Allocs command extensions" />
+		<Description value="Additional commands for server operation" />
+		<Author value="Christian 'Alloc' Illy" />
+		<Version value="1" />
+		<Website value="http://7dtd.illy.bz" />
+	</ModInfo>
+</xml>
Index: binary-improvements/AllocsCommands/PrivateMassageConnections.cs
===================================================================
--- binary-improvements/AllocsCommands/PrivateMassageConnections.cs	(revision 230)
+++ binary-improvements/AllocsCommands/PrivateMassageConnections.cs	(revision 230)
@@ -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;
+		}
+	}
+}
