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

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

Fixed ItemIconHandler for mods

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.Add (_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.Add (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.