diff options
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs | 226 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 159 |
2 files changed, 339 insertions, 46 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 4501dd9..3b39153 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | ||
30 | using System.Collections.Specialized; | 31 | using System.Collections.Specialized; |
31 | using System.Drawing; | 32 | using System.Drawing; |
32 | using System.Drawing.Imaging; | 33 | using System.Drawing.Imaging; |
@@ -53,8 +54,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
53 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadBakedTextureModule")] | 54 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadBakedTextureModule")] |
54 | public class UploadBakedTextureModule : INonSharedRegionModule | 55 | public class UploadBakedTextureModule : INonSharedRegionModule |
55 | { | 56 | { |
56 | // private static readonly ILog m_log = | 57 | private static readonly ILog m_log = |
57 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 58 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
58 | 59 | ||
59 | /// <summary> | 60 | /// <summary> |
60 | /// For historical reasons this is fixed, but there | 61 | /// For historical reasons this is fixed, but there |
@@ -63,39 +64,211 @@ namespace OpenSim.Region.ClientStack.Linden | |||
63 | 64 | ||
64 | private Scene m_scene; | 65 | private Scene m_scene; |
65 | private bool m_persistBakedTextures; | 66 | private bool m_persistBakedTextures; |
66 | private string m_URL; | 67 | |
68 | private IBakedTextureModule m_BakedTextureModule; | ||
67 | 69 | ||
68 | public void Initialise(IConfigSource source) | 70 | public void Initialise(IConfigSource source) |
69 | { | 71 | { |
70 | IConfig config = source.Configs["ClientStack.LindenCaps"]; | ||
71 | if (config == null) | ||
72 | return; | ||
73 | |||
74 | m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty); | ||
75 | |||
76 | IConfig appearanceConfig = source.Configs["Appearance"]; | 72 | IConfig appearanceConfig = source.Configs["Appearance"]; |
77 | if (appearanceConfig != null) | 73 | if (appearanceConfig != null) |
78 | m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); | 74 | m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); |
75 | |||
76 | |||
79 | } | 77 | } |
80 | 78 | ||
81 | public void AddRegion(Scene s) | 79 | public void AddRegion(Scene s) |
82 | { | 80 | { |
83 | m_scene = s; | 81 | m_scene = s; |
82 | |||
84 | } | 83 | } |
85 | 84 | ||
86 | public void RemoveRegion(Scene s) | 85 | public void RemoveRegion(Scene s) |
87 | { | 86 | { |
87 | s.EventManager.OnRegisterCaps -= RegisterCaps; | ||
88 | s.EventManager.OnNewPresence -= RegisterNewPresence; | ||
89 | s.EventManager.OnRemovePresence -= DeRegisterPresence; | ||
90 | m_BakedTextureModule = null; | ||
91 | m_scene = null; | ||
88 | } | 92 | } |
89 | 93 | ||
94 | |||
95 | |||
90 | public void RegionLoaded(Scene s) | 96 | public void RegionLoaded(Scene s) |
91 | { | 97 | { |
92 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; | 98 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; |
99 | m_scene.EventManager.OnNewPresence += RegisterNewPresence; | ||
100 | m_scene.EventManager.OnRemovePresence += DeRegisterPresence; | ||
101 | |||
102 | } | ||
103 | |||
104 | private void DeRegisterPresence(UUID agentId) | ||
105 | { | ||
106 | ScenePresence presence = null; | ||
107 | if (m_scene.TryGetScenePresence(agentId, out presence)) | ||
108 | { | ||
109 | presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings; | ||
110 | } | ||
111 | |||
112 | } | ||
113 | |||
114 | private void RegisterNewPresence(ScenePresence presence) | ||
115 | { | ||
116 | presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings; | ||
117 | |||
118 | } | ||
119 | |||
120 | private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) | ||
121 | { | ||
122 | int maxCacheitemsLoop = cacheItems.Length; | ||
123 | if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES) | ||
124 | { | ||
125 | maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; | ||
126 | m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); | ||
127 | } | ||
128 | |||
129 | m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
130 | if (cacheItems.Length > 0) | ||
131 | { | ||
132 | m_log.Debug("[Cacheitems]: " + cacheItems.Length); | ||
133 | for (int iter = 0; iter < maxCacheitemsLoop; iter++) | ||
134 | { | ||
135 | m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + | ||
136 | cacheItems[iter].TextureID); | ||
137 | } | ||
138 | |||
139 | ScenePresence p = null; | ||
140 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) | ||
141 | { | ||
142 | |||
143 | WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; | ||
144 | if (existingitems == null) | ||
145 | { | ||
146 | if (m_BakedTextureModule != null) | ||
147 | { | ||
148 | WearableCacheItem[] savedcache = null; | ||
149 | try | ||
150 | { | ||
151 | if (p.Appearance.WearableCacheItemsDirty) | ||
152 | { | ||
153 | savedcache = m_BakedTextureModule.Get(p.UUID); | ||
154 | p.Appearance.WearableCacheItems = savedcache; | ||
155 | p.Appearance.WearableCacheItemsDirty = false; | ||
156 | } | ||
157 | |||
158 | } | ||
159 | /* | ||
160 | * The following Catch types DO NOT WORK with m_BakedTextureModule.Get | ||
161 | * it jumps to the General Packet Exception Handler if you don't catch Exception! | ||
162 | * | ||
163 | catch (System.Net.Sockets.SocketException) | ||
164 | { | ||
165 | cacheItems = null; | ||
166 | } | ||
167 | catch (WebException) | ||
168 | { | ||
169 | cacheItems = null; | ||
170 | } | ||
171 | catch (InvalidOperationException) | ||
172 | { | ||
173 | cacheItems = null; | ||
174 | } */ | ||
175 | catch (Exception) | ||
176 | { | ||
177 | // The service logs a sufficient error message. | ||
178 | } | ||
179 | |||
180 | |||
181 | if (savedcache != null) | ||
182 | existingitems = savedcache; | ||
183 | } | ||
184 | } | ||
185 | // Existing items null means it's a fully new appearance | ||
186 | if (existingitems == null) | ||
187 | { | ||
188 | |||
189 | for (int i = 0; i < maxCacheitemsLoop; i++) | ||
190 | { | ||
191 | if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) | ||
192 | { | ||
193 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; | ||
194 | if (face == null) | ||
195 | { | ||
196 | textureEntry.CreateFace(cacheItems[i].TextureIndex); | ||
197 | textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = | ||
198 | AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
199 | continue; | ||
200 | } | ||
201 | cacheItems[i].TextureID =face.TextureID; | ||
202 | if (m_scene.AssetService != null) | ||
203 | cacheItems[i].TextureAsset = | ||
204 | m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); | ||
205 | } | ||
206 | else | ||
207 | { | ||
208 | m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); | ||
209 | } | ||
210 | |||
211 | |||
212 | } | ||
213 | } | ||
214 | else | ||
215 | |||
216 | |||
217 | { | ||
218 | // for each uploaded baked texture | ||
219 | for (int i = 0; i < maxCacheitemsLoop; i++) | ||
220 | { | ||
221 | if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) | ||
222 | { | ||
223 | Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; | ||
224 | if (face == null) | ||
225 | { | ||
226 | textureEntry.CreateFace(cacheItems[i].TextureIndex); | ||
227 | textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = | ||
228 | AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
229 | continue; | ||
230 | } | ||
231 | cacheItems[i].TextureID = | ||
232 | face.TextureID; | ||
233 | } | ||
234 | else | ||
235 | { | ||
236 | m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | for (int i = 0; i < maxCacheitemsLoop; i++) | ||
241 | { | ||
242 | if (cacheItems[i].TextureAsset == null) | ||
243 | { | ||
244 | cacheItems[i].TextureAsset = | ||
245 | m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | |||
250 | |||
251 | |||
252 | p.Appearance.WearableCacheItems = cacheItems; | ||
253 | |||
254 | |||
255 | |||
256 | if (m_BakedTextureModule != null) | ||
257 | { | ||
258 | m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); | ||
259 | p.Appearance.WearableCacheItemsDirty = true; | ||
260 | |||
261 | } | ||
262 | } | ||
263 | } | ||
93 | } | 264 | } |
94 | 265 | ||
95 | public void PostInitialise() | 266 | public void PostInitialise() |
96 | { | 267 | { |
97 | } | 268 | } |
98 | 269 | ||
270 | |||
271 | |||
99 | public void Close() { } | 272 | public void Close() { } |
100 | 273 | ||
101 | public string Name { get { return "UploadBakedTextureModule"; } } | 274 | public string Name { get { return "UploadBakedTextureModule"; } } |
@@ -107,26 +280,23 @@ namespace OpenSim.Region.ClientStack.Linden | |||
107 | 280 | ||
108 | public void RegisterCaps(UUID agentID, Caps caps) | 281 | public void RegisterCaps(UUID agentID, Caps caps) |
109 | { | 282 | { |
110 | // UUID capID = UUID.Random(); | 283 | UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( |
284 | caps, m_scene.AssetService, m_persistBakedTextures); | ||
111 | 285 | ||
112 | //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); | 286 | |
113 | if (m_URL == "localhost") | 287 | |
114 | { | 288 | caps.RegisterHandler( |
115 | caps.RegisterHandler( | 289 | "UploadBakedTexture", |
290 | new RestStreamHandler( | ||
291 | "POST", | ||
292 | "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, | ||
293 | avatarhandler.UploadBakedTexture, | ||
116 | "UploadBakedTexture", | 294 | "UploadBakedTexture", |
117 | new RestStreamHandler( | 295 | agentID.ToString())); |
118 | "POST", | 296 | |
119 | "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, | 297 | |
120 | new UploadBakedTextureHandler( | 298 | |
121 | caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture, | 299 | |
122 | "UploadBakedTexture", | ||
123 | agentID.ToString())); | ||
124 | |||
125 | } | ||
126 | else | ||
127 | { | ||
128 | caps.RegisterHandler("UploadBakedTexture", m_URL); | ||
129 | } | ||
130 | } | 300 | } |
131 | } | 301 | } |
132 | } \ No newline at end of file | 302 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 585cdc4..1f522e8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -325,6 +325,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
325 | private readonly byte[] m_channelVersion = Utils.EmptyBytes; | 325 | private readonly byte[] m_channelVersion = Utils.EmptyBytes; |
326 | private readonly IGroupsModule m_GroupsModule; | 326 | private readonly IGroupsModule m_GroupsModule; |
327 | 327 | ||
328 | private int m_cachedTextureSerial; | ||
328 | private PriorityQueue m_entityUpdates; | 329 | private PriorityQueue m_entityUpdates; |
329 | private PriorityQueue m_entityProps; | 330 | private PriorityQueue m_entityProps; |
330 | private Prioritizer m_prioritizer; | 331 | private Prioritizer m_prioritizer; |
@@ -11742,36 +11743,158 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11742 | /// <returns></returns> | 11743 | /// <returns></returns> |
11743 | protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) | 11744 | protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) |
11744 | { | 11745 | { |
11746 | //m_log.Debug("texture cached: " + packet.ToString()); | ||
11745 | AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; | 11747 | AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet; |
11748 | AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); | ||
11746 | 11749 | ||
11747 | if (cachedtex.AgentData.SessionID != SessionId) | 11750 | if (cachedtex.AgentData.SessionID != SessionId) |
11748 | return false; | 11751 | return false; |
11749 | 11752 | ||
11750 | List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>(); | ||
11751 | 11753 | ||
11752 | for (int i = 0; i < cachedtex.WearableData.Length; i++) | 11754 | // TODO: don't create new blocks if recycling an old packet |
11753 | { | 11755 | cachedresp.AgentData.AgentID = AgentId; |
11754 | CachedTextureRequestArg arg = new CachedTextureRequestArg(); | 11756 | cachedresp.AgentData.SessionID = m_sessionId; |
11755 | arg.BakedTextureIndex = cachedtex.WearableData[i].TextureIndex; | 11757 | cachedresp.AgentData.SerialNum = m_cachedTextureSerial; |
11756 | arg.WearableHashID = cachedtex.WearableData[i].ID; | 11758 | m_cachedTextureSerial++; |
11757 | 11759 | cachedresp.WearableData = | |
11758 | requestArgs.Add(arg); | 11760 | new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; |
11759 | } | 11761 | |
11762 | //IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>(); | ||
11763 | // var item = fac.GetBakedTextureFaces(AgentId); | ||
11764 | //WearableCacheItem[] items = fac.GetCachedItems(AgentId); | ||
11765 | |||
11766 | IAssetService cache = m_scene.AssetService; | ||
11767 | IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
11768 | //bakedTextureModule = null; | ||
11769 | int maxWearablesLoop = cachedtex.WearableData.Length; | ||
11770 | if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) | ||
11771 | maxWearablesLoop = AvatarWearable.MAX_WEARABLES; | ||
11772 | |||
11773 | if (bakedTextureModule != null && cache != null) | ||
11774 | { | ||
11775 | // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid | ||
11776 | |||
11777 | WearableCacheItem[] cacheItems = null; | ||
11778 | ScenePresence p = m_scene.GetScenePresence(AgentId); | ||
11779 | if (p.Appearance != null) | ||
11780 | if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty) | ||
11781 | { | ||
11782 | try | ||
11783 | { | ||
11784 | cacheItems = bakedTextureModule.Get(AgentId); | ||
11785 | p.Appearance.WearableCacheItems = cacheItems; | ||
11786 | p.Appearance.WearableCacheItemsDirty = false; | ||
11787 | } | ||
11760 | 11788 | ||
11761 | try | 11789 | /* |
11762 | { | 11790 | * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception! |
11763 | CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest; | 11791 | * |
11764 | if (handlerCachedTextureRequest != null) | 11792 | catch (System.Net.Sockets.SocketException) |
11793 | { | ||
11794 | cacheItems = null; | ||
11795 | } | ||
11796 | catch (WebException) | ||
11797 | { | ||
11798 | cacheItems = null; | ||
11799 | } | ||
11800 | catch (InvalidOperationException) | ||
11801 | { | ||
11802 | cacheItems = null; | ||
11803 | } */ | ||
11804 | catch (Exception) | ||
11805 | { | ||
11806 | cacheItems = null; | ||
11807 | } | ||
11808 | |||
11809 | } | ||
11810 | else if (p.Appearance.WearableCacheItems != null) | ||
11811 | { | ||
11812 | cacheItems = p.Appearance.WearableCacheItems; | ||
11813 | } | ||
11814 | |||
11815 | if (cache != null && cacheItems != null) | ||
11765 | { | 11816 | { |
11766 | handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs); | 11817 | foreach (WearableCacheItem item in cacheItems) |
11818 | { | ||
11819 | |||
11820 | if (cache.GetCached(item.TextureID.ToString()) == null) | ||
11821 | { | ||
11822 | item.TextureAsset.Temporary = true; | ||
11823 | cache.Store(item.TextureAsset); | ||
11824 | } | ||
11825 | |||
11826 | |||
11827 | } | ||
11828 | } | ||
11829 | if (cacheItems != null) | ||
11830 | { | ||
11831 | |||
11832 | for (int i = 0; i < maxWearablesLoop; i++) | ||
11833 | { | ||
11834 | WearableCacheItem item = | ||
11835 | WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems); | ||
11836 | |||
11837 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); | ||
11838 | cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex; | ||
11839 | cachedresp.WearableData[i].HostName = new byte[0]; | ||
11840 | if (item != null && cachedtex.WearableData[i].ID == item.CacheId) | ||
11841 | { | ||
11842 | |||
11843 | cachedresp.WearableData[i].TextureID = item.TextureID; | ||
11844 | } | ||
11845 | else | ||
11846 | { | ||
11847 | cachedresp.WearableData[i].TextureID = UUID.Zero; | ||
11848 | } | ||
11849 | } | ||
11850 | } | ||
11851 | else | ||
11852 | { | ||
11853 | for (int i = 0; i < maxWearablesLoop; i++) | ||
11854 | { | ||
11855 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); | ||
11856 | cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; | ||
11857 | cachedresp.WearableData[i].TextureID = UUID.Zero; | ||
11858 | //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); | ||
11859 | cachedresp.WearableData[i].HostName = new byte[0]; | ||
11860 | } | ||
11767 | } | 11861 | } |
11768 | } | 11862 | } |
11769 | catch (Exception e) | 11863 | else |
11770 | { | 11864 | { |
11771 | m_log.ErrorFormat("[CLIENT VIEW]: AgentTextureCached packet handler threw an exception, {0}", e); | 11865 | if (cache == null) |
11772 | return false; | 11866 | { |
11867 | for (int i = 0; i < maxWearablesLoop; i++) | ||
11868 | { | ||
11869 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); | ||
11870 | cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; | ||
11871 | cachedresp.WearableData[i].TextureID = UUID.Zero; | ||
11872 | //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); | ||
11873 | cachedresp.WearableData[i].HostName = new byte[0]; | ||
11874 | } | ||
11875 | } | ||
11876 | else | ||
11877 | { | ||
11878 | for (int i = 0; i < maxWearablesLoop; i++) | ||
11879 | { | ||
11880 | cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); | ||
11881 | cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; | ||
11882 | |||
11883 | |||
11884 | |||
11885 | if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null) | ||
11886 | cachedresp.WearableData[i].TextureID = UUID.Zero; | ||
11887 | //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); | ||
11888 | else | ||
11889 | cachedresp.WearableData[i].TextureID = UUID.Zero; | ||
11890 | // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); | ||
11891 | cachedresp.WearableData[i].HostName = new byte[0]; | ||
11892 | } | ||
11893 | } | ||
11773 | } | 11894 | } |
11774 | 11895 | cachedresp.Header.Zerocoded = true; | |
11896 | OutPacket(cachedresp, ThrottleOutPacketType.Task); | ||
11897 | |||
11775 | return true; | 11898 | return true; |
11776 | } | 11899 | } |
11777 | 11900 | ||