Index: binary-improvements/7dtd-binaries/README.txt
===================================================================
--- binary-improvements/7dtd-binaries/README.txt	(revision 250)
+++ binary-improvements/7dtd-binaries/README.txt	(revision 251)
@@ -1,3 +1,3 @@
 Put the Assembly-CSharp.dll, Assembly-CSharp-firstpass.dll, LogLibrary.dll, mscorlib.dll,
-System.dll, System.Xml.dll and UnityEngine.dll from your dedicated server in this folder.
+System.dll, System.Drawing.dll, System.Xml.dll and UnityEngine.dll from your dedicated server in this folder.
 
Index: binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj
===================================================================
--- binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj	(revision 250)
+++ binary-improvements/7dtd-server-fixes/7dtd-server-fixes.csproj	(revision 251)
@@ -1,3 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
+﻿<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
@@ -46,4 +46,8 @@
       <Private>False</Private>
     </Reference>
+    <Reference Include="System.Drawing">
+      <HintPath>..\7dtd-binaries\System.Drawing.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
     <Reference Include="UnityEngine">
       <HintPath>..\7dtd-binaries\UnityEngine.dll</HintPath>
@@ -62,4 +66,6 @@
     <Compile Include="src\AssemblyInfo.cs" />
     <Compile Include="src\AllocsLogFunctions.cs" />
+    <Compile Include="src\LiveData\Animals.cs" />
+    <Compile Include="src\LiveData\Hostiles.cs" />
     <Compile Include="src\PlayerDataStuff.cs" />
     <Compile Include="src\PersistentData\PersistentContainer.cs" />
@@ -86,4 +92,5 @@
     <Compile Include="src\API.cs" />
     <Compile Include="src\ChatHookExample.cs" />
+    <Compile Include="src\PetesUtils.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
Index: binary-improvements/7dtd-server-fixes/src/PersistentData/InvItem.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/PersistentData/InvItem.cs	(revision 250)
+++ binary-improvements/7dtd-server-fixes/src/PersistentData/InvItem.cs	(revision 251)
@@ -11,4 +11,6 @@
 		public int quality;
 		public InvItem[] parts;
+        public string icon = "";
+        public string iconcolor = "";
 
 		public InvItem (string itemName, int count, int quality = -1)
Index: binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs	(revision 250)
+++ binary-improvements/7dtd-server-fixes/src/PersistentData/Inventory.cs	(revision 251)
@@ -72,4 +72,46 @@
 					item = new InvItem (name, _count);
 				}
+
+                // Figure out the icon's name
+                string icon_name = "";
+
+                ItemClass item_class = ItemClass.list [_itemValue.type];
+
+                if (!PetesUtils.ValidText (icon_name)) {
+                    try {
+                        icon_name = item_class.GetIconName ();
+                    }
+                    catch { }
+                }
+
+                if (!PetesUtils.ValidText (icon_name)) {
+                    try {
+                        icon_name = item_class.MeshFile;
+                    }
+                    catch { }
+                }
+
+                if (!PetesUtils.ValidText (icon_name)) {
+                    try {
+                        icon_name = item_class.DropMeshFile;
+                    }
+                    catch { }
+                }
+
+                if (!PetesUtils.ValidText (icon_name))
+                    icon_name = item_class.GetItemName ();
+
+                if (icon_name.Contains ("\\"))
+                    icon_name = icon_name.Substring (icon_name.LastIndexOf ("\"") + 1);
+
+                item.icon = icon_name;
+
+                try {
+                    item.iconcolor = item_class.CustomIconTint.ToHexStringRGB ();
+                }
+                catch {
+                    item.iconcolor = "FFFFFF";
+                }
+                    
 				return item;
 			} else {
@@ -77,7 +119,4 @@
 			}
 		}
-
-
 	}
 }
