using System; using System.Collections.Generic; using System.Net; using System.Threading; using UnityEngine; namespace AllocsFixes.NetConnections.Servers.Web.Handlers { public class ItemIconHandler : PathHandler { private string staticPart; private bool logMissingFiles; private Dictionary icons = new Dictionary (); private bool loaded = false; public ItemIconHandler (string staticPart, bool logMissingFiles, string moduleName = null) : base(moduleName) { this.staticPart = staticPart; this.logMissingFiles = logMissingFiles; } public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, WebConnection user, int permissionLevel) { if (!loaded) { if (!LoadIcons ()) { resp.StatusCode = (int)HttpStatusCode.NotFound; Log.Out ("Web:IconHandler: Could not load icons"); return; } } // BEGIN CHANGED BY PSOUZA4 string requestFileName = req.Url.AbsolutePath.Remove (0, staticPart.Length); requestFileName = requestFileName.Remove (requestFileName.LastIndexOf ('.')); 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"); 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; if (logMissingFiles) Log.Out ("Web:IconHandler:FileNotFound: \"" + req.Url.AbsolutePath + "\" "); return; } } private bool LoadIcons () { lock (icons) { if (loaded) { return true; } GameObject atlasObj = GameObject.Find ("/NGUI Root (2D)/ItemIconAtlas"); if (atlasObj == null) { Log.Error ("Web:IconHandler: Atlas object not found"); loaded = true; return false; } DynamicUIAtlas atlas = atlasObj.GetComponent (); if (atlas == null) { Log.Error ("Web:IconHandler: Atlas component not found"); loaded = true; return false; } Texture2D atlasTex = atlas.texture as Texture2D; foreach (UISpriteData data in atlas.spriteList) { string name = data.name; Texture2D tex = new Texture2D (data.width, data.height, TextureFormat.ARGB32, false); tex.SetPixels (atlasTex.GetPixels (data.x, atlasTex.height - data.height - data.y, data.width, data.height)); byte[] pixData = tex.EncodeToPNG (); icons.Add (name, pixData); UnityEngine.Object.Destroy (tex); } loaded = true; Log.Out ("Web:IconHandler: Icons loaded"); return true; } } } }