Index: /binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj
===================================================================
--- /binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj	(revision 144)
@@ -94,6 +94,9 @@
     <Compile Include="src\CustomCommands\EnableRendering.cs" />
     <Compile Include="src\PersistentData\PersistentContainer.cs" />
-    <Compile Include="src\PersistentData\KnownPlayers.cs" />
     <Compile Include="src\StateManager.cs" />
+    <Compile Include="src\PersistentData\InvItem.cs" />
+    <Compile Include="src\PersistentData\Inventory.cs" />
+    <Compile Include="src\PersistentData\Players.cs" />
+    <Compile Include="src\PersistentData\Player.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
Index: /binary-improvements/7dtd-server-fixes/src/AllocsLogFunctions.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/AllocsLogFunctions.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/AllocsLogFunctions.cs	(revision 144)
@@ -1,2 +1,3 @@
+using AllocsFixes.PersistentData;
 using System;
 using System.Collections.Generic;
@@ -13,4 +14,5 @@
 				int entityId = CommonMappingFunctions.GetEntityID (ci);
 				EntityPlayer ep = CommonMappingFunctions.GetEntityPlayer (ci);
+				string steamId = CommonMappingFunctions.GetSteamID (ci);
 
 				string ip = ci.networkPlayer.ipAddress;
@@ -23,9 +25,23 @@
 					", entityid=" + entityId +
 					", name=" + name +
-					", steamid=" + CommonMappingFunctions.GetSteamID (ci) +
+					", steamid=" + steamId +
 					", ip=" + ip
 				);
+
+				PersistentContainer.Instance.Players[steamId].SetOnline(ci);
 			} catch (Exception e) {
-				Log.Out ("Error in RequestToSpawnPlayer: " + e);
+				Log.Out ("Error in AllocsLogFunctions.RequestToSpawnPlayer: " + e);
+			}
+		}
+
+		public static void PlayerDisconnected (GameManager manager, int _clientId) {
+			try {
+				ClientInfo ci = CommonMappingFunctions.GetClientInfoFromClientID (_clientId);
+				string steamId = CommonMappingFunctions.GetSteamID (ci);
+				Players players = PersistentContainer.Instance.Players;
+				if (players.SteamIDs.Contains(steamId))
+					players[steamId].SetOffline();
+			} catch (Exception e) {
+				Log.Out ("Error in AllocsLogFunctions.PlayerDisconnected: " + e);
 			}
 		}