-
Index: binary-improvements/7dtd-server-fixes/src/PersistentData/Players.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/PersistentData/Players.cs	(revision 250)
+++ binary-improvements/7dtd-server-fixes/src/PersistentData/Players.cs	(revision 251)
@@ -6,5 +6,5 @@
 namespace AllocsFixes.PersistentData
 {
-	[Serializable]
+    [Serializable]
 	public class Players
 	{
Index: binary-improvements/7dtd-server-fixes/src/PetesUtils.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/PetesUtils.cs	(revision 251)
+++ binary-improvements/7dtd-server-fixes/src/PetesUtils.cs	(revision 251)
@@ -0,0 +1,159 @@
+﻿using System;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+
+namespace AllocsFixes
+{
+    public static class PetesUtils {
+        public static bool ValidText(object oText) {
+            if (oText == null)
+                return false;
+
+            if (oText.GetType () == typeof (string)) {
+                if (((string)oText).Trim ().Length < 1)
+                    return false;
+
+                return true;
+            }
+
+            if (oText.ToString ().Trim ().Length < 1)
+                return false;
+
+            return true;
+        }
+
+        // Note: don't forget to dispose the image (which also disposes the underlying stream) when done with the image.
+        public static System.Drawing.Image GetImageFromBytes(byte[] bImage) {
+            if ((bImage == null) || (bImage.Length == 0))
+                return null;
+
+            try {
+                MemoryStream ms = new MemoryStream ();
+                ms.Write (bImage, 0, bImage.Length);
+                ms.Seek (0, SeekOrigin.Begin);
+                Image i = Image.FromStream (ms);
+                return i;
+            }
+            catch { }
+
+            return null;
+        }
+
+        /*
+        public static System.Drawing.Color BlendColors(System.Drawing.Color color, System.Drawing.Color backColor, double amount) {
+            byte r = (byte)((color.R * amount) + backColor.R * (1 - amount));
+            byte g = (byte)((color.G * amount) + backColor.G * (1 - amount));
+            byte b = (byte)((color.B * amount) + backColor.B * (1 - amount));
+            return System.Drawing.Color.FromArgb (r, g, b);
+        }
+        */
+
+        /*
+        public static System.Drawing.Color FromAhsb (int alpha, float hue, float saturation, float brightness)
+        {
+            if (0 > alpha || 255 < alpha) {
+                throw new ArgumentOutOfRangeException ("alpha", alpha, "Value must be within a range of 0 - 255.");
+            }
+
+            if (0f > hue || 360f < hue) {
+                throw new ArgumentOutOfRangeException ("hue", hue, "Value must be within a range of 0 - 360.");
+            }
+
+            if (0f > saturation || 1f < saturation) {
+                throw new ArgumentOutOfRangeException ("saturation", saturation, "Value must be within a range of 0 - 1.");
+            }
+
+            if (0f > brightness || 1f < brightness) {
+                throw new ArgumentOutOfRangeException ("brightness", brightness, "Value must be within a range of 0 - 1.");
+            }
+
+            if (0 == saturation) {
+                return System.Drawing.Color.FromArgb (alpha, Convert.ToInt32 (brightness * 255), Convert.ToInt32 (brightness * 255), Convert.ToInt32 (brightness * 255));
+            }
+
+            float fMax, fMid, fMin;
+            int iSextant, iMax, iMid, iMin;
+
+            if (0.5 < brightness) {
+                fMax = brightness - (brightness * saturation) + saturation;
+                fMin = brightness + (brightness * saturation) - saturation;
+            }
+            else {
+                fMax = brightness + (brightness * saturation);
+                fMin = brightness - (brightness * saturation);
+            }
+
+            iSextant = (int)Math.Floor (hue / 60f);
+            if (300f <= hue)
+                hue -= 360f;
+
+            hue /= 60f;
+            hue -= 2f * (float)Math.Floor (((iSextant + 1f) % 6f) / 2f);
+            
+            if (0 == iSextant % 2)
+                fMid = hue * (fMax - fMin) + fMin;
+            else
+                fMid = fMin - hue * (fMax - fMin);
+
+            iMax = Convert.ToInt32 (fMax * 255);
+            iMid = Convert.ToInt32 (fMid * 255);
+            iMin = Convert.ToInt32 (fMin * 255);
+
+            switch (iSextant) {
+                case 1:
+                    return System.Drawing.Color.FromArgb (alpha, iMid, iMax, iMin);
+                case 2:
+                    return System.Drawing.Color.FromArgb (alpha, iMin, iMax, iMid);
+                case 3:
+                    return System.Drawing.Color.FromArgb (alpha, iMin, iMid, iMax);
+                case 4:
+                    return System.Drawing.Color.FromArgb (alpha, iMid, iMin, iMax);
+                case 5:
+                    return System.Drawing.Color.FromArgb (alpha, iMax, iMin, iMid);
+                default:
+                    return System.Drawing.Color.FromArgb (alpha, iMax, iMid, iMin);
+            }
+        }
+        */
+
+        public static ImageCodecInfo GetEncoderInfo (String mimeType) {
+            ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders ();
+
+            foreach (ImageCodecInfo t in encoders)
+                if (t.MimeType == mimeType)
+                    return t;
+
+            return null;
+        }
+
+        public static byte[] SaveImage_ToBytes (System.Drawing.Image iImage, bool bAndDispose = false)
+        {
+            try {
+                ImageCodecInfo codec = PetesUtils.GetEncoderInfo ("image/png");
+
+                Encoder qualityEncoder = Encoder.Quality;
+                EncoderParameter ratio = new EncoderParameter (qualityEncoder, 100L);
+                EncoderParameters codecParams = new EncoderParameters (1);
+                codecParams.Param [0] = ratio;
+
+                byte[] b = null;
+
+                using (MemoryStream ms = new MemoryStream ()) {
+                    iImage.Save (ms, codec, codecParams);
+
+                    b = ms.ToArray ();
+
+                    if (bAndDispose)
+                        iImage.Dispose ();
+                }
+
+                return b;
+            }
+            catch { }
+
+            return null;
+        }
+
+    }
+}
Index: binary-improvements/AllocsCommands/AllocsCommands.csproj
===================================================================
--- binary-improvements/AllocsCommands/AllocsCommands.csproj	(revision 250)
+++ binary-improvements/AllocsCommands/AllocsCommands.csproj	(revision 251)
@@ -49,5 +49,5 @@
     <Compile Include="Commands\ShowInventory.cs" />
     <Compile Include="Commands\TeleportPlayer.cs" />
-    <Compile Include="PrivateMassageConnections.cs" />
+    <Compile Include="PrivateMessageConnections.cs" />
     <Compile Include="Chat.cs" />
     <Compile Include="Commands\ListItems.cs" />
Index: binary-improvements/AllocsCommands/Chat.cs
===================================================================
--- binary-improvements/AllocsCommands/Chat.cs	(revision 250)
+++ binary-improvements/AllocsCommands/Chat.cs	(revision 251)
@@ -8,5 +8,5 @@
 			string senderName;
 			if (_sender != null) {
-				PrivateMassageConnections.SetLastPMSender (_sender, _receiver);
+				PrivateMessageConnections.SetLastPMSender (_sender, _receiver);
 				senderName = _sender.playerName;
 			} else {
Index: binary-improvements/AllocsCommands/Commands/Reply.cs
===================================================================
--- binary-improvements/AllocsCommands/Commands/Reply.cs	(revision 250)
+++ binary-improvements/AllocsCommands/Commands/Reply.cs	(revision 251)
@@ -31,5 +31,5 @@
 			string message = _params [0];
 
-			ClientInfo receiver = PrivateMassageConnections.GetLastPMSenderForPlayer (_sender);
+			ClientInfo receiver = PrivateMessageConnections.GetLastPMSenderForPlayer (_sender);
 			if (receiver != null) {
 				Chat.SendMessage (receiver, _sender, message);
Index: binary-improvements/AllocsCommands/PrivateMassageConnections.cs
===================================================================
--- binary-improvements/AllocsCommands/PrivateMassageConnections.cs	(revision 250)
+++ 	(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/PrivateMessageConnections.cs
===================================================================
--- binary-improvements/AllocsCommands/PrivateMessageConnections.cs	(revision 251)
+++ binary-improvements/AllocsCommands/PrivateMessageConnections.cs	(revision 251)
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace AllocsFixes.CustomCommands
+{
+	public class PrivateMessageConnections
+	{
+		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/MapRendering/Web/API/GetAnimalsLocation.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetAnimalsLocation.cs	(revision 251)
+++ binary-improvements/MapRendering/Web/API/GetAnimalsLocation.cs	(revision 251)
@@ -0,0 +1,40 @@
+﻿using AllocsFixes.JSON;
+using AllocsFixes.LiveData;
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+    class GetAnimalsLocation : WebAPI
+    {
+        public override void HandleRequest(HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel)
+        {
+            JSONArray animalsJsResult = new JSONArray();
+
+            foreach (EntityAnimal entity in Animals.List)
+            {
+                Vector3i position = new Vector3i(entity.GetPosition());
+
+                JSONObject jsonPOS = new JSONObject();
+                jsonPOS.Add("x", new JSONNumber(position.x));
+                jsonPOS.Add("y", new JSONNumber(position.y));
+                jsonPOS.Add("z", new JSONNumber(position.z));
+
+                JSONObject pJson = new JSONObject();
+                pJson.Add("id", new JSONNumber(entity.entityId));
+
+                if (!string.IsNullOrEmpty(entity.EntityName))
+                    pJson.Add("name", new JSONString(entity.EntityName));
+                else
+                    pJson.Add("name", new JSONString("animal class #" + entity.entityClass.ToString()));
+
+                pJson.Add("position", jsonPOS);
+
+                animalsJsResult.Add(pJson);
+            }
+            
+            WriteJSON(resp, animalsJsResult);
+        }
+    }
+}
Index: binary-improvements/MapRendering/Web/API/GetHostileLocation.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetHostileLocation.cs	(revision 251)
+++ binary-improvements/MapRendering/Web/API/GetHostileLocation.cs	(revision 251)
@@ -0,0 +1,40 @@
+﻿using AllocsFixes.JSON;
+using AllocsFixes.LiveData;
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+    class GetHostileLocation : WebAPI
+    {
+        public override void HandleRequest(HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel)
+        {
+            JSONArray hostilesJsResult = new JSONArray();
+
+            foreach (EntityEnemy entity in Hostiles.List)
+            {
+                Vector3i position = new Vector3i(entity.GetPosition());
+
+                JSONObject jsonPOS = new JSONObject();
+                jsonPOS.Add("x", new JSONNumber(position.x));
+                jsonPOS.Add("y", new JSONNumber(position.y));
+                jsonPOS.Add("z", new JSONNumber(position.z));
+
+                JSONObject pJson = new JSONObject();
+                pJson.Add("id", new JSONNumber(entity.entityId));
+
+                if (!string.IsNullOrEmpty(entity.EntityName))
+                    pJson.Add("name", new JSONString(entity.EntityName));
+                else
+                    pJson.Add("name", new JSONString("enemy class #" + entity.entityClass.ToString()));
+
+                pJson.Add("position", jsonPOS);
+
+                hostilesJsResult.Add(pJson);
+            }
+
+            WriteJSON(resp, hostilesJsResult);
+        }
+    }
+}
Index: binary-improvements/MapRendering/Web/API/GetLandClaims.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetLandClaims.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/API/GetLandClaims.cs	(revision 251)
@@ -11,10 +11,10 @@
 		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel)
 		{
-			string steamid = string.Empty;
+			string ViewersSteamID = string.Empty;
+            ulong lViewersSteamID = 0L;
 
 			if (req.QueryString ["steamid"] != null) {
-				long tempLong;
-				steamid = req.QueryString ["steamid"];
-				if (steamid.Length != 17 || !long.TryParse (steamid, out tempLong)) {
+				ViewersSteamID = req.QueryString ["steamid"];
+                if (ViewersSteamID.Length != 17 || !ulong.TryParse (ViewersSteamID, out lViewersSteamID)) {
 					resp.StatusCode = (int)HttpStatusCode.BadRequest;
 					Web.SetResponseTextContent (resp, "Invalid SteamID given");
@@ -23,4 +23,9 @@
 			}
 
+            // default user, cheap way to avoid 'null reference exception'
+            try { user = user ?? new WebConnection ("", "", 0L); } catch { }
+
+            bool bViewAll = false; try { bViewAll = user.CanViewAllClaims (permissionLevel); } catch { }
+            
 			JSONObject result = new JSONObject ();
 			result.Add ("claimsize", new JSONNumber (GamePrefs.GetInt (EnumGamePrefs.LandClaimSize)));
@@ -33,6 +38,8 @@
 				World w = GameManager.Instance.World;
 				Dictionary<PersistentPlayerData, List<Vector3i>> owners = new Dictionary<PersistentPlayerData, List<Vector3i>> ();
+
+                // Add all owners to this temporary list regardless of permissions
 				foreach (KeyValuePair<Vector3i, PersistentPlayerData> kvp in d) {
-					if (steamid.Length == 0 || kvp.Value.PlayerId.Equals (steamid)) {
+					if (kvp.Value.PlayerId.Equals (ViewersSteamID)) {
 						if (!owners.ContainsKey (kvp.Value)) {
 							owners.Add (kvp.Value, new List<Vector3i> ());
@@ -42,33 +49,40 @@
 				}
 
+                // Loop through all claim owners...
 				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.IsLandProtectionValidForPlayer (kvp.Key);
+                    try
+                    {
+                        // ... but only show us claims that are from the current web user or if the current web user can see all claims regardless of ownership
+                        if (kvp.Key.PlayerId.Equals (ViewersSteamID) || bViewAll)
+                        {
+                            string currentSteamID = kvp.Key.PlayerId;
+                            bool isActive = w.IsLandProtectionValidForPlayer (kvp.Key);
 
-						JSONObject owner = new JSONObject ();
-						claimOwners.Add (owner);
+                            JSONObject owner = new JSONObject ();
+                            claimOwners.Add (owner);
 
-						owner.Add ("steamid", new JSONString (curID));
-						owner.Add ("claimactive", new JSONBoolean (isActive));
+                            owner.Add("steamid", new JSONString (currentSteamID));
+                            owner.Add("claimactive", new JSONBoolean (isActive));
 
-						if (PersistentContainer.Instance.Players [curID, false] != null) {
-							owner.Add ("playername", new JSONString (PersistentContainer.Instance.Players [curID, false].Name));
-						} else {
-							owner.Add ("playername", new JSONNull ());
-						}
+                            if (PersistentContainer.Instance.Players [currentSteamID, false] != null) {
+                                owner.Add("playername", new JSONString (PersistentContainer.Instance.Players [currentSteamID, false].Name));
+                            } else {
+                                owner.Add("playername", new JSONNull ());
+                            }
 
-						JSONArray claims = new JSONArray ();
-						owner.Add ("claims", claims);
+                            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));
+                            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);
-						}
-					}
+                                claims.Add (claim);
+                            }
+                        }
+                    }
+                    catch { }
 				}
 			}
Index: binary-improvements/MapRendering/Web/API/GetPlayerInventory.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayerInventory.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/API/GetPlayerInventory.cs	(revision 251)
@@ -75,6 +75,8 @@
 				JSONObject jsonItem = new JSONObject ();
 				jsonItem.Add ("count", new JSONNumber (_item.count));
-				jsonItem.Add ("name", new JSONString (_item.itemName));
-				jsonItem.Add ("quality", new JSONNumber (_item.quality));
+                jsonItem.Add ("name", new JSONString (_item.itemName));
+                jsonItem.Add ("icon", new JSONString (_item.icon));
+                jsonItem.Add ("iconcolor", new JSONString ((string.IsNullOrEmpty (_item.iconcolor) || _item.iconcolor == "FFFFFF" ? "" : _item.iconcolor)));
+                jsonItem.Add ("quality", new JSONNumber(_item.quality));
 				if (_item.quality >= 0) {
 					jsonItem.Add ("qualitycolor", new JSONString (QualityInfo.GetQualityColorHex (_item.quality)));
Index: binary-improvements/MapRendering/Web/API/GetPlayersLocation.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetPlayersLocation.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/API/GetPlayersLocation.cs	(revision 251)
@@ -11,27 +11,51 @@
 		public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel)
 		{
-			JSONArray playersJsResult = new JSONArray ();
+            AdminTools admTools = null;
+
+            try { admTools = GameManager.Instance.adminTools; } catch { }
+            try { user = user ?? new WebConnection ("", "", 0L); } catch { } // default user, cheap way to avoid 'null reference exception'
+
+            bool bViewAll = false; try { bViewAll = user.CanViewAllPlayers (permissionLevel); } catch { }
+
+            JSONArray playersJsResult = new JSONArray ();
 
 			Players playersList = PersistentContainer.Instance.Players;
 
 			foreach (string sid in playersList.SteamIDs) {
-				Player p = playersList[sid, false];
+                try {
+                    if ((admTools != null) && (PetesUtils.ValidText (sid)))
+                        if (admTools.IsBanned (sid))
+                            continue;
+                }
+                catch { }
 
-				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));
+                try
+                {
+                    Player p = playersList [sid, false];
 
-				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);
+                    ulong player_steam_ID = 0L;
+                    if (!ulong.TryParse (sid, out player_steam_ID))
+                        player_steam_ID = 0L;
 
-				playersJsResult.Add(pJson);
-			}
+                    if ((player_steam_ID == user.SteamID) || bViewAll) {
+                        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));
 
