source: binary-improvements/MapRendering/Web/Handlers/ItemIconHandler.cs@ 328

Last change on this file since 328 was 326, checked in by alloc, 6 years ago

More cleanup, allocation improvements

File size: 5.5 KB
RevLine 
[253]1using System;
2using System.Collections.Generic;
[325]3using System.IO;
[253]4using System.Net;
5using UnityEngine;
[325]6using Object = UnityEngine.Object;
[253]7
[325]8namespace AllocsFixes.NetConnections.Servers.Web.Handlers {
[253]9 public class ItemIconHandler : PathHandler {
[325]10 private readonly Dictionary<string, byte[]> icons = new Dictionary<string, byte[]> ();
11 private readonly bool logMissingFiles;
12
13 private readonly string staticPart;
14 private bool loaded;
15
16 static ItemIconHandler () {
17 Instance = null;
[267]18 }
19
[325]20 public ItemIconHandler (string staticPart, bool logMissingFiles, string moduleName = null) : base (moduleName) {
[253]21 this.staticPart = staticPart;
22 this.logMissingFiles = logMissingFiles;
[325]23 Instance = this;
[253]24 }
25
[325]26 public static ItemIconHandler Instance { get; private set; }
27
28 public override void HandleRequest (HttpListenerRequest req, HttpListenerResponse resp, WebConnection user,
29 int permissionLevel) {
[253]30 if (!loaded) {
[325]31 resp.StatusCode = (int) HttpStatusCode.InternalServerError;
[291]32 Log.Out ("Web:IconHandler: Icons not loaded");
33 return;
[253]34 }
35
36 string requestFileName = req.Url.AbsolutePath.Remove (0, staticPart.Length);
37 requestFileName = requestFileName.Remove (requestFileName.LastIndexOf ('.'));
38
[326]39 if (icons.ContainsKey (requestFileName) && req.Url.AbsolutePath.EndsWith (".png", StringComparison.OrdinalIgnoreCase)) {
[253]40 resp.ContentType = MimeType.GetMimeType (".png");
41
42 byte[] itemIconData = icons [requestFileName];
43
44 resp.ContentLength64 = itemIconData.Length;
45 resp.OutputStream.Write (itemIconData, 0, itemIconData.Length);
46 } else {
[325]47 resp.StatusCode = (int) HttpStatusCode.NotFound;
[253]48 if (logMissingFiles) {
49 Log.Out ("Web:IconHandler:FileNotFound: \"" + req.Url.AbsolutePath + "\" ");
50 }
51 }
52 }
53
[267]54 public bool LoadIcons () {
[253]55 lock (icons) {
56 if (loaded) {
57 return true;
58 }
59
60 MicroStopwatch microStopwatch = new MicroStopwatch ();
61
62 GameObject atlasObj = GameObject.Find ("/NGUI Root (2D)/ItemIconAtlas");
63 if (atlasObj == null) {
64 Log.Error ("Web:IconHandler: Atlas object not found");
65 loaded = true;
66 return false;
67 }
[325]68
[253]69 DynamicUIAtlas atlas = atlasObj.GetComponent<DynamicUIAtlas> ();
70 if (atlas == null) {
71 Log.Error ("Web:IconHandler: Atlas component not found");
72 loaded = true;
73 return false;
74 }
75
[291]76 string textureResourceName = atlas.PrebakedAtlas;
77 List<UISpriteData> sprites;
78 int elementWidth, elementHeight;
79 Texture2D atlasTex;
80
[325]81 if (!DynamicUIAtlasTools.ReadPrebakedAtlasDescriptor (textureResourceName, out sprites,
82 out elementWidth, out elementHeight)) {
[291]83 SdtdConsole.Instance.Output ("Web:IconHandler: Could not read dynamic atlas descriptor");
84 return false;
85 }
86
87 if (!DynamicUIAtlasTools.ReadPrebakedAtlasTexture (textureResourceName, out atlasTex)) {
88 SdtdConsole.Instance.Output ("Web:IconHandler: Could not read dynamic atlas texture");
89 return false;
90 }
91
[292]92 // Get list of used tints for all items
[253]93 Dictionary<string, List<Color>> tintedIcons = new Dictionary<string, List<Color>> ();
94 foreach (ItemClass ic in ItemClass.list) {
95 if (ic != null) {
96 Color tintColor = ic.GetIconTint ();
97 if (tintColor != Color.white) {
98 string name = ic.GetIconName ();
99 if (!tintedIcons.ContainsKey (name)) {
100 tintedIcons.Add (name, new List<Color> ());
101 }
[325]102
[253]103 List<Color> list = tintedIcons [name];
104 list.Add (tintColor);
105 }
106 }
107 }
108
[292]109 // Load icons from vanilla
[291]110 foreach (UISpriteData data in sprites) {
[253]111 string name = data.name;
112 Texture2D tex = new Texture2D (data.width, data.height, TextureFormat.ARGB32, false);
[325]113 tex.SetPixels (atlasTex.GetPixels (data.x, atlasTex.height - data.height - data.y, data.width,
114 data.height));
[253]115
[292]116 AddIcon (name, tex, tintedIcons);
[253]117
[325]118 Object.Destroy (tex);
[292]119 }
[253]120
[325]121 Resources.UnloadAsset (atlasTex);
122
[292]123 // Load icons from mods
124 foreach (Mod mod in ModManager.GetLoadedMods ()) {
125 try {
126 string modIconsPath = mod.Path + "/ItemIcons";
127 if (Directory.Exists (modIconsPath)) {
128 foreach (string file in Directory.GetFiles (modIconsPath)) {
129 try {
[326]130 if (file.EndsWith (".png", StringComparison.OrdinalIgnoreCase)) {
[292]131 string name = Path.GetFileNameWithoutExtension (file);
132 Texture2D tex = new Texture2D (1, 1, TextureFormat.ARGB32, false);
133 if (tex.LoadImage (File.ReadAllBytes (file))) {
134 if (tex.width == elementWidth && tex.height == elementHeight) {
135 AddIcon (name, tex, tintedIcons);
136 }
137
[325]138 Object.Destroy (tex);
[292]139 }
[254]140 }
[292]141 } catch (Exception e) {
142 Log.Exception (e);
[253]143 }
[254]144 }
[253]145 }
[292]146 } catch (Exception e) {
147 Log.Exception (e);
[253]148 }
149 }
150
151 loaded = true;
152 Log.Out ("Web:IconHandler: Icons loaded - {0} ms", microStopwatch.ElapsedMilliseconds);
153
154 return true;
155 }
156 }
[292]157
158 private void AddIcon (string _name, Texture2D _tex, Dictionary<string, List<Color>> _tintedIcons) {
[306]159 icons [_name + "__FFFFFF"] = _tex.EncodeToPNG ();
[292]160
161 if (_tintedIcons.ContainsKey (_name)) {
162 foreach (Color c in _tintedIcons [_name]) {
163 string tintedName = _name + "__" + AllocsUtils.ColorToHex (c);
164 if (!icons.ContainsKey (tintedName)) {
165 Texture2D tintedTex = new Texture2D (_tex.width, _tex.height, TextureFormat.ARGB32, false);
166
167 for (int x = 0; x < _tex.width; x++) {
168 for (int y = 0; y < _tex.height; y++) {
169 tintedTex.SetPixel (x, y, _tex.GetPixel (x, y) * c);
170 }
171 }
172
[306]173 icons [tintedName] = tintedTex.EncodeToPNG ();
[292]174
[325]175 Object.Destroy (tintedTex);
[292]176 }
177 }
178 }
179 }
[253]180 }
[325]181}
Note: See TracBrowser for help on using the repository browser.