aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Hypergrid
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
parent* removed superfluous constants class (diff)
downloadopensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.zip
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.gz
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.bz2
opensim-SC_OLD-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')
-rw-r--r--OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs376
-rw-r--r--OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs152
-rw-r--r--OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.cs84
-rw-r--r--OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs360
4 files changed, 972 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}
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs
new file mode 100644
index 0000000..f36075e
--- /dev/null
+++ b/OpenSim/Region/Framework/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;
43// using OpenSim.Region.Environment;
44using OpenSim.Region.Framework.Scenes;
45
46namespace OpenSim.Region.Framework.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,
62 ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
63 bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
64 : base(regInfo, authen, commsMan, sceneGridService, assetCach, storeManager, 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(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient)
106 {
107 UUID assetID = base.DeleteToInventory(action, 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/Framework/Scenes/Hypergrid/HGScene.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.cs
new file mode 100644
index 0000000..a52fdc6
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.cs
@@ -0,0 +1,84 @@
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;
37// using OpenSim.Region.Environment;
38using OpenSim.Region.Framework.Scenes;
39using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
40
41namespace OpenSim.Region.Framework.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 if (uinfo != null)
56 {
57 UserProfileData UserProfile = uinfo.UserProfile;
58
59 if (UserProfile != null)
60 {
61 RegionInfo regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegion);
62 //if (regionInfo != null)
63 //{
64 // UserProfile.HomeRegionID = regionInfo.RegionID;
65 // //CommsManager.UserService.UpdateUserProfile(UserProfile);
66 //}
67 if (regionInfo == null)
68 {
69 // can't find the Home region: Tell viewer and abort
70 client.SendTeleportFailed("Your home-region could not be found.");
71 return;
72 }
73 RequestTeleportLocation(
74 client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt,
75 (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome));
76 }
77 }
78 else
79 client.SendTeleportFailed("Sorry! I lost your home-region information.");
80
81 }
82
83 }
84}
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
new file mode 100644
index 0000000..d0dc4f7
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
@@ -0,0 +1,360 @@
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.Net;
32using System.Reflection;
33using System.Threading;
34using log4net;
35using OpenMetaverse;
36using OSD = OpenMetaverse.StructuredData.OSD;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Cache;
40using OpenSim.Framework.Communications.Capabilities;
41using OpenSim.Region.Framework.Scenes;
42// using OpenSim.Region.Environment;
43using OpenSim.Region.Framework.Interfaces;
44
45namespace OpenSim.Region.Framework.Scenes.Hypergrid
46{
47 public class HGSceneCommunicationService : SceneCommunicationService
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 public readonly 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 = true;
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 uint newRegionX = (uint)(reg.RegionHandle >> 40);
113 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
114 uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
115 uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
116
117 ///
118 /// Hypergrid mod start
119 ///
120 ///
121 bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle);
122 bool isHomeUser = true;
123 ulong realHandle = regionHandle;
124 CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID);
125 if (uinfo != null)
126 {
127 isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile);
128 realHandle = m_hg.FindRegionHandle(regionHandle);
129 Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString());
130 }
131 ///
132 /// Hypergrid mod stop
133 ///
134 ///
135
136 if (eq == null)
137 avatar.ControllingClient.SendTeleportLocationStart();
138
139
140 // Let's do DNS resolution only once in this process, please!
141 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
142 // it's actually doing a lot of work.
143 IPEndPoint endPoint = reg.ExternalEndPoint;
144 if (endPoint.Address == null)
145 {
146 // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses.
147 destRegionUp = false;
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
157 if (!avatar.ValidateAttachments())
158 {
159 avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
160 return;
161 }
162
163 // the avatar.Close below will clear the child region list. We need this below for (possibly)
164 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
165 //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
166 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
167 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
168 // once we reach here...
169 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
170
171 string capsPath = String.Empty;
172 AgentCircuitData agentCircuit = avatar.ControllingClient.RequestClientInfo();
173 agentCircuit.BaseFolder = UUID.Zero;
174 agentCircuit.InventoryFolder = UUID.Zero;
175 agentCircuit.startpos = position;
176 agentCircuit.child = true;
177 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
178 {
179 // brand new agent, let's create a new caps seed
180 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
181 }
182
183 //if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agentCircuit))
184 if (!m_interregionCommsOut.SendCreateChildAgent(reg.RegionHandle, agentCircuit))
185 {
186 avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports.");
187 return;
188 }
189
190 // Let's close some agents
191 if (isHyperLink) // close them all except this one
192 {
193 List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles);
194 regions.Remove(avatar.Scene.RegionInfo.RegionHandle);
195 SendCloseChildAgentConnections(avatar.UUID, regions);
196 }
197 else // close just a few
198 avatar.CloseChildAgents(newRegionX, newRegionY);
199
200 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
201 {
202 capsPath
203 = "http://"
204 + reg.ExternalHostName
205 + ":"
206 + reg.HttpPort
207 + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
208
209 if (eq != null)
210 {
211 eq.EnableSimulator(realHandle, endPoint, avatar.UUID);
212
213 // ES makes the client send a UseCircuitCode message to the destination,
214 // which triggers a bunch of things there.
215 // So let's wait
216 Thread.Sleep(2000);
217
218 eq.EstablishAgentCommunication(avatar.UUID, endPoint, capsPath);
219 }
220 else
221 {
222 avatar.ControllingClient.InformClientOfNeighbour(realHandle, endPoint);
223 // TODO: make Event Queue disablable!
224 }
225 }
226 else
227 {
228 // child agent already there
229 agentCircuit.CapsPath = avatar.Scene.CapsModule.GetChildSeed(avatar.UUID, reg.RegionHandle);
230 capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort
231 + "/CAPS/" + agentCircuit.CapsPath + "0000/";
232 }
233
234 //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
235 // position, false);
236
237 //if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
238 // position, false))
239 //{
240 // avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
241 // // We should close that agent we just created over at destination...
242 // List<ulong> lst = new List<ulong>();
243 // lst.Add(realHandle);
244 // SendCloseChildAgentAsync(avatar.UUID, lst);
245 // return;
246 //}
247
248 SetInTransit(avatar.UUID);
249 // Let's send a full update of the agent. This is a synchronous call.
250 AgentData agent = new AgentData();
251 avatar.CopyTo(agent);
252 agent.Position = position;
253 agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort +
254 "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/";
255
256 m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent);
257
258 m_log.DebugFormat(
259 "[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID);
260
261
262 ///
263 /// Hypergrid mod: realHandle instead of reg.RegionHandle
264 ///
265 ///
266 if (eq != null)
267 {
268 eq.TeleportFinishEvent(realHandle, 13, endPoint,
269 4, teleportFlags, capsPath, avatar.UUID);
270 }
271 else
272 {
273 avatar.ControllingClient.SendRegionTeleport(realHandle, 13, endPoint, 4,
274 teleportFlags, capsPath);
275 }
276 ///
277 /// Hypergrid mod stop
278 ///
279
280
281 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
282 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
283 // that the client contacted the destination before we send the attachments and close things here.
284 if (!WaitForCallback(avatar.UUID))
285 {
286 // Client never contacted destination. Let's restore everything back
287 avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
288
289 ResetFromTransit(avatar.UUID);
290 // Yikes! We should just have a ref to scene here.
291 avatar.Scene.InformClientOfNeighbours(avatar);
292
293 // Finally, kill the agent we just created at the destination.
294 m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID);
295
296 return;
297 }
298
299 // Can't go back from here
300 if (KiPrimitive != null)
301 {
302 KiPrimitive(avatar.LocalId);
303 }
304
305 avatar.MakeChildAgent();
306
307 // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
308 avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
309
310
311 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
312 ///
313 /// Hypergrid mod: extra check for isHyperLink
314 ///
315 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
316 {
317 Thread.Sleep(5000);
318 avatar.Close();
319 CloseConnection(avatar.UUID);
320 }
321 // if (teleport success) // seems to be always success here
322 // the user may change their profile information in other region,
323 // so the userinfo in UserProfileCache is not reliable any more, delete it
324 if (avatar.Scene.NeedSceneCacheClear(avatar.UUID) || isHyperLink)
325 {
326 m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID);
327 m_log.DebugFormat(
328 "[HGSceneCommService]: User {0} is going to another region, profile cache removed",
329 avatar.UUID);
330 }
331 }
332 else
333 {
334 avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
335 }
336 }
337 else
338 {
339 // TP to a place that doesn't exist (anymore)
340 // Inform the viewer about that
341 avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore");
342
343 // and set the map-tile to '(Offline)'
344 uint regX, regY;
345 Utils.LongToUInts(regionHandle, out regX, out regY);
346
347 MapBlockData block = new MapBlockData();
348 block.X = (ushort)(regX / Constants.RegionSize);
349 block.Y = (ushort)(regY / Constants.RegionSize);
350 block.Access = 254; // == not there
351
352 List<MapBlockData> blocks = new List<MapBlockData>();
353 blocks.Add(block);
354 avatar.ControllingClient.SendMapBlock(blocks, 0);
355 }
356 }
357 }
358
359 }
360}