aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-11-25 15:19:00 +0000
committerJustin Clarke Casey2008-11-25 15:19:00 +0000
commite187972377c19bdd85093677c4c54034e4f9196e (patch)
treecc1bb5f003628b018b823eafc9ee0a67f98df31c /OpenSim/Region/Environment/Scenes
parent* Adding some virtual hooks and making some privaets protected for great just... (diff)
downloadopensim-SC-e187972377c19bdd85093677c4c54034e4f9196e.zip
opensim-SC-e187972377c19bdd85093677c4c54034e4f9196e.tar.gz
opensim-SC-e187972377c19bdd85093677c4c54034e4f9196e.tar.bz2
opensim-SC-e187972377c19bdd85093677c4c54034e4f9196e.tar.xz
* Apply http://opensimulator.org/mantis/view.php?id=2640
* This is Diva's hypergrid patch, as perviously discussed on the opensim-dev mailing list * Applied some minor prebuild.xml jiggling to resolve a dependency issue * Thanks Diva!
Diffstat (limited to 'OpenSim/Region/Environment/Scenes')
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs377
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs152
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs78
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs263
4 files changed, 870 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs
new file mode 100644
index 0000000..3e27b7c
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs
@@ -0,0 +1,377 @@
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;
43using OpenSim.Region.Environment;
44using OpenSim.Region.Environment.Scenes;
45
46//using HyperGrid.Framework;
47//using OpenSim.Region.Communications.Hypergrid;
48
49namespace OpenSim.Region.Environment.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 IsHomeUser(UUID userID)
85 {
86 CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
87
88 if (uinfo != null)
89 {
90 //if ((uinfo.UserProfile.UserAssetURI == null) || (uinfo.UserProfile.UserAssetURI == "") ||
91 // uinfo.UserProfile.UserAssetURI.Equals(m_scene.CommsManager.NetworkServersInfo.AssetURL))
92 if (HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI))
93 {
94 m_log.Debug("[HGScene]: Home user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
95 return true;
96 }
97 }
98
99 m_log.Debug("[HGScene]: Foreign user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
100 return false;
101 }
102
103 private bool IsInAssetMap(UUID uuid)
104 {
105 return m_assetMap.ContainsKey(uuid);
106 }
107
108 private bool FetchAsset(GridAssetClient asscli, UUID assetID, bool isTexture)
109 {
110 // I'm not going over 3 seconds since this will be blocking processing of all the other inbound
111 // packets from the client.
112 int pollPeriod = 200;
113 int maxPolls = 15;
114
115 AssetBase asset;
116
117 // Maybe it came late, and it's already here. Check first.
118 if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset))
119 {
120 m_log.Debug("[HGScene]: Asset already in asset cache. " + assetID);
121 return true;
122 }
123
124
125 asscli.RequestAsset(assetID, isTexture);
126
127 do
128 {
129 Thread.Sleep(pollPeriod);
130
131 if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset) && (asset != null))
132 {
133 m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Name + " " + assetID);
134 // I think I need to store it in the asset DB too.
135 // For now, let me just do it for textures and scripts
136 if (((AssetType)asset.Type == AssetType.Texture) ||
137 ((AssetType)asset.Type == AssetType.LSLBytecode) ||
138 ((AssetType)asset.Type == AssetType.LSLText))
139 {
140 AssetBase asset1 = new AssetBase();
141 Copy(asset, asset1);
142 m_scene.AssetCache.AssetServer.StoreAsset(asset1);
143 }
144 return true;
145 }
146 } while (--maxPolls > 0);
147
148 m_log.WarnFormat("[HGScene]: {0} {1} was not received before the retrieval timeout was reached",
149 isTexture ? "texture" : "asset", assetID.ToString());
150
151 return false;
152 }
153
154 private bool PostAsset(GridAssetClient asscli, UUID assetID)
155 {
156 AssetBase asset1;
157 m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset1);
158
159 if (asset1 != null)
160 {
161 // See long comment in AssetCache.AddAsset
162 if (!asset1.Temporary || asset1.Local)
163 {
164 // The asset cache returns instances of subclasses of AssetBase:
165 // TextureImage or AssetInfo. So in passing them to the remote
166 // server we first need to convert this to instances of AssetBase,
167 // which is the serializable class for assets.
168 AssetBase asset = new AssetBase();
169 Copy(asset1, asset);
170
171 asscli.StoreAsset(asset);
172 }
173 return true;
174 }
175 else
176 m_log.Warn("[HGScene]: Tried to post asset to remote server, but asset not in local cache.");
177
178 return false;
179 }
180
181 private void Copy(AssetBase from, AssetBase to)
182 {
183 to.Data = from.Data;
184 to.Description = from.Description;
185 to.FullID = from.FullID;
186 to.ID = from.ID;
187 to.Local = from.Local;
188 to.Name = from.Name;
189 to.Temporary = from.Temporary;
190 to.Type = from.Type;
191
192 }
193
194 private void _guardedAdd(Dictionary<UUID, bool> lst, UUID obj, bool val)
195 {
196 if (!lst.ContainsKey(obj))
197 lst.Add(obj, val);
198 }
199
200 private void SniffTextureUUIDs(Dictionary<UUID, bool> uuids, SceneObjectGroup sog)
201 {
202 try
203 {
204 _guardedAdd(uuids, sog.RootPart.Shape.Textures.DefaultTexture.TextureID, true);
205 }
206 catch (Exception) { }
207
208 foreach (Primitive.TextureEntryFace tface in sog.RootPart.Shape.Textures.FaceTextures)
209 {
210 try
211 {
212 _guardedAdd(uuids, tface.TextureID, true);
213 }
214 catch (Exception) { }
215 }
216
217 foreach (SceneObjectPart sop in sog.Children.Values)
218 {
219 try
220 {
221 _guardedAdd(uuids, sop.Shape.Textures.DefaultTexture.TextureID, true);
222 }
223 catch (Exception) { }
224 foreach (Primitive.TextureEntryFace tface in sop.Shape.Textures.FaceTextures)
225 {
226 try
227 {
228 _guardedAdd(uuids, tface.TextureID, true);
229 }
230 catch (Exception) { }
231 }
232 }
233 }
234
235 private void SniffTaskInventoryUUIDs(Dictionary<UUID, bool> uuids, SceneObjectGroup sog)
236 {
237 TaskInventoryDictionary tinv = sog.RootPart.TaskInventory;
238
239 foreach (TaskInventoryItem titem in tinv.Values)
240 {
241 uuids.Add(titem.AssetID, (InventoryType)titem.Type == InventoryType.Texture);
242 }
243 }
244
245 private Dictionary<UUID, bool> SniffUUIDs(AssetBase asset)
246 {
247 Dictionary<UUID, bool> uuids = new Dictionary<UUID, bool>();
248 if ((asset != null) && ((AssetType)asset.Type == AssetType.Object))
249 {
250 string ass_str = Utils.BytesToString(asset.Data);
251 SceneObjectGroup sog = new SceneObjectGroup(ass_str, true);
252
253 SniffTextureUUIDs(uuids, sog);
254
255 // We need to sniff further...
256 SniffTaskInventoryUUIDs(uuids, sog);
257
258 }
259
260 return uuids;
261 }
262
263 private Dictionary<UUID, bool> SniffUUIDs(UUID assetID)
264 {
265 Dictionary<UUID, bool> uuids = new Dictionary<UUID, bool>();
266
267 AssetBase asset;
268 m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset);
269
270 return SniffUUIDs(asset);
271 }
272
273 private void Dump(Dictionary<UUID, bool> lst)
274 {
275 m_log.Debug("XXX -------- UUID DUMP ------- XXX");
276 foreach (KeyValuePair<UUID, bool> kvp in lst)
277 m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")");
278 m_log.Debug("XXX -------- UUID DUMP ------- XXX");
279 }
280
281 #endregion
282
283
284 #region Public interface
285
286 public void Get(UUID itemID, UUID ownerID)
287 {
288 if (!IsInAssetMap(itemID) && !IsHomeUser(ownerID))
289 {
290 // Get the item from the remote asset server onto the local AssetCache
291 // and place an entry in m_assetMap
292
293 GridAssetClient asscli = null;
294 string userAssetURL = UserAssetURL(ownerID);
295 if (userAssetURL != null)
296 {
297 m_assetServers.TryGetValue(userAssetURL, out asscli);
298 if (asscli == null)
299 {
300 m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
301 asscli = new GridAssetClient(userAssetURL);
302 asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
303 m_assetServers.Add(userAssetURL, asscli);
304 }
305
306 m_log.Debug("[HGScene]: Fetching object " + itemID + " to asset server " + userAssetURL);
307 bool success = FetchAsset(asscli, itemID, false); // asscli.RequestAsset(item.ItemID, false);
308
309 // OK, now fetch the inside.
310 Dictionary<UUID, bool> ids = SniffUUIDs(itemID);
311 Dump(ids);
312 foreach (KeyValuePair<UUID, bool> kvp in ids)
313 FetchAsset(asscli, kvp.Key, kvp.Value);
314
315
316 if (success)
317 {
318 m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL);
319 m_assetMap.Add(itemID, asscli);
320 }
321 else
322 m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL);
323 }
324 else
325 m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
326 }
327 }
328
329 public void Post(UUID itemID, UUID ownerID)
330 {
331 if (!IsHomeUser(ownerID))
332 {
333 // Post the item from the local AssetCache ontp the remote asset server
334 // and place an entry in m_assetMap
335
336 GridAssetClient asscli = null;
337 string userAssetURL = UserAssetURL(ownerID);
338 if (userAssetURL != null)
339 {
340 m_assetServers.TryGetValue(userAssetURL, out asscli);
341 if (asscli == null)
342 {
343 m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
344 asscli = new GridAssetClient(userAssetURL);
345 asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
346 m_assetServers.Add(userAssetURL, asscli);
347 }
348 m_log.Debug("[HGScene]: Posting object " + itemID + " to asset server " + userAssetURL);
349 bool success = PostAsset(asscli, itemID);
350
351 // Now the inside
352 Dictionary<UUID, bool> ids = SniffUUIDs(itemID);
353 Dump(ids);
354 foreach (KeyValuePair<UUID, bool> kvp in ids)
355 PostAsset(asscli, kvp.Key);
356
357 if (success)
358 {
359 m_log.Debug("[HGScene]: Successfully posted item to remote asset server " + userAssetURL);
360 m_assetMap.Add(itemID, asscli);
361 }
362 else
363 m_log.Warn("[HGScene]: Could not post asset to remote asset server " + userAssetURL);
364
365 //if (!m_assetMap.ContainsKey(itemID))
366 // m_assetMap.Add(itemID, asscli);
367 }
368 else
369 m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
370
371 }
372 }
373
374 #endregion
375
376 }
377}
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs
new file mode 100644
index 0000000..af3c04f
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs
@@ -0,0 +1,152 @@
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;
43using OpenSim.Region.Environment;
44using OpenSim.Region.Environment.Scenes;
45
46namespace OpenSim.Region.Environment.Scenes.Hypergrid
47{
48 public partial class HGScene : Scene
49 {
50 #region Fields
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private HGAssetMapper m_assMapper;
54
55 #endregion
56
57 #region Constructors
58
59 public HGScene(RegionInfo regInfo, AgentCircuitManager authen,
60 CommunicationsManager commsMan, SceneCommunicationService sceneGridService,
61 AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer,
62 ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
63 bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
64 : base(regInfo, authen, commsMan, sceneGridService, assetCach, storeManager, httpServer, moduleLoader,
65 dumpAssetsToFile, physicalPrim, SeeIntoRegionFromNeighbor, config, simulatorVersion)
66 {
67 m_log.Info("[HGScene]: Starting HGScene.");
68 m_assMapper = new HGAssetMapper(this);
69
70 EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
71 }
72
73 #endregion
74
75 #region Event handlers
76
77 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
78 {
79 CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(avatarID);
80 if (userInfo != null)
81 {
82 m_assMapper.Post(assetID, avatarID);
83 }
84 }
85
86 #endregion
87
88 #region Overrides of Scene.Inventory methods
89
90 ///
91 /// CapsUpdateInventoryItemAsset
92 ///
93 public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
94 {
95 UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
96
97 UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0);
98
99 return newAssetID;
100 }
101
102 ///
103 /// DeleteToInventory
104 ///
105 public override UUID DeleteToInventory(int destination, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient)
106 {
107 UUID assetID = base.DeleteToInventory(destination, folderID, objectGroup, remoteClient);
108
109 if (!assetID.Equals(UUID.Zero))
110 {
111 UploadInventoryItem(remoteClient.AgentId, assetID, "", 0);
112 }
113 else
114 m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
115
116 return assetID;
117 }
118
119 ///
120 /// RezObject
121 ///
122 public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
123 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
124 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
125 {
126 CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
127 if (userInfo != null)
128 {
129 if (userInfo.RootFolder != null)
130 {
131 InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
132
133 if (item != null)
134 {
135 m_assMapper.Get(item.AssetID, remoteClient.AgentId);
136
137 }
138 }
139 }
140
141 // OK, we're done fetching. Pass it up to the default RezObject
142 return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
143 RezSelected, RemoveItem, fromTaskID, attachment);
144
145 }
146
147
148 #endregion
149
150 }
151
152}
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs
new file mode 100644
index 0000000..a1a6173
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs
@@ -0,0 +1,78 @@
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.Generic;
31
32using OpenMetaverse;
33
34using OpenSim.Framework;
35
36using OpenSim.Framework.Communications.Cache;
37using OpenSim.Region.Environment;
38using OpenSim.Region.Environment.Scenes;
39using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
40
41namespace OpenSim.Region.Environment.Scenes.Hypergrid
42{
43 public partial class HGScene : Scene
44 {
45 /// <summary>
46 /// Teleport an avatar to their home region
47 /// </summary>
48 /// <param name="agentId"></param>
49 /// <param name="client"></param>
50 public override void TeleportClientHome(UUID agentId, IClientAPI client)
51 {
52 m_log.Debug("[HGScene]: TeleportClientHome " + client.FirstName + " " + client.LastName);
53
54 CachedUserInfo uinfo = CommsManager.UserProfileCacheService.GetUserDetails(agentId);
55 UserProfileData UserProfile = uinfo.UserProfile;
56
57 if (UserProfile != null)
58 {
59 RegionInfo regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegion);
60 //if (regionInfo != null)
61 //{
62 // UserProfile.HomeRegionID = regionInfo.RegionID;
63 // //CommsManager.UserService.UpdateUserProfile(UserProfile);
64 //}
65 if (regionInfo == null)
66 {
67 // can't find the Home region: Tell viewer and abort
68 client.SendTeleportFailed("Your home-region could not be found.");
69 return;
70 }
71 RequestTeleportLocation(
72 client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt,
73 (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome));
74 }
75 }
76
77 }
78}
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs
new file mode 100644
index 0000000..501584a
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs
@@ -0,0 +1,263 @@
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.Generic;
31using System.Reflection;
32using System.Threading;
33
34using OpenMetaverse;
35
36using log4net;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Cache;
40using OpenSim.Region.Environment.Scenes;
41using OpenSim.Region.Environment;
42using OpenSim.Region.Interfaces;
43using OSD = OpenMetaverse.StructuredData.OSD;
44
45namespace OpenSim.Region.Environment.Scenes.Hypergrid
46{
47 public class HGSceneCommunicationService : SceneCommunicationService
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private IHyperlink m_hg;
52
53 public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan)
54 {
55 m_hg = hg;
56 }
57
58
59 /// <summary>
60 /// Try to teleport an agent to a new region.
61 /// </summary>
62 /// <param name="remoteClient"></param>
63 /// <param name="RegionHandle"></param>
64 /// <param name="position"></param>
65 /// <param name="lookAt"></param>
66 /// <param name="flags"></param>
67 public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position,
68 Vector3 lookAt, uint teleportFlags)
69 {
70 if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID))
71 return;
72
73 bool destRegionUp = false;
74
75 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>();
76
77 if (regionHandle == m_regionInfo.RegionHandle)
78 {
79 // Teleport within the same region
80 if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0)
81 {
82 Vector3 emergencyPos = new Vector3(128, 128, 128);
83
84 m_log.WarnFormat(
85 "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
86 position, avatar.Name, avatar.UUID, emergencyPos);
87 position = emergencyPos;
88 }
89 // TODO: Get proper AVG Height
90 float localAVHeight = 1.56f;
91 float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y);
92 float newPosZ = posZLimit + localAVHeight;
93 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
94 {
95 position.Z = newPosZ;
96 }
97
98 // Only send this if the event queue is null
99 if (eq == null)
100 avatar.ControllingClient.SendTeleportLocationStart();
101
102
103 avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
104 avatar.Teleport(position);
105 }
106 else
107 {
108 RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle);
109 if (reg != null)
110 {
111 ///
112 /// Hypergrid mod start
113 ///
114 ///
115 bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle);
116 bool isHomeUser = true;
117 ulong realHandle = regionHandle;
118 CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID);
119 if (uinfo != null)
120 {
121 isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI);
122 realHandle = m_hg.FindRegionHandle(regionHandle);
123 Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString());
124 }
125 ///
126 /// Hypergrid mod stop
127 ///
128 ///
129
130 if (eq == null)
131 avatar.ControllingClient.SendTeleportLocationStart();
132
133 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
134 agent.BaseFolder = UUID.Zero;
135 agent.InventoryFolder = UUID.Zero;
136 agent.startpos = position;
137 agent.child = true;
138
139 if (reg.RemotingAddress != "" && reg.RemotingPort != 0)
140 {
141 // region is remote. see if it is up
142 destRegionUp = m_commsProvider.InterRegion.CheckRegion(reg.RemotingAddress, reg.RemotingPort);
143 }
144 else
145 {
146 // assume local regions are always up
147 destRegionUp = true;
148 }
149
150 if (destRegionUp)
151 {
152 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
153 // both regions
154 if (avatar.ParentID != (uint)0)
155 avatar.StandUp();
156 if (!avatar.ValidateAttachments())
157 {
158 avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
159 return;
160 }
161
162 // the avatar.Close below will clear the child region list. We need this below for (possibly)
163 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
164 List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
165 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
166 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
167 // once we reach here...
168 avatar.Scene.RemoveCapsHandler(avatar.UUID);
169 agent.child = false;
170 m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent);
171
172 m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
173 position, false);
174 Thread.Sleep(2000);
175 AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo();
176
177 // TODO Should construct this behind a method
178 string capsPath =
179 "http://" + reg.ExternalHostName + ":" + reg.HttpPort
180 + "/CAPS/" + circuitdata.CapsPath + "0000/";
181
182 m_log.DebugFormat(
183 "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID);
184
185
186 ///
187 /// Hypergrid mod: realHandle instead of reg.RegionHandle
188 ///
189 ///
190 if (eq != null)
191 {
192 OSD Item = EventQueueHelper.TeleportFinishEvent(realHandle, 13, reg.ExternalEndPoint,
193 4, teleportFlags, capsPath, avatar.UUID);
194 eq.Enqueue(Item, avatar.UUID);
195 }
196 else
197 {
198 avatar.ControllingClient.SendRegionTeleport(realHandle, 13, reg.ExternalEndPoint, 4,
199 teleportFlags, capsPath);
200 }
201 ///
202 /// Hypergrid mod stop
203 ///
204
205 avatar.MakeChildAgent();
206 Thread.Sleep(7000);
207 avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
208 if (KiPrimitive != null)
209 {
210 KiPrimitive(avatar.LocalId);
211 }
212
213 avatar.Close();
214
215 uint newRegionX = (uint)(reg.RegionHandle >> 40);
216 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
217 uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
218 uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
219 ///
220 /// Hypergrid mod: extra check for isHyperLink
221 ///
222 if ((Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) || isHyperLink)
223 {
224 //SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList());
225 SendCloseChildAgentConnections(avatar.UUID, childRegions);
226 CloseConnection(avatar.UUID);
227 }
228 // if (teleport success) // seems to be always success here
229 // the user may change their profile information in other region,
230 // so the userinfo in UserProfileCache is not reliable any more, delete it
231 if (avatar.Scene.NeedSceneCacheClear(avatar.UUID))
232 m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID);
233 m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID);
234 }
235 else
236 {
237 avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
238 }
239 }
240 else
241 {
242 // TP to a place that doesn't exist (anymore)
243 // Inform the viewer about that
244 avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore");
245
246 // and set the map-tile to '(Offline)'
247 uint regX, regY;
248 Utils.LongToUInts(regionHandle, out regX, out regY);
249
250 MapBlockData block = new MapBlockData();
251 block.X = (ushort)(regX / Constants.RegionSize);
252 block.Y = (ushort)(regY / Constants.RegionSize);
253 block.Access = 254; // == not there
254
255 List<MapBlockData> blocks = new List<MapBlockData>();
256 blocks.Add(block);
257 avatar.ControllingClient.SendMapBlock(blocks, 0);
258 }
259 }
260 }
261
262 }
263}