using System; using System.Collections.Generic; using System.IO; using System.Net; using UnityEngine; using Object = UnityEngine.Object; namespace AllocsFixes.NetConnections.Servers.Web.Handlers { public class ItemIconHandler : PathHandler { private readonly Dictionary icons = new Dictionary (); private readonly bool logMissingFiles; private bool loaded; static ItemIconHandler () { Instance = null; } public ItemIconHandler (bool _logMissingFiles, string _moduleName = null) : base (_moduleName) { logMissingFiles = _logMissingFiles; Instance = this; } public static ItemIconHandler Instance { get; private set; } public override void HandleRequest (HttpListenerRequest _req, HttpListenerResponse _resp, WebConnection _user, int _permissionLevel) { if (!loaded) { _resp.StatusCode = (int) HttpStatusCode.InternalServerError; Log.Out ("Web:IconHandler: Icons not loaded"); return; } string requestFileName = _req.Url.AbsolutePath.Remove (0, urlBasePath.Length); requestFileName = requestFileName.Remove (requestFileName.LastIndexOf ('.')); if (icons.ContainsKey (requestFileName) && _req.Url.AbsolutePath.EndsWith (".png", StringComparison.OrdinalIgnoreCase)) { _resp.ContentType = MimeType.GetMimeType (".png"); byte[] itemIconData = icons [requestFileName]; _resp.ContentLength64 = itemIconData.Length; _resp.OutputStream.Write (itemIconData, 0, itemIconData.Length); } else { _resp.StatusCode = (int) HttpStatusCode.NotFound; if (logMissingFiles) { Log.Out ("Web:IconHandler:FileNotFound: \"" + _req.Url.AbsolutePath + "\" "); } } } public bool LoadIcons () { lock (icons) { if (loaded) { return true; } MicroStopwatch microStopwatch = new MicroStopwatch (); // Get list of used tints for all items Dictionary> tintedIcons = new Dictionary> (); foreach (ItemClass ic in ItemClass.list) { if (ic != null) { Color tintColor = ic.GetIconTint (); if (tintColor != Color.white) { string name = ic.GetIconName (); if (!tintedIcons.ContainsKey (name)) { tintedIcons.Add (name, new List ()); } List list = tintedIcons [name]; list.Add (tintColor); } } } try { loadIconsFromFolder (GameIO.GetGameDir ("Data/ItemIcons"), tintedIcons); } catch (Exception e) { Log.Error ("Failed loading icons from base game"); Log.Exception (e); } // Load icons from mods foreach (Mod mod in ModManager.GetLoadedMods ()) { try { string modIconsPath = mod.Path + "/ItemIcons"; loadIconsFromFolder (modIconsPath, tintedIcons); } catch (Exception e) { Log.Error ("Failed loading icons from mod " + mod.Name); Log.Exception (e); } } loaded = true; Log.Out ("Web:IconHandler: Icons loaded - {0} ms", microStopwatch.ElapsedMilliseconds); return true; } } private void loadIconsFromFolder (string _path, Dictionary> _tintedIcons) { if (Directory.Exists (_path)) { foreach (string file in Directory.GetFiles (_path)) { try { if (file.EndsWith (".png", StringComparison.OrdinalIgnoreCase)) { string name = Path.GetFileNameWithoutExtension (file); Texture2D tex = new Texture2D (1, 1, TextureFormat.ARGB32, false); if (tex.LoadImage (File.ReadAllBytes (file))) { AddIcon (name, tex, _tintedIcons); Object.Destroy (tex); } } } catch (Exception e) { Log.Exception (e); } } } } private void AddIcon (string _name, Texture2D _tex, Dictionary> _tintedIcons) { icons [_name + "__FFFFFF"] = _tex.EncodeToPNG (); if (_tintedIcons.ContainsKey (_name)) { foreach (Color c in _tintedIcons [_name]) { string tintedName = _name + "__" + AllocsUtils.ColorToHex (c); if (!icons.ContainsKey (tintedName)) { Texture2D tintedTex = new Texture2D (_tex.width, _tex.height, TextureFormat.ARGB32, false); for (int x = 0; x < _tex.width; x++) { for (int y = 0; y < _tex.height; y++) { tintedTex.SetPixel (x, y, _tex.GetPixel (x, y) * c); } } icons [tintedName] = tintedTex.EncodeToPNG (); Object.Destroy (tintedTex); } } } } } }