aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
diff options
context:
space:
mode:
authorDr Scofield2009-02-06 16:55:34 +0000
committerDr Scofield2009-02-06 16:55:34 +0000
commit9b66108081a8c8cf79faaa6c541554091c40850e (patch)
tree095a232ae5a9de3a9244bcd34da08294f61eeea5 /OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
parent* removed superfluous constants class (diff)
downloadopensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.zip
opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.gz
opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.bz2
opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.xz
This changeset is the step 1 of 2 in refactoring
OpenSim.Region.Environment into a "framework" part and a modules only part. This first changeset refactors OpenSim.Region.Environment.Scenes, OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region modules in OpenSim.Region.Environment. The next step will be to move region modules up from OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and then sort out which modules are really core modules and which should move out to forge. I've been very careful to NOT BREAK anything. i hope i've succeeded. as this is the work of a whole week i hope i managed to keep track with the applied patches of the last week --- could any of you that did check in stuff have a look at whether it survived? thx!
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs376
1 files changed, 376 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
new file mode 100644
index 0000000..bd9c260
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
@@ -0,0 +1,376 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections;
31using System.Collections.Generic;
32using System.Reflection;
33using System.Threading;
34
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38
39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Cache;
42using OpenSim.Framework.Servers;
43// using OpenSim.Region.Environment;
44using OpenSim.Region.Framework.Scenes;
45
46//using HyperGrid.Framework;
47//using OpenSim.Region.Communications.Hypergrid;
48
49namespace OpenSim.Region.Framework.Scenes.Hypergrid
50{
51 public class HGAssetMapper
52 {
53 #region Fields
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 // This maps between asset server URLs and asset server clients
57 private Dictionary<string, GridAssetClient> m_assetServers = new Dictionary<string, GridAssetClient>();
58
59 // This maps between asset UUIDs and asset servers
60 private Dictionary<UUID, GridAssetClient> m_assetMap = new Dictionary<UUID, GridAssetClient>();
61
62 private Scene m_scene;
63 #endregion
64
65 #region Constructor
66
67 public HGAssetMapper(Scene scene)
68 {
69 m_scene = scene;
70 }
71
72 #endregion
73
74 #region Internal functions
75
76 private string UserAssetURL(UUID userID)
77 {
78 CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
79 if (uinfo != null)
80 return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI;
81 return null;
82 }
83
84 private bool IsLocalUser(UUID userID)
85 {
86 CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
87
88 if (uinfo != null)
89 {
90 if (HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile))
91 {
92 m_log.Debug("[HGScene]: Home user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
93 return true;
94 }
95 }
96
97 m_log.Debug("[HGScene]: Foreign user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
98 return false;
99 }
100
101 private bool IsInAssetMap(UUID uuid)
102 {
103 return m_assetMap.ContainsKey(uuid);
104 }
105
106 private bool FetchAsset(GridAssetClient asscli, UUID assetID, bool isTexture)
107 {
108 // I'm not going over 3 seconds since this will be blocking processing of all the other inbound
109 // packets from the client.
110 int pollPeriod = 200;
111 int maxPolls = 15;
112
113 AssetBase asset;
114
115 // Maybe it came late, and it's already here. Check first.
116 if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset))
117 {
118 m_log.Debug("[HGScene]: Asset already in asset cache. " + assetID);
119 return true;
120 }
121
122
123 asscli.RequestAsset(assetID, isTexture);
124
125 do
126 {
127 Thread.Sleep(pollPeriod);
128
129 if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset) && (asset != null))
130 {
131 m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Metadata.Name + " " + assetID);
132 // I think I need to store it in the asset DB too.
133 // For now, let me just do it for textures and scripts
134 if (((AssetType)asset.Metadata.Type == AssetType.Texture) ||
135 ((AssetType)asset.Metadata.Type == AssetType.LSLBytecode) ||
136 ((AssetType)asset.Metadata.Type == AssetType.LSLText))
137 {
138 AssetBase asset1 = new AssetBase();
139 Copy(asset, asset1);
140 m_scene.AssetCache.AssetServer.StoreAsset(asset1);
141 }
142 return true;
143 }
144 } while (--maxPolls > 0);
145
146 m_log.WarnFormat("[HGScene]: {0} {1} was not received before the retrieval timeout was reached",
147 isTexture ? "texture" : "asset", assetID.ToString());
148
149 return false;
150 }
151
152 private bool PostAsset(GridAssetClient asscli, UUID assetID)
153 {
154 AssetBase asset1;
155 m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset1);
156
157 if (asset1 != null)
158 {
159 // See long comment in AssetCache.AddAsset
160 if (!asset1.Metadata.Temporary || asset1.Metadata.Local)
161 {
162 // The asset cache returns instances of subclasses of AssetBase:
163 // TextureImage or AssetInfo. So in passing them to the remote
164 // server we first need to convert this to instances of AssetBase,
165 // which is the serializable class for assets.
166 AssetBase asset = new AssetBase();
167 Copy(asset1, asset);
168
169 asscli.StoreAsset(asset);
170 }
171 return true;
172 }
173 else
174 m_log.Warn("[HGScene]: Tried to post asset to remote server, but asset not in local cache.");
175
176 return false;
177 }
178
179 private void Copy(AssetBase from, AssetBase to)
180 {
181 to.Data = from.Data;
182 to.Metadata.Description = from.Metadata.Description;
183 to.Metadata.FullID = from.Metadata.FullID;
184 to.Metadata.ID = from.Metadata.ID;
185 to.Metadata.Local = from.Metadata.Local;
186 to.Metadata.Name = from.Metadata.Name;
187 to.Metadata.Temporary = from.Metadata.Temporary;
188 to.Metadata.Type = from.Metadata.Type;
189
190 }
191
192 private void _guardedAdd(Dictionary<UUID, bool> lst, UUID obj, bool val)
193 {
194 if (!lst.ContainsKey(obj))
195 lst.Add(obj, val);
196 }
197
198 private void SniffTextureUUIDs(Dictionary<UUID, bool> uuids, SceneObjectGroup sog)
199 {
200 try
201 {
202 _guardedAdd(uuids, sog.RootPart.Shape.Textures.DefaultTexture.TextureID, true);
203 }
204 catch (Exception) { }
205
206 foreach (Primitive.TextureEntryFace tface in sog.RootPart.Shape.Textures.FaceTextures)
207 {
208 try
209 {
210 _guardedAdd(uuids, tface.TextureID, true);
211 }
212 catch (Exception) { }
213 }
214
215 foreach (SceneObjectPart sop in sog.Children.Values)
216 {
217 try
218 {
219 _guardedAdd(uuids, sop.Shape.Textures.DefaultTexture.TextureID, true);
220 }
221 catch (Exception) { }
222 foreach (Primitive.TextureEntryFace tface in sop.Shape.Textures.FaceTextures)
223 {
224 try
225 {
226 _guardedAdd(uuids, tface.TextureID, true);
227 }
228 catch (Exception) { }
229 }
230 }
231 }
232
233 private void SniffTaskInventoryUUIDs(Dictionary<UUID, bool> uuids, SceneObjectGroup sog)
234 {
235 TaskInventoryDictionary tinv = sog.RootPart.TaskInventory;
236
237 foreach (TaskInventoryItem titem in tinv.Values)
238 {
239 uuids.Add(titem.AssetID, (InventoryType)titem.Type == InventoryType.Texture);
240 }
241 }
242
243 private Dictionary<UUID, bool> SniffUUIDs(AssetBase asset)
244 {
245 Dictionary<UUID, bool> uuids = new Dictionary<UUID, bool>();
246 if ((asset != null) && ((AssetType)asset.Metadata.Type == AssetType.Object))
247 {
248 string ass_str = Utils.BytesToString(asset.Data);
249 SceneObjectGroup sog = new SceneObjectGroup(ass_str, true);
250
251 SniffTextureUUIDs(uuids, sog);
252
253 // We need to sniff further...
254 SniffTaskInventoryUUIDs(uuids, sog);
255
256 }
257
258 return uuids;
259 }
260
261 private Dictionary<UUID, bool> SniffUUIDs(UUID assetID)
262 {
263 //Dictionary<UUID, bool> uuids = new Dictionary<UUID, bool>();
264
265 AssetBase asset;
266 m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset);
267
268 return SniffUUIDs(asset);
269 }
270
271 private void Dump(Dictionary<UUID, bool> lst)
272 {
273 m_log.Debug("XXX -------- UUID DUMP ------- XXX");
274 foreach (KeyValuePair<UUID, bool> kvp in lst)
275 m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")");
276 m_log.Debug("XXX -------- UUID DUMP ------- XXX");
277 }
278
279 #endregion
280
281
282 #region Public interface
283
284 public void Get(UUID itemID, UUID ownerID)
285 {
286 if (!IsInAssetMap(itemID) && !IsLocalUser(ownerID))
287 {
288 // Get the item from the remote asset server onto the local AssetCache
289 // and place an entry in m_assetMap
290
291 GridAssetClient asscli = null;
292 string userAssetURL = UserAssetURL(ownerID);
293 if (userAssetURL != null)
294 {
295 m_assetServers.TryGetValue(userAssetURL, out asscli);
296 if (asscli == null)
297 {
298 m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
299 asscli = new GridAssetClient(userAssetURL);
300 asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
301 m_assetServers.Add(userAssetURL, asscli);
302 }
303
304 m_log.Debug("[HGScene]: Fetching object " + itemID + " to asset server " + userAssetURL);
305 bool success = FetchAsset(asscli, itemID, false); // asscli.RequestAsset(item.ItemID, false);
306
307 // OK, now fetch the inside.
308 Dictionary<UUID, bool> ids = SniffUUIDs(itemID);
309 Dump(ids);
310 foreach (KeyValuePair<UUID, bool> kvp in ids)
311 FetchAsset(asscli, kvp.Key, kvp.Value);
312
313
314 if (success)
315 {
316 m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL);
317 m_assetMap.Add(itemID, asscli);
318 }
319 else
320 m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL);
321 }
322 else
323 m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
324 }
325 }
326
327 public void Post(UUID itemID, UUID ownerID)
328 {
329 if (!IsLocalUser(ownerID))
330 {
331 // Post the item from the local AssetCache ontp the remote asset server
332 // and place an entry in m_assetMap
333
334 GridAssetClient asscli = null;
335 string userAssetURL = UserAssetURL(ownerID);
336 if (userAssetURL != null)
337 {
338 m_assetServers.TryGetValue(userAssetURL, out asscli);
339 if (asscli == null)
340 {
341 m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
342 asscli = new GridAssetClient(userAssetURL);
343 asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
344 m_assetServers.Add(userAssetURL, asscli);
345 }
346 m_log.Debug("[HGScene]: Posting object " + itemID + " to asset server " + userAssetURL);
347 bool success = PostAsset(asscli, itemID);
348
349 // Now the inside
350 Dictionary<UUID, bool> ids = SniffUUIDs(itemID);
351 Dump(ids);
352 foreach (KeyValuePair<UUID, bool> kvp in ids)
353 PostAsset(asscli, kvp.Key);
354
355 if (success)
356 {
357 m_log.Debug("[HGScene]: Successfully posted item to remote asset server " + userAssetURL);
358 if (!m_assetMap.ContainsKey(itemID))
359 m_assetMap.Add(itemID, asscli);
360 }
361 else
362 m_log.Warn("[HGScene]: Could not post asset to remote asset server " + userAssetURL);
363
364 //if (!m_assetMap.ContainsKey(itemID))
365 // m_assetMap.Add(itemID, asscli);
366 }
367 else
368 m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
369
370 }
371 }
372
373 #endregion
374
375 }
376}