-			WriteJSON(resp, playersJsResult);
+                        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);
+                    }
+                }
+                catch { }
+            }
+
+			WriteJSON (resp, playersJsResult);
 		}
 	}
Index: binary-improvements/MapRendering/Web/API/GetRawEntitiesList.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetRawEntitiesList.cs	(revision 251)
+++ binary-improvements/MapRendering/Web/API/GetRawEntitiesList.cs	(revision 251)
@@ -0,0 +1,174 @@
+﻿using AllocsFixes.JSON;
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+    class GetRawEntitiesList : WebAPI
+    {
+        public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel)
+        {
+            JSONArray entitiesJsResult = new JSONArray ();
+
+            // Yes: hardcoded... even hacking the web interface won't show this data.  You -must- be an admin.
+            if (permissionLevel != 0) {
+                try {
+                    foreach (object base_entity in GameManager.Instance.World.Entities.list) {
+                        try {
+                            Entity entity = (Entity)base_entity;
+
+                            if ((entity.entityType == EntityType.Animal) || (base_entity.GetType () == typeof(EntityAnimal)) || (base_entity.GetType ().ToString ().ToLower ().Contains ("animal")))
+                            {
+                                EntityAnimal ea = (EntityAnimal)entity;
+
+                                Vector3i position = new Vector3i (entity.GetPosition ());
+
+                                JSONObject jsonPOS = new JSONObject ();
+                                jsonPOS.Add("x", new JSONNumber (position.x));
+                                jsonPOS.Add("y", new JSONNumber (position.y));
+                                jsonPOS.Add("z", new JSONNumber (position.z));
+
+                                JSONObject pJson = new JSONObject ();
+                                pJson.Add ("id", new JSONNumber (entity.entityId));
+                                pJson.Add ("type", new JSONString ("animal"));
+                                pJson.Add ("tag", new JSONString (entity.tag ?? ""));
+                                pJson.Add ("model", new JSONString ((entity.emodel == null) ? "?" : entity.emodel.name ?? "?"));
+                                pJson.Add ("alive", new JSONBoolean (ea.IsAlive ()));
+                                pJson.Add ("health", new JSONNumber (ea.Health));
+
+                                if (PetesUtils.ValidText (ea.EntityName))
+                                    pJson.Add ("name", new JSONString (ea.EntityName));
+                                else
+                                    pJson.Add ("name", new JSONString ("animal class #" + entity.entityClass.ToString ()));
+
+                                pJson.Add ("position", jsonPOS);
+
+                                entitiesJsResult.Add (pJson);
+                            }
+                            else if ((entity.entityType == EntityType.Zombie) || (base_entity.GetType () == typeof(EntityEnemy))) {
+                                EntityEnemy ee = (EntityEnemy)entity;
+
+                                Vector3i position = new Vector3i (entity.GetPosition ());
+
+                                JSONObject jsonPOS = new JSONObject ();
+                                jsonPOS.Add ("x", new JSONNumber (position.x));
+                                jsonPOS.Add ("y", new JSONNumber (position.y));
+                                jsonPOS.Add ("z", new JSONNumber (position.z));
+
+                                JSONObject pJson = new JSONObject ();
+                                pJson.Add ("id", new JSONNumber (entity.entityId));
+                                pJson.Add ("type", new JSONString ("enemy"));
+                                pJson.Add ("tag", new JSONString (entity.tag ?? ""));
+                                pJson.Add ("model", new JSONString ((entity.emodel == null) ? "?" : entity.emodel.name ?? "?"));
+                                pJson.Add ("alive", new JSONBoolean (ee.IsAlive ()));
+                                pJson.Add ("health", new JSONNumber (ee.Health));
+
+                                if (PetesUtils.ValidText (ee.EntityName))
+                                    pJson.Add ("name", new JSONString (ee.EntityName));
+                                else
+                                    pJson.Add ("name", new JSONString ("enemy class #" + entity.entityClass.ToString ()));
+
+                                pJson.Add ("position", jsonPOS);
+
+                                entitiesJsResult.Add (pJson);
+                            }
+                            else if ((entity.entityType == EntityType.Player) || (base_entity.GetType () == typeof(EntityPlayer))) {
+                                EntityPlayer ep = (EntityPlayer)entity;
+
+                                Vector3i position = new Vector3i (entity.GetPosition ());
+
+                                JSONObject jsonPOS = new JSONObject ();
+                                jsonPOS.Add ("x", new JSONNumber (position.x));
+                                jsonPOS.Add ("y", new JSONNumber (position.y));
+                                jsonPOS.Add ("z", new JSONNumber (position.z));
+
+                                JSONObject pJson = new JSONObject ();
+                                pJson.Add ("id", new JSONNumber (entity.entityId));
+                                pJson.Add ("type", new JSONString ("player"));
+                                pJson.Add ("tag", new JSONString (entity.tag ?? ""));
+                                pJson.Add ("model", new JSONString ((entity.emodel == null) ? "?" : entity.emodel.name ?? "?"));
+                                pJson.Add ("alive", new JSONBoolean (ep.IsAlive ()));
+                                pJson.Add ("score", new JSONNumber (ep.Score));
+                                pJson.Add ("health", new JSONNumber (ep.Health));
+                                pJson.Add ("zombiekills", new JSONNumber (ep.KilledZombies));
+                                pJson.Add ("stamina", new JSONNumber (ep.Stamina));
+
+                                if (PetesUtils.ValidText (ep.EntityName))
+                                    pJson.Add ("name", new JSONString (ep.EntityName));
+                                else
+                                    pJson.Add ("name", new JSONString ("player class #" + entity.entityClass.ToString ()));
+
+                                pJson.Add("position", jsonPOS);
+
+                                entitiesJsResult.Add(pJson);
+                            }
+                            else { // note: animals are an EntityAnimal but are being generated with the wrong entityType ID, so get caught here
+                                Vector3i position = new Vector3i (entity.GetPosition ());
+
+                                JSONObject jsonPOS = new JSONObject ();
+                                jsonPOS.Add ("x", new JSONNumber (position.x));
+                                jsonPOS.Add ("y", new JSONNumber (position.y));
+                                jsonPOS.Add ("z", new JSONNumber (position.z));
+
+                                JSONObject pJson = new JSONObject ();
+                                pJson.Add ("id", new JSONNumber (entity.entityId));
+                                pJson.Add ("type", new JSONString ("unknown #" + ((int)entity.entityType).ToString ()));
+                                pJson.Add ("tag", new JSONString (entity.tag ?? ""));
+
+                                string true_name = entity.name;
+                                
+                                try {
+                                    int iTries = 0;
+                                    UnityEngine.GameObject go = entity.gameObject;
+
+                                    while (true_name == "GameObject") {
+                                        true_name = go.name;
+                                        go = go.gameObject;
+
+                                        if (++iTries > 10)
+                                            break;
+                                    }
+                                }
+                                catch { }
+
+                                string true_emodel = (entity.emodel == null) ? "?" : entity.emodel.name;
+
+                                try {
+                                    int iTries = 0;
+                                    UnityEngine.GameObject go = entity.emodel.gameObject;
+
+                                    while (true_emodel == "GameObject") {
+                                        true_emodel = go.name;
+                                        go = go.gameObject;
+
+                                        if (++iTries > 10)
+                                            break;
+                                    }
+                                }
+                                catch { }
+
+                                pJson.Add ("model", new JSONString (true_emodel));
+
+                                if (PetesUtils.ValidText (true_name))
+                                    pJson.Add("name", new JSONString (base_entity.GetType ().ToString () + ": " + true_name));
+                                else
+                                    pJson.Add("name", new JSONString (base_entity.GetType ().ToString () + " class #" + entity.entityClass.ToString ()));
+
+                                pJson.Add ("position", jsonPOS);
+
+                                entitiesJsResult.Add (pJson);
+                            }
+                        }
+                        catch { }
+                    }
+                }
+                catch (Exception ex) {
+                    entitiesJsResult.Add (new JSONString ("Error: " + ex.GetType ().ToString () + " - " + ex.Message + "\r\n" + ex.StackTrace));
+                }
+            }
+
+            WriteJSON (resp, entitiesJsResult);
+        }
+    }
+}
Index: binary-improvements/MapRendering/Web/API/GetStats.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetStats.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/API/GetStats.cs	(revision 251)
@@ -1,3 +1,4 @@
 using AllocsFixes.JSON;
+using AllocsFixes.LiveData;
 using AllocsFixes.PersistentData;
 using System;
@@ -20,4 +21,6 @@
 
 			result.Add ("players", new JSONNumber (GameManager.Instance.World.Players.Count));
+            result.Add ("hostiles", new JSONNumber (Hostiles.Count));
+            result.Add ("animals", new JSONNumber (Animals.Count));
 
 			WriteJSON (resp, result);
Index: binary-improvements/MapRendering/Web/API/GetWebUIUpdates.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/GetWebUIUpdates.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/API/GetWebUIUpdates.cs	(revision 251)
@@ -1,3 +1,4 @@
 using AllocsFixes.JSON;
+using AllocsFixes.LiveData;
 using AllocsFixes.PersistentData;
 using System;
@@ -23,4 +24,6 @@
 
 			result.Add ("players", new JSONNumber (GameManager.Instance.World.Players.Count));
+            result.Add ("hostiles", new JSONNumber (Hostiles.Count));
+            result.Add ("animals", new JSONNumber (Animals.Count));
 
 			result.Add ("newlogs", new JSONNumber (LogBuffer.Instance.LatestLine - latestLine));
Index: binary-improvements/MapRendering/Web/API/Null.cs
===================================================================
--- binary-improvements/MapRendering/Web/API/Null.cs	(revision 251)
+++ binary-improvements/MapRendering/Web/API/Null.cs	(revision 251)
@@ -0,0 +1,19 @@
+﻿using AllocsFixes.JSON;
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Text;
+
+namespace AllocsFixes.NetConnections.Servers.Web.API
+{
+    public class Null : WebAPI
+    {
+        public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel)
+        {
+			resp.ContentLength64 = 0;
+			resp.ContentType = "text/plain";
+			resp.ContentEncoding = Encoding.ASCII;
+			resp.OutputStream.Write (new byte[] { }, 0, 0);
+        }
+    }
+}
Index: binary-improvements/MapRendering/Web/Handlers/ApiHandler.cs
===================================================================
--- binary-improvements/MapRendering/Web/Handlers/ApiHandler.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/Handlers/ApiHandler.cs	(revision 251)
@@ -13,16 +13,27 @@
 		private Dictionary<String, WebAPI> apis = new Dictionary<string, WebAPI> ();
 
-		public ApiHandler (string staticPart, string moduleName = null) : base(moduleName) {
+		public ApiHandler (string staticPart, string moduleName = null) : base (moduleName) {
 			this.staticPart = staticPart;
 
 			foreach (Type t in Assembly.GetExecutingAssembly ().GetTypes ()) {
 				if (!t.IsAbstract && t.IsSubclassOf (typeof(WebAPI))) {
-					ConstructorInfo ctor = t.GetConstructor (new Type[0]);
+					ConstructorInfo ctor = t.GetConstructor (new Type [0]);
 					if (ctor != null) {
-						WebAPI apiInstance = (WebAPI)ctor.Invoke (new object[0]);
+						WebAPI apiInstance = (WebAPI)ctor.Invoke (new object [0]);
 						addApi (t.Name.ToLower (), apiInstance);
 					}
 				}
 			}
+
+            // Add dummy types
+            Type dummy_t = typeof (API.Null);
+            ConstructorInfo dummy_ctor = dummy_t.GetConstructor (new Type [0]);
+            if (dummy_ctor != null) {
+                WebAPI dummy_apiInstance = (WebAPI)dummy_ctor.Invoke (new object[0]);
+
+                // Permissions that don't map to a real API
+                addApi("viewallclaims", dummy_apiInstance);
+                addApi("viewallplayers", dummy_apiInstance);
+            }
 		}
 
Index: binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs
===================================================================
--- binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs	(revision 251)
@@ -1,5 +1,4 @@
 using System;
 using System.Collections.Generic;
-using System.IO;
 using System.Net;
 using System.Threading;
@@ -13,6 +12,6 @@
 		private string staticPart;
 		private bool logMissingFiles;
-		private Dictionary<string, byte[]> icons = new Dictionary<string, byte[]> ();
-		private bool loaded = false;
+        private Dictionary<string, byte[]> icons = new Dictionary<string, byte[]> ();
+        private bool loaded = false;
 
 		public ItemIconHandler (string staticPart, bool logMissingFiles, string moduleName = null) : base(moduleName) {
@@ -30,11 +29,68 @@
 			}
 
-			string fn = req.Url.AbsolutePath.Remove (0, staticPart.Length);
-			fn = fn.Remove (fn.LastIndexOf ('.'));
+            // BEGIN CHANGED BY PSOUZA4
+			string requestFileName = req.Url.AbsolutePath.Remove (0, staticPart.Length);
+			requestFileName = requestFileName.Remove (requestFileName.LastIndexOf ('.'));
 
-			if (icons.ContainsKey (fn)) {
+            string requestColorTintHex = string.Empty;
+            
+            // Chose a split instead of using a querystring variable in the URI, but that may arguably be cleaner
+            if (requestFileName.Contains("@@")) {
+                try {
+                    string[] tempTintingOptions = requestFileName.Split (new string[] { "@@" }, StringSplitOptions.RemoveEmptyEntries);
+                    requestFileName = tempTintingOptions [0];
+                    requestColorTintHex = tempTintingOptions [1].Trim ().ToUpper ();
+                }
+                catch { }
+            }
+
+            if (icons.ContainsKey (requestFileName) && req.Url.AbsolutePath.ToLower ().EndsWith(".png")) {
 				resp.ContentType = MimeType.GetMimeType (".png");
-				resp.ContentLength64 = icons [fn].Length;
-				resp.OutputStream.Write (icons [fn], 0, icons [fn].Length);
+
+                byte[] itemIconData = icons [requestFileName];
+
+                // Note: optionally split this code into a ImageMultiplyBlend method
+                if (!string.IsNullOrEmpty (requestColorTintHex) && (requestColorTintHex != "FFFFFF")) {
+                    try {
+                        System.Drawing.Color colorTint = System.Drawing.ColorTranslator.FromHtml ("#" + requestColorTintHex);
+                        System.Drawing.Bitmap image = (System.Drawing.Bitmap)PetesUtils.GetImageFromBytes (itemIconData);
+
+                        for (var x = 0; x < image.Width; x++) {
+                            for (int y = 0; y < image.Height; y++) {
+                                System.Drawing.Color originalColor = image.GetPixel (x, y);
+                                System.Drawing.Color changedColor = originalColor;
+
+                                // Only change the icon tinting if the alpha channel is fully opaque
+                                if (originalColor.A == 255) {
+                                    // based on http://stackoverflow.com/questions/3837757/multiply-two-images-in-c-sharp-as-multiply-two-layers-in-photoshop
+
+                                    double component_R = (((double)originalColor.R) * ((double)colorTint.R)) / 255.0;
+                                    double component_G = (((double)originalColor.G) * ((double)colorTint.G)) / 255.0;
+                                    double component_B = (((double)originalColor.B) * ((double)colorTint.B)) / 255.0;
+
+                                    if (component_R > 255.0) component_R = 255.0;
+                                    if (component_G > 255.0) component_G = 255.0;
+                                    if (component_B > 255.0) component_B = 255.0;
+
+                                    // multiply blend shouldn't ever calculate below 0, but for completeness let's leave in this logic
+                                    if (component_R < 0.0) component_R = 0.0;
+                                    if (component_G < 0.0) component_G = 0.0;
+                                    if (component_B < 0.0) component_B = 0.0;
+
+                                    changedColor = System.Drawing.Color.FromArgb (originalColor.A, (int)component_R, (int)component_G, (int)component_B);
+                                }                                
+
+                                image.SetPixel (x, y, changedColor);
+                            }
+                        }
+
+                        itemIconData = PetesUtils.SaveImage_ToBytes (image, true);
+                    }
+                    catch { }
+                }
+
+				resp.ContentLength64 = itemIconData.Length;
+				resp.OutputStream.Write (itemIconData, 0, itemIconData.Length);
+                // END CHANGED BY PSOUZA4
 			} else {
 				resp.StatusCode = (int)HttpStatusCode.NotFound;
Index: binary-improvements/MapRendering/Web/Handlers/StaticHandler.cs
===================================================================
--- binary-improvements/MapRendering/Web/Handlers/StaticHandler.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/Handlers/StaticHandler.cs	(revision 251)
@@ -27,4 +27,5 @@
 
 			byte[] content = cache.GetFileContent (datapath + "/" + fn);
+
 			if (content != null) {
 				resp.ContentType = MimeType.GetMimeType (Path.GetExtension (fn));
Index: binary-improvements/MapRendering/Web/WebConnection.cs
===================================================================
--- binary-improvements/MapRendering/Web/WebConnection.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/WebConnection.cs	(revision 251)
@@ -1,5 +1,5 @@
 using System;
 using System.Collections.Generic;
-
+using AllocsFixes.NetConnections.Servers.Web;
 using UnityEngine;
 
@@ -29,4 +29,38 @@
 			get { return DateTime.Now - lastAction; }
 		}
+
+        public bool CanViewAllPlayers (int _permissionLevel) {
+            bool val = false;
+
+            try {
+                const int defaultPermissionLevel = 0;
+
+                val = _permissionLevel <= defaultPermissionLevel;
+
+                foreach (WebPermissions.WebModulePermission wap in WebPermissions.Instance.GetModules ())
+                    if (wap.module.Trim ().ToLower () == "webapi.viewallplayers")
+                        val = _permissionLevel <= wap.permissionLevel;
+            }
+            catch { }
+
+            return val;
+        }
+
+        public bool CanViewAllClaims (int _permissionLevel) {
+            bool val = false;
+
+            try {
+                const int defaultPermissionLevel = 0;
+
+                val = _permissionLevel <= defaultPermissionLevel;
+
+                foreach (WebPermissions.WebModulePermission wap in WebPermissions.Instance.GetModules ())
+                    if (wap.module.Trim ().ToLower () == "webapi.viewallclaims")
+                        val = _permissionLevel <= wap.permissionLevel;
+            }
+            catch { }
+
+            return val;
+        }
 
 		public WebConnection (string _sessionId, string _endpoint, ulong _steamId) {
Index: binary-improvements/MapRendering/Web/WebPermissions.cs
===================================================================
--- binary-improvements/MapRendering/Web/WebPermissions.cs	(revision 250)
+++ binary-improvements/MapRendering/Web/WebPermissions.cs	(revision 251)
@@ -99,5 +99,7 @@
 			if (!string.IsNullOrEmpty (_module)) {
 				lock (this) {
-					knownModules.Add (_module, new WebModulePermission (_module, 0));
+                    if (!IsKnownModule( _module)) {
+					    knownModules.Add (_module, new WebModulePermission (_module, 0));
+                    }
 				}
 			}
@@ -269,24 +271,40 @@
 
 			using (StreamWriter sw = new StreamWriter(GetFullPath ())) {
-				sw.WriteLine ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-				sw.WriteLine ("<webpermissions>");
-				sw.WriteLine ("    <admintokens>");
-				sw.WriteLine ("        <!-- <token name=\"adminuser1\" token=\"supersecrettoken\" permission_level=\"0\" /> -->");
-				foreach (AdminToken at in admintokens.Values) {
-					sw.WriteLine (string.Format ("        <token name=\"{0}\" token=\"{1}\" permission_level=\"{2}\" />", at.name, at.token, at.permissionLevel));
-				}
-				sw.WriteLine ("    </admintokens>");
-				sw.WriteLine ();
-				sw.WriteLine ("    <permissions>");
-				sw.WriteLine ("        <!-- <permission module=\"webapi.executeconsolecommand\" permission_level=\"0\" /> -->");
-				sw.WriteLine ("        <!-- <permission module=\"webapi.getplayersonline\" permission_level=\"1\" /> -->");
-				sw.WriteLine ("        <!-- <permission module=\"web.map\" permission_level=\"1000\" /> -->");
-				foreach (WebModulePermission wap in modules.Values) {
-					sw.WriteLine (string.Format ("        <permission module=\"{0}\" permission_level=\"{1}\" />", wap.module, wap.permissionLevel));
-				}
-				sw.WriteLine ("    </permissions>");
-				sw.WriteLine ();
-				sw.WriteLine ("</webpermissions>");
-			
+                sw.WriteLine ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+                sw.WriteLine ("<webpermissions>");
+                sw.WriteLine  ();
+                sw.WriteLine ("	<admintokens>");
+                sw.WriteLine ("		<!-- <token name=\"adminuser1\" token=\"supersecrettoken\" permission_level=\"0\" /> -->");
+                foreach (AdminToken at in admintokens.Values) {
+                    sw.WriteLine (string.Format ("		<token name=\"{0}\" token=\"{1}\" permission_level=\"{2}\" />", at.name, at.token, at.permissionLevel));
+                }
+                sw.WriteLine ("	</admintokens>");
+                sw.WriteLine ();
+                sw.WriteLine ("	<permissions>");
+                foreach (WebModulePermission wap in modules.Values) {
+                    sw.WriteLine (string.Format ("		<permission module=\"{0}\" permission_level=\"{1}\" />", wap.module, wap.permissionLevel));
+                }
+                sw.WriteLine ("		<!-- <permission module=\"web.map\" permission_level=\"1000\" /> -->");
+                sw.WriteLine ();
+                sw.WriteLine ("		<!-- <permission module=\"webapi.getlog\" permission_level=\"0\" /> -->");
+                sw.WriteLine ("		<!-- <permission module=\"webapi.executeconsolecommand\" permission_level=\"0\" /> -->");
+                sw.WriteLine ();
+                sw.WriteLine ("		<!-- <permission module=\"webapi.getstats\" permission_level=\"1000\" /> -->");
+                sw.WriteLine ("		<!-- <permission module=\"webapi.getplayersonline\" permission_level=\"1000\" /> -->");
+                sw.WriteLine ();
+                sw.WriteLine ("		<!-- <permission module=\"webapi.getplayerslocation\" permission_level=\"1000\" /> -->");
+                sw.WriteLine ("		<!-- <permission module=\"webapi.viewallplayers\" permission_level=\"1\" /> -->");
+                sw.WriteLine ();
+                sw.WriteLine ("		<!-- <permission module=\"webapi.getlandclaims\" permission_level=\"1000\" /> -->");
+                sw.WriteLine ("		<!-- <permission module=\"webapi.viewallclaims\" permission_level=\"1\" /> -->");
+                sw.WriteLine ();
+                sw.WriteLine ("		<!-- <permission module=\"webapi.getplayerinventory\" permission_level=\"1\" /> -->");
+                sw.WriteLine ();
+                sw.WriteLine ("		<!-- <permission module=\"webapi.gethostilelocation\" permission_level=\"1\" /> -->");
+                sw.WriteLine ("		<!-- <permission module=\"webapi.getanimalslocation\" permission_level=\"1\" /> -->");
+                sw.WriteLine ("	</permissions>");
+                sw.WriteLine ();
+                sw.WriteLine ("</webpermissions>");
+
 				sw.Flush ();
 				sw.Close ();
Index: binary-improvements/MapRendering/WebAndMapRendering.csproj
===================================================================
--- binary-improvements/MapRendering/WebAndMapRendering.csproj	(revision 250)
+++ binary-improvements/MapRendering/WebAndMapRendering.csproj	(revision 251)
@@ -1,3 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
+﻿<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
@@ -21,5 +21,12 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="System" />
+    <Reference Include="System">
+      <HintPath>..\7dtd-binaries\System.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Drawing">
+      <HintPath>..\7dtd-binaries\System.Drawing.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
     <Reference Include="LogLibrary">
       <HintPath>..\7dtd-binaries\LogLibrary.dll</HintPath>
@@ -51,4 +58,8 @@
     <Compile Include="Commands\EnableRendering.cs" />
     <Compile Include="API.cs" />
+    <Compile Include="Web\API\GetAnimalsLocation.cs" />
+    <Compile Include="Web\API\GetRawEntitiesList.cs" />
+    <Compile Include="Web\API\GetHostileLocation.cs" />
+    <Compile Include="Web\API\Null.cs" />
     <Compile Include="Web\Web.cs" />
     <Compile Include="Web\MimeType.cs" />
@@ -87,8 +98,5 @@
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Commands\" />
-    <Folder Include="Web\Handlers\" />
-  </ItemGroup>
+  <ItemGroup />
   <ItemGroup>
     <None Include="ModInfo.xml">
Index: binary-improvements/webserver/index.html
===================================================================
--- binary-improvements/webserver/index.html	(revision 250)
+++ binary-improvements/webserver/index.html	(revision 251)
@@ -3,5 +3,5 @@
 <head>
 	<meta charset="UTF-8">
-	<title>7dtd map browser</title>
+	<title>7 Days to Die Map</title>
 
 	<!-- jQuery -->
@@ -59,5 +59,7 @@
 			<div id="serverstats">
 				<span id="stats_time">-</span><br/>
-				<span id="stats_players">-</span> Players
+				<span id="stats_players">-</span> Players<br />
+				<span id="stats_hostiles">-</span> Hostiles<br />
+				<span id="stats_animals">-</span> Animals
 			</div>
 
@@ -87,5 +89,5 @@
 		</div>
 		<div id="admincontent">
-			<h1 id="nopermissionwarning" style="display:none">An error occured or you do not have any permissions on this WebPanel. Log in with the link on the lower left!</h1>
+			<h1 id="nopermissionwarning" style="display:none">An error occured or you have not logged in.  Try logging in with the Steam login in the lower left!</h1>
 			<div id="tab_map" class="adminmap"></div>
 			<div id="tab_log" class="adminlog">
Index: binary-improvements/webserver/js/inventory_dialog.js
===================================================================
--- binary-improvements/webserver/js/inventory_dialog.js	(revision 250)
+++ binary-improvements/webserver/js/inventory_dialog.js	(revision 251)
@@ -19,5 +19,5 @@
 
 		if (itemdata !== null) {
-			cell.attr("style", "background-image: url(" + ITEMICONBASEURL + itemdata.name + ".png);");
+			cell.attr("style", "background-image: url(" + ITEMICONBASEURL + itemdata.icon + "@@" + itemdata.iconcolor + ".png);");
 			if (itemdata.quality >= 0) {
 				cell.attr("title", itemdata.name + " (quality: " + itemdata.quality + ")");
Index: binary-improvements/webserver/js/map.js
===================================================================
--- binary-improvements/webserver/js/map.js	(revision 250)
+++ binary-improvements/webserver/js/map.js	(revision 251)
@@ -48,5 +48,31 @@
 	var tileLayerMiniMap = GetSdtdTileLayer (mapinfo, initTime, true);
 
-
+	// player icon
+	var playerIcon = L.icon({
+	    iconUrl: '/static/leaflet/images/marker-survivor.png',
+	    iconRetinaUrl: '/static/leaflet/images/marker-survivor-2x.png',
+	    iconSize: [25, 48],
+	    iconAnchor: [12, 24],
+	    popupAnchor: [0, -20]
+	});
+	
+	// hostile icon
+	var hostileIcon = L.icon({
+	    iconUrl: '/static/leaflet/images/marker-zombie.png',
+	    iconRetinaUrl: '/static/leaflet/images/marker-zombie-2x.png',
+	    iconSize: [25, 33],
+	    iconAnchor: [12, 16],
+	    popupAnchor: [0, -10]
+	});	
+	
+	// animal icon
+	var animalIcon = L.icon({
+	    iconUrl: '/static/leaflet/images/marker-animal.png',
+	    iconRetinaUrl: '/static/leaflet/images/marker-animal-2x.png',
+	    iconSize: [25, 26],
+	    iconAnchor: [12, 13],
+	    popupAnchor: [0, -10]
+	});
+	
 
 
@@ -58,4 +84,10 @@
 	});
 	var playersOfflineMarkerGroup = L.markerClusterGroup({
+		maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
+	});
+	var hostilesMarkerGroup = L.markerClusterGroup({
+		maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
+	});
+	var animalsMarkerGroup = L.markerClusterGroup({
 		maxClusterRadius: function(zoom) { return zoom == mapinfo.maxzoom ? 10 : 50; }
 	});
@@ -107,4 +139,14 @@
 	}
 	
+	if (HasPermission ("webapi.gethostilelocation")) {
+		layerControl.addOverlay (hostilesMarkerGroup, "Hostiles (<span id='mapControlHostileCount'>0</span>)");
+		layerCount++;
+	}
+	
+	if (HasPermission ("webapi.getanimalslocation")) {
+		layerControl.addOverlay (animalsMarkerGroup, "Animals (<span id='mapControlAnimalsCount'>0</span>)");
+		layerCount++;
+	}
+	
 	if (HasPermission ("webapi.getplayerslocation")) {
 		layerControl.addOverlay (playersOfflineMarkerGroup, "Players (offline) (<span id='mapControlOfflineCount'>0</span>)");
@@ -120,7 +162,9 @@
 
 
+	var hostilesMappingList = {};
+	var animalsMappingList = {};
 	var playersMappingList = {};
 
-
+	
 
 	// ===============================================================================================
@@ -155,5 +199,5 @@
 				marker = playersMappingList[val.steamid].currentPosMarker;
 			} else {
-				marker = L.marker([val.position.x, val.position.z]).bindPopup(
+				marker = L.marker([val.position.x, val.position.z], {icon: playerIcon}).bindPopup(
 					"Player: " + val.name +
 					(HasPermission ("webapi.getplayerinventory") ?
@@ -226,4 +270,152 @@
 
 
+
+
+	// ===============================================================================================
+	// Hostiles markers
+
+	var setHostileMarkers = function(data) {
+		updatingMarkersHostile = true;
+		
+		var hostileCount = 0;
+
+		hostilesMarkerGroup.clearLayers();
+		
+		$.each( data, function( key, val ) {
+			var marker;
+			if (hostilesMappingList.hasOwnProperty(val.id)) {
+				marker = hostilesMappingList[val.id].currentPosMarker;
+			} else {
+				marker = L.marker([val.position.x, val.position.z], {icon: hostileIcon}).bindPopup(
+					"Hostile: " + val.name
+				);
+				//hostilesMappingList[val.id] = { };
+				hostilesMarkerGroup.addLayer(marker);
+			}
+
+			var bAbort = false;
+			
+			oldpos = marker.getLatLng ();
+
+			//if ( oldpos.lat != val.position.x || oldpos.lng != val.position.z ) {
+			//	hostilesMarkerGroup.removeLayer(marker);
+				marker.setLatLng([val.position.x, val.position.z]);
+				marker.setOpacity(1.0);
+				hostilesMarkerGroup.addLayer(marker);
+			//}
+
+			val.currentPosMarker = marker;
+			hostilesMappingList[val.id] = val;
+			
+			hostileCount++;
+		});
+		
+		$( "#mapControlHostileCount" ).text( hostileCount );
+		
+		updatingMarkersHostile = false;
+	}
+
+	var updateHostileTimeout;
+	var updateHostileEvent = function() {
+		$.getJSON( "../api/gethostilelocation")
+		.done(setHostileMarkers)
+		.fail(function(jqxhr, textStatus, error) {
+			console.log("Error fetching hostile list");
+		})
+		.always(function() {
+			updateHostileTimeout = window.setTimeout(updateHostileEvent, 4000);
+		});
+	}
+
+	tabs.on ("tabbedcontenttabopened", function (event, data) {
+		if (data.newTab === "#tab_map") {
+			if (HasPermission ("webapi.gethostilelocation")) {
+				updateHostileEvent ();
+			}
+		} else {
+			window.clearTimeout (updateHostileTimeout);
+		}
+	});
+	
+	if (tabs.tabbedContent ("isTabOpen", "tab_map")) {
+		if (HasPermission ("webapi.gethostilelocation")) {
+			updateHostileEvent ();
+		}
+	}
+
+
+
+	// ===============================================================================================
+	// Animals markers
+
+	var setAnimalMarkers = function(data) {
+		updatingMarkersAnimals = true;
+		
+		var animalsCount = 0;
+
+		animalsMarkerGroup.clearLayers();
+		
+		$.each( data, function( key, val ) {
+			var marker;
+			if (animalsMappingList.hasOwnProperty(val.id)) {
+				marker = animalsMappingList[val.id].currentPosMarker;
+			} else {
+				marker = L.marker([val.position.x, val.position.z], {icon: animalIcon}).bindPopup(
+					"Animal: " + val.name
+				);
+				//animalsMappingList[val.id] = { };
+				animalsMarkerGroup.addLayer(marker);
+			}
+
+			var bAbort = false;
+			
+			oldpos = marker.getLatLng ();
+
+			//if ( oldpos.lat != val.position.x || oldpos.lng != val.position.z ) {
+			//	animalsMarkerGroup.removeLayer(marker);
+				marker.setLatLng([val.position.x, val.position.z]);
+				marker.setOpacity(1.0);
+				animalsMarkerGroup.addLayer(marker);
+			//}
+
+			val.currentPosMarker = marker;
+			animalsMappingList[val.id] = val;
+			
+			animalsCount++;
+		});
+		
+		$( "#mapControlAnimalsCount" ).text( animalsCount );
+		
+		updatingMarkersAnimals = false;
+	}
+
+	var updateAnimalsTimeout;
+	var updateAnimalsEvent = function() {
+		$.getJSON( "../api/getanimalslocation")
+		.done(setAnimalMarkers)
+		.fail(function(jqxhr, textStatus, error) {
+			console.log("Error fetching animals list");
+		})
+		.always(function() {
+			updateAnimalsTimeout = window.setTimeout(updateAnimalsEvent, 4000);
+		});
+	}
+
+	tabs.on ("tabbedcontenttabopened", function (event, data) {
+		if (data.newTab === "#tab_map") {
+			if (HasPermission ("webapi.getanimalslocation")) {
+				updateAnimalsEvent ();
+			}
+		} else {
+			window.clearTimeout (updateAnimalsTimeout);
+		}
+	});
+	
+	if (tabs.tabbedContent ("isTabOpen", "tab_map")) {
+		if (HasPermission ("webapi.getanimalslocation")) {
+			updateAnimalsEvent ();
+		}
+	}
+
 }
 
Index: binary-improvements/webserver/js/stats.js
===================================================================
--- binary-improvements/webserver/js/stats.js	(revision 250)
+++ binary-improvements/webserver/js/stats.js	(revision 251)
@@ -14,4 +14,6 @@
 			$("#stats_time").html (time);
 			$("#stats_players").html (data.players);
+			$("#stats_hostiles").html (data.hostiles);
+			$("#stats_animals").html (data.animals);
 		})
 		.fail(function(jqxhr, textStatus, error) {
@@ -40,4 +42,6 @@
 			$("#stats_time").html (time);
 			$("#stats_players").html (data.players);
+			$("#stats_hostiles").html (data.hostiles);
+			$("#stats_animals").html (data.animals);
 			$("#newlogcount").html (data.newlogs);
 			if (data.newlogs > 0) {
Index: binary-improvements/webserver/sessionheader.tmpl
===================================================================
--- binary-improvements/webserver/sessionheader.tmpl	(revision 250)
+++ binary-improvements/webserver/sessionheader.tmpl	(revision 251)
@@ -3,5 +3,5 @@
 <head>
 	<meta charset="UTF-8">
-	<title>7dtd map browser</title>
+	<title>7 Days to Die Map</title>
 
 	<!-- Own stylesheet -->
