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

Last change on this file since 306 was 306, checked in by alloc, 7 years ago

Fixes update A16.2

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