Index: /binary-improvements/7dtd-server-fixes/src/CommonMappingFunctions.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/CommonMappingFunctions.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/CommonMappingFunctions.cs	(revision 144)
@@ -136,14 +136,19 @@
 		{
 			try {
-				int entityId = -1;
-				if (int.TryParse (_nameOrId, out entityId)) {
-					ClientInfo ci = GetClientInfoFromEntityID (entityId);
-					if (ci != null)
-						return ci;
+				long tempLong;
+				if (_nameOrId.Length == 17 && long.TryParse (_nameOrId, out tempLong)) {
+					return GetClientInfoFromSteamID (_nameOrId);
+				} else {
+					int entityId = -1;
+					if (int.TryParse (_nameOrId, out entityId)) {
+						ClientInfo ci = GetClientInfoFromEntityID (entityId);
+						if (ci != null)
+							return ci;
+					}
+
+					return GetClientInfoFromPlayerName (_nameOrId, ignoreColorcodes);
 				}
-
-				return GetClientInfoFromPlayerName (_nameOrId, ignoreColorcodes);
 			} catch (Exception e) {
-				Log.Out ("Error getting ClientInfo for entity ID or player name: " + e);
+				Log.Out ("Error getting ClientInfo for steam ID / entity ID / player name \"" + _nameOrId + "\": " + e);
 			}
 			return null;
Index: /binary-improvements/7dtd-server-fixes/src/CustomCommands/ListPlayersExtended.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/CustomCommands/ListPlayersExtended.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/CustomCommands/ListPlayersExtended.cs	(revision 144)
@@ -32,34 +32,34 @@
 					}
 					m_Console.SendResult (string.Concat (new object[]
-			{
-				string.Empty,
-				++num,
-				". id=",
-				current.Value.fd008f,
-				", ",
-				current.Value.EntityName,
-				", pos=",
-				current.Value.GetPosition (),
-				", rot=",
-				current.Value.rotation,
-				", remote=",
-				current.Value.fd00b2,
-				", health=",
-				current.Value.Health,
-				", deaths=",
-				current.Value.Died,
-				", zombies=",
-				current.Value.KilledZombies,
-				", players=",
-				current.Value.KilledPlayers,
-				", score=",
-				current.Value.Score,
-				", steamid=",
-				CommonMappingFunctions.GetSteamID (ci),
-				", ip=",
-				ip,
-				", ping=",
-				current.Value.pingToServer
-			}
+						{
+							string.Empty,
+							++num,
+							". id=",
+							current.Value.fd008f,
+							", ",
+							current.Value.EntityName,
+							", pos=",
+							current.Value.GetPosition (),
+							", rot=",
+							current.Value.rotation,
+							", remote=",
+							current.Value.fd00b2,
+							", health=",
+							current.Value.Health,
+							", deaths=",
+							current.Value.Died,
+							", zombies=",
+							current.Value.KilledZombies,
+							", players=",
+							current.Value.KilledPlayers,
+							", score=",
+							current.Value.Score,
+							", steamid=",
+							CommonMappingFunctions.GetSteamID (ci),
+							", ip=",
+							ip,
+							", ping=",
+							current.Value.pingToServer
+						}
 					)
 					);
Index: /binary-improvements/7dtd-server-fixes/src/CustomCommands/ShowInventory.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/CustomCommands/ShowInventory.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/CustomCommands/ShowInventory.cs	(revision 144)
@@ -1,2 +1,3 @@
+using AllocsFixes.PersistentData;
 using System;
 using System.Collections.Generic;
@@ -6,14 +7,11 @@
 	public class ShowInventory : ConsoleCommand
 	{
-		private GameManager manager;
-
 		public ShowInventory (ConsoleSdtd cons) : base(cons)
 		{
-			manager = m_Console.gameManager;
 		}
 
 		public override string Description ()
 		{
-			return "list inventory of a given player (entity id or name)";
+			return "list inventory of a given player (steam id, entity id or name)";
 		}
 
@@ -27,38 +25,32 @@
 			try {
 				if (_params.Length < 1) {
-					m_Console.SendResult ("Usage: showinventory <playername|entityid>");
+					m_Console.SendResult ("Usage: showinventory <steamid|playername|entityid>");
 					return;
 				}
 
-				int entityId = -1;
-				PlayerDataStuff.PlayerItems items = null;
-				if (int.TryParse (_params [0], out entityId)) {
-					items = PlayerDataStuff.GetPlayerItems (entityId);
-				}
-
-				if (items == null) {
-					string playerName = _params [0].ToLower ();
-					foreach (KeyValuePair<int, EntityPlayer> kvp in manager.World.playerEntities.dict) {
-						if (kvp.Value.EntityName.ToLower ().Equals (playerName)) {
-							entityId = kvp.Key;
-							break;
-						}
-					}
-				}
-				items = PlayerDataStuff.GetPlayerItems (entityId);
-
-				if (items == null) {
-					m_Console.SendResult ("Playername or entity id not found or no inventory saved (first saved after a player has been online for 30s).");
+				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;
 				}
 
+				Log.Out ( "SteamID: " + steamid);
+
+				Player p = PersistentContainer.Instance.Players[steamid];
+
+				Log.Out ("Player");
+
+				PersistentData.Inventory inv = p.Inventory;
+
+				Log.Out ("Inv");
+
 				m_Console.SendResult ("Belt of player:");
-				foreach (KeyValuePair<string, int> kvp in items.belt) {
-					m_Console.SendResult (string.Format ("    {0:000} * {1}", kvp.Value, kvp.Key));
+				for (int i = 0; i < inv.belt.Count; i++) {
+					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:");
-				foreach (KeyValuePair<string, int> kvp in items.bag) {
-					m_Console.SendResult (string.Format ("    {0:000} * {1}", kvp.Value, kvp.Key));
+				for (int i = 0; i < inv.bag.Count; i++) {
+					m_Console.SendResult (string.Format ("    Slot {0}: {1:000} * {2}", i, inv.bag[i].count, inv.bag[i].itemName));
 				}
 				m_Console.SendResult (string.Empty);
Index: /binary-improvements/7dtd-server-fixes/src/MapRendering/Constants.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/MapRendering/Constants.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/MapRendering/Constants.cs	(revision 144)
@@ -3,5 +3,5 @@
 namespace AllocsFixes.MapRendering
 {
-	public class Constants
+	public static class Constants
 	{
 		public const int MAP_BLOCK_SIZE = 128;
Index: /binary-improvements/7dtd-server-fixes/src/MapRendering/MapRendering.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/MapRendering/MapRendering.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/MapRendering/MapRendering.cs	(revision 144)
@@ -36,5 +36,5 @@
 
 			chunkSaveTimer.AutoReset = false;
-			chunkSaveTimer.Elapsed += new System.Timers.ElapsedEventHandler (RenderDirtyChunks);
+			chunkSaveTimer.Elapsed += new System.Timers.ElapsedEventHandler (TimedRendering);
 		}
 
@@ -130,14 +130,13 @@
 						}
 					}
+
+					while (dirtyChunks.Count > 0) {
+						RenderDirtyChunks ();
+					}
+
 					Log.Out (String.Format ("RenderMap: {0}/{1} ({2}%)", curFullMapPos.x, widthPix, (int)((float)curFullMapPos.x / widthPix * 100)));
 				}
 			} finally {
 				Monitor.Exit (Instance.zoomLevelBuffers);
-			}
-			int totalDirtyCount = dirtyChunks.Count;
-			Log.Out (String.Format ("Rendering chunks: {0}/{1} ({2}%)", totalDirtyCount - dirtyChunks.Count, totalDirtyCount, (int)((float)(totalDirtyCount - dirtyChunks.Count) / totalDirtyCount * 100)));
-			while (dirtyChunks.Count > 0) {
-				RenderDirtyChunks (null, null);
-				Log.Out (String.Format ("Rendering chunks: {0}/{1} ({2}%)", totalDirtyCount - dirtyChunks.Count, totalDirtyCount, (int)((float)(totalDirtyCount - dirtyChunks.Count) / totalDirtyCount * 100)));
 			}
 
@@ -162,49 +161,52 @@
 		}
 
-		private void RenderDirtyChunks (object source, System.Timers.ElapsedEventArgs e)
+		private void TimedRendering (object source, System.Timers.ElapsedEventArgs e)
 		{
 			Monitor.Enter (zoomLevelBuffers);
 			try {
-				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, blockOffset;
-					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, v_blockOffset;
-					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);
-				}
-
-				if (e != null)
+				RenderDirtyChunks ();
 				if (dirtyChunks.Count > 0)
 					Instance.chunkSaveTimer.Start ();
 			} finally {
 				Monitor.Exit (zoomLevelBuffers);
+			}
+		}
+
+		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, blockOffset;
+				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, v_blockOffset;
+				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);
 			}
 		}
Index: /binary-improvements/7dtd-server-fixes/src/PersistentData/InvItem.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/PersistentData/InvItem.cs	(revision 144)
+++ /binary-improvements/7dtd-server-fixes/src/PersistentData/InvItem.cs	(revision 144)
@@ -0,0 +1,17 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace AllocsFixes.PersistentData
+{
+	[Serializable]
+	public class InvItem
+	{
+		public string itemName;
+		public int count;
+
+		public InvItem (string itemName, int count)
+		{
+		}
+	}
+}
+
Index: /binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs	(revision 144)
+++ /binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs	(revision 144)
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Threading;
+
+namespace AllocsFixes.PersistentData
+{
+	[Serializable]
+	public class Inventory
+	{
+		public List<InvItem> bag;
+		public List<InvItem> belt;
+
+		public Inventory ()
+		{
+			bag = new List<InvItem> ();
+			belt = new List<InvItem> ();
+		}
+
+		public void Update (PlayerDataFile pdf)
+		{
+			Log.Out ("Updating player inventory - player id: " + pdf.id);
+			ProcessInv (bag, pdf.bag);
+			ProcessInv (belt, pdf.inventory);
+			Log.Out ("Now: belt: " + belt.Count + " - bag: " + bag.Count);
+		}
+
+		private void ProcessInv (List<InvItem> target, InventoryField[] sourceFields)
+		{
+			Monitor.Enter (target);
+			try {
+				target.Clear ();
+				for (int i = 0; i < sourceFields.Length; i++) {
+					if (sourceFields [i].count > 0) {
+						int count = sourceFields [i].count;
+						string name = getInvFieldName (sourceFields [i]);
+
+						target.Add (new InvItem (name, count));
+					} else {
+						target.Add (null);
+					}
+				}
+			} finally {
+				Monitor.Exit (target);
+			}
+		}
+
+		private string getInvFieldName (InventoryField item)
+		{
+			ItemBase iBase = ItemBase.list [item.itemValue.type];
+			string name = iBase.name;
+			if (iBase.IsBlock ()) {
+				ItemBlock iBlock = (ItemBlock)iBase;
+				name = iBlock.GetItemName (item.itemValue);
+			}
+			return name;
+		}
+
+
+	}
+}
+
Index: nary-improvements/7dtd-server-fixes/src/PersistentData/KnownPlayers.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/PersistentData/KnownPlayers.cs	(revision 143)
+++ 	(revision )
@@ -1,23 +1,0 @@
-using System;
-using System.Runtime.Serialization;
-
-namespace AllocsFixes.PersistentData
-{
-	[Serializable]
-	public class KnownPlayers
-	{
-		private int entityId;
-		private string name;
-
-		public KnownPlayers ()
-		{
-		}
-
-		public KnownPlayers (SerializationInfo info, StreamingContext ctxt)
-		{
-			this.entityId = info.GetInt32 ("entityId");
-			this.name = info.GetString ("name");
-		}
-	}
-}
-
Index: /binary-improvements/7dtd-server-fixes/src/PersistentData/PersistentContainer.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/PersistentData/PersistentContainer.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/PersistentData/PersistentContainer.cs	(revision 144)
@@ -1,4 +1,3 @@
 using System;
-using System.Collections.Generic;
 using System.IO;
 using System.Runtime.Serialization;
@@ -10,5 +9,14 @@
 	public class PersistentContainer
 	{
-		public Dictionary<string, KnownPlayers> players = new Dictionary<string, KnownPlayers> ();
+		private Players players;
+
+		public Players Players {
+			get {
+				if (players == null)
+					players = new Players ();
+				return players;
+			}
+		}
+
 		private static PersistentContainer instance;
 
@@ -24,5 +32,4 @@
 		private PersistentContainer ()
 		{
-			Log.Out ("new PersistentContainer()");
 		}
 
Index: /binary-improvements/7dtd-server-fixes/src/PersistentData/Player.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/PersistentData/Player.cs	(revision 144)
+++ /binary-improvements/7dtd-server-fixes/src/PersistentData/Player.cs	(revision 144)
@@ -0,0 +1,99 @@
+using System;
+using System.Runtime.Serialization;
+using UnityEngine;
+
+namespace AllocsFixes.PersistentData
+{
+	[Serializable]
+	public class Player
+	{
+		private readonly string steamId;
+		private int entityId;
+		private string name;
+		private string ip;
+		private long totalPlayTime;
+		private Inventory inventory;
+		[NonSerialized]
+		private ClientInfo
+			clientInfo;
+
+		public string SteamID {
+			get { return steamId; }
+		}
+
+		public int EntityID {
+			get { return entityId; }
+			set { entityId = value; }
+		}
+
+		public string Name {
+			get { return name; }
+			set { name = value; }
+		}
+
+		public string IP {
+			get { return ip; }
+			set { ip = value; }
+		}
+
+		public Inventory Inventory {
+			get {
+				if (inventory == null)
+					inventory = new Inventory ();
+				return inventory;
+			}
+		}
+
+		public bool IsOnline {
+			get { return clientInfo != null; }
+		}
+
+		public ClientInfo ClientInfo {
+			get { return clientInfo; }
+		}
+
+		public EntityPlayer Entity {
+			get {
+				if (IsOnline) {
+					return CommonMappingFunctions.GetEntityPlayer (clientInfo);
+				} else {
+					return null;
+				}
+			}
+		}
+
+		public long TotalPlayTime {
+			get {
+				if (IsOnline) {
+					return totalPlayTime + (long)(Time.timeSinceLevelLoad - Entity.CreationTimeSinceLevelLoad);
+				} else {
+					return totalPlayTime;
+				}
+			}
+		}
+
+		public void SetOffline ()
+		{
+			Log.Out ("Player set to offline: " + steamId);
+			totalPlayTime += (long)(Time.timeSinceLevelLoad - Entity.CreationTimeSinceLevelLoad);
+			clientInfo = null;
+		}
+
+		public void SetOnline (ClientInfo ci)
+		{
+			Log.Out ("Player set to online: " + steamId);
+			clientInfo = ci;
+			entityId = CommonMappingFunctions.GetEntityID (ci);
+			name = CommonMappingFunctions.GetPlayerName (ci);
+			ip = ci.networkPlayer.ipAddress;
+		}
+
+		public Player (string steamId)
+		{
+			this.steamId = steamId;
+			this.inventory = new Inventory ();
+		}
+
+
+	}
+}
Index: /binary-improvements/7dtd-server-fixes/src/PersistentData/Players.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/PersistentData/Players.cs	(revision 144)
+++ /binary-improvements/7dtd-server-fixes/src/PersistentData/Players.cs	(revision 144)
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text.RegularExpressions;
+
+namespace AllocsFixes.PersistentData
+{
+	[Serializable]
+	public class Players
+	{
+		private Dictionary<string, Player> players = new Dictionary<string, Player> ();
+
+		public Player this [string steamId] {
+			get {
+				if (players.ContainsKey (steamId))
+					return players [steamId];
+				else {
+					if (steamId != null && steamId.Length == 17) {
+						Log.Out ("Created new player entry for ID: " + steamId);
+						Player p = new Player (steamId);
+						players.Add (steamId, p);
+						return p;
+					}
+					return null;
+				}
+			}
+		}
+
+		public List<string> SteamIDs {
+			get { return new List<string> (players.Keys); }
+		}
+
+		public string GetSteamID (string _nameOrId, bool _ignoreColorCodes)
+		{
+			if (_nameOrId == null || _nameOrId.Length == 0)
+				return null;
+
+			long tempLong;
+			if (_nameOrId.Length == 17 && long.TryParse (_nameOrId, out tempLong)) {
+				return _nameOrId;
+			} else {
+				int entityId = -1;
+				if (int.TryParse (_nameOrId, out entityId)) {
+					foreach (KeyValuePair<string, Player> kvp in players) {
+						if (kvp.Value.IsOnline && kvp.Value.EntityID == entityId) {
+							return kvp.Key;
+						}
+					}
+
+					_nameOrId = _nameOrId.ToLower ();
+					foreach (KeyValuePair<string, Player> kvp in players) {
+						string name = kvp.Value.Name.ToLower ();
+						if (_ignoreColorCodes) {
+							name = Regex.Replace (name, "\\[[0-9a-fA-F]{6}\\]", "");
+						}
+						if (kvp.Value.IsOnline && kvp.Value.Name.Equals (name)) {
+							return kvp.Key;
+						}
+					}
+				}
+			}
+			return null;
+		}
+	}
+}
+
Index: /binary-improvements/7dtd-server-fixes/src/PlayerDataStuff.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/PlayerDataStuff.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/PlayerDataStuff.cs	(revision 144)
@@ -1,2 +1,3 @@
+using AllocsFixes.PersistentData;
 using System;
 using System.Collections.Generic;
@@ -6,98 +7,17 @@
 	public class PlayerDataStuff
 	{
-		public class PlayerItems
-		{
-			public SortedList<string, int> belt = new SortedList<string, int> ();
-			public SortedList<string, int> bag = new SortedList<string, int> ();
-
-			public PlayerItems (InventoryField[] _belt, InventoryField[] _bag)
-			{
-				foreach (InventoryField item in _belt) {
-					if (item.count > 0) {
-						string name = getInvFieldName (item);
-						if (belt.ContainsKey (name)) {
-							belt [name] += item.count;
-						} else {
-							belt.Add (name, item.count);
-						}
-					}
-				}
-
-				foreach (InventoryField item in _bag) {
-					if (item.count > 0) {
-						string name = getInvFieldName (item);
-						if (bag.ContainsKey (name)) {
-							bag [name] += item.count;
-						} else {
-							bag.Add (name, item.count);
-						}
-					}
-				}
-			}
-		};
-
-		private static Dictionary<int, PlayerItems> itemsPerEntityId = new Dictionary<int, PlayerItems> ();
-
-		public static PlayerItems GetPlayerItems (int entityId)
-		{
-			if (itemsPerEntityId.ContainsKey (entityId))
-				return itemsPerEntityId [entityId];
-			else
-				return null;
-		}
 
 		public static void GM_SavePlayerData (GameManager manager, int _clientId, PlayerDataFile _playerDataFile)
 		{
 			try {
-				int entityId = CommonMappingFunctions.GetEntityID (CommonMappingFunctions.GetClientInfoFromClientID (_clientId));
-				if (entityId >= 0) {
-					Log.Out ("Saving playerData for entity id: " + entityId);
-
-					if (itemsPerEntityId.ContainsKey (entityId))
-						itemsPerEntityId.Remove (entityId);
-					itemsPerEntityId.Add (entityId, new PlayerItems (_playerDataFile.inventory, _playerDataFile.bag));
-				}
+				ClientInfo ci = CommonMappingFunctions.GetClientInfoFromClientID(_clientId);
+				string steamId = CommonMappingFunctions.GetSteamID(ci);
+				PersistentContainer.Instance.Players[steamId].Inventory.Update(_playerDataFile);
 			} catch (Exception e) {
 				Log.Out ("Error in GM_SavePlayerData: " + e);
 			}
-
-//		Log.Out ("Inventory of player:");
-//		for (int i = 0; i < _playerDataFile.inventory.Length; i++) {
-//			InventoryField item = _playerDataFile.inventory [i];
-//			printItem (item, i);
-//		}
-//
-//		Log.Out ("Bag of player:");
-//		for (int i = 0; i < _playerDataFile.bag.Length; i++) {
-//			InventoryField item = _playerDataFile.bag [i];
-//			printItem (item, i);
-//		}
 		}
 
-		private static string getInvFieldName (InventoryField item)
-		{
-			ItemBase iBase = ItemBase.list [item.itemValue.type];
-			string name = iBase.name;
-			if (iBase.IsBlock ()) {
-				ItemBlock iBlock = (ItemBlock)iBase;
-				name = iBlock.GetItemName (item.itemValue);
-			}
-			return name;
-		}
 
-		private static void printItem (InventoryField item, int slot)
-		{
-			if (item.count > 0) {
-				ItemBase iBase = ItemBase.list [item.itemValue.type];
-				string name = iBase.name;
-				if (iBase.IsBlock ()) {
-					ItemBlock iBlock = (ItemBlock)iBase;
-					name = iBlock.GetItemName (item.itemValue);
-				}
-				Log.Out (string.Format ("Slot {0:00}: {1:00} * {2}, blockinst={3}, meta={4}, type={5}, usetimes={6}",
-			                        slot, item.count, name, item.itemValue.blockinst, item.itemValue.meta, item.itemValue.type, item.itemValue.usetimes)
-				);
-			}
-		}
 	}
 }
Index: /binary-improvements/7dtd-server-fixes/src/StateManager.cs
===================================================================
--- /binary-improvements/7dtd-server-fixes/src/StateManager.cs	(revision 143)
+++ /binary-improvements/7dtd-server-fixes/src/StateManager.cs	(revision 144)
@@ -10,5 +10,4 @@
 				CommandExtensions.InitCommandExtensions (manager);
 				PersistentData.PersistentContainer.Load ();
-				PersistentData.PersistentContainer.Instance.players.Add("123", new AllocsFixes.PersistentData.KnownPlayers());
 			} catch (Exception e) {
 				Log.Out ("Error in StateManager.Awake: " + e);
Index: /binary-improvements/assembly-patcher/Main.cs
===================================================================
--- /binary-improvements/assembly-patcher/Main.cs	(revision 143)
+++ /binary-improvements/assembly-patcher/Main.cs	(revision 144)
@@ -64,4 +64,5 @@
 			TypeDefinition type = module.GetType ("GameManager");
 			addHook (type, "RequestToSpawnPlayer", true, 5, true, typeof(AllocsFixes.AllocsLogFunctions).GetMethod ("RequestToSpawnPlayer"));
+			addHook (type, "PlayerDisconnected", true, 1, false, typeof(AllocsFixes.AllocsLogFunctions).GetMethod ("PlayerDisconnected"));
 		}
 
Index: /binary-improvements/bin/Release/7dtd-server-fixes_version.txt
===================================================================
--- /binary-improvements/bin/Release/7dtd-server-fixes_version.txt	(revision 143)
+++ /binary-improvements/bin/Release/7dtd-server-fixes_version.txt	(revision 144)
@@ -1,1 +1,1 @@
-Version:       0.91.5355.28079
+Version:       0.91.5355.32677
