From e187972377c19bdd85093677c4c54034e4f9196e Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Tue, 25 Nov 2008 15:19:00 +0000
Subject: * 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!
---
.../Modules/Hypergrid/HGStandaloneAssetService.cs | 199 +++++++++++
.../Hypergrid/HGStandaloneInventoryService.cs | 315 +++++++++++++++++
.../Modules/Hypergrid/HGWorldMapModule.cs | 178 ++++++++++
.../Environment/Scenes/Hypergrid/HGAssetMapper.cs | 377 +++++++++++++++++++++
.../Scenes/Hypergrid/HGScene.Inventory.cs | 152 +++++++++
.../Region/Environment/Scenes/Hypergrid/HGScene.cs | 78 +++++
.../Hypergrid/HGSceneCommunicationService.cs | 263 ++++++++++++++
7 files changed, 1562 insertions(+)
create mode 100644 OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneAssetService.cs
create mode 100644 OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneInventoryService.cs
create mode 100644 OpenSim/Region/Environment/Modules/Hypergrid/HGWorldMapModule.cs
create mode 100644 OpenSim/Region/Environment/Scenes/Hypergrid/HGAssetMapper.cs
create mode 100644 OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.Inventory.cs
create mode 100644 OpenSim/Region/Environment/Scenes/Hypergrid/HGScene.cs
create mode 100644 OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs
(limited to 'OpenSim/Region/Environment')
diff --git a/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneAssetService.cs b/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneAssetService.cs
new file mode 100644
index 0000000..cfcda42
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneAssetService.cs
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Reflection;
+
+using log4net;
+using Nini.Config;
+
+using OpenMetaverse;
+
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Servers;
+using OpenSim.Region.Environment.Interfaces;
+using OpenSim.Region.Environment.Scenes;
+using OpenSim.Grid.AssetServer;
+
+namespace OpenSim.Region.Environment.Modules.Hypergrid
+{
+ public class HGStandaloneAssetService : IRegionModule
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static bool initialized = false;
+ private static bool enabled = false;
+
+ Scene m_scene;
+ AssetService m_assetService;
+
+ #region IRegionModule interface
+
+ public void Initialise(Scene scene, IConfigSource config)
+ {
+ if (!initialized)
+ {
+ initialized = true;
+ m_scene = scene;
+
+ // This module is only on for standalones in hypergrid mode
+ enabled = !config.Configs["Startup"].GetBoolean("gridmode", true) && config.Configs["Startup"].GetBoolean("hypergrid", false);
+ }
+ }
+
+ public void PostInitialise()
+ {
+ if (enabled)
+ {
+ m_log.Info("[HGStandaloneAssetService]: Starting...");
+
+ m_assetService = new AssetService(m_scene);
+ }
+ }
+
+ public void Close()
+ {
+ }
+
+ public string Name
+ {
+ get { return "HGStandaloneAssetService"; }
+ }
+
+ public bool IsSharedModule
+ {
+ get { return true; }
+ }
+
+ #endregion
+
+ }
+
+ public class AssetService
+ {
+ private IUserService m_userService;
+ private bool m_doLookup = false;
+
+ public bool DoLookup
+ {
+ get { return m_doLookup; }
+ set { m_doLookup = value; }
+ }
+ private static readonly ILog m_log
+ = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ public AssetService(Scene m_scene)
+ {
+ AddHttpHandlers(m_scene);
+ m_userService = m_scene.CommsManager.UserService;
+ }
+
+ protected void AddHttpHandlers(Scene m_scene)
+ {
+ IAssetProviderPlugin m_assetProvider = ((AssetServerBase)m_scene.AssetCache.AssetServer).AssetProviderPlugin;
+
+ m_scene.AddStreamHandler(new GetAssetStreamHandler(m_assetProvider));
+ m_scene.AddStreamHandler(new PostAssetStreamHandler(m_assetProvider));
+
+ }
+
+
+ /////
+ ///// Check that the source of an inventory request is one that we trust.
+ /////
+ /////
+ /////
+ //public bool CheckTrustSource(IPEndPoint peer)
+ //{
+ // if (m_doLookup)
+ // {
+ // m_log.InfoFormat("[GRID AGENT INVENTORY]: Checking trusted source {0}", peer);
+ // UriBuilder ub = new UriBuilder(m_userserver_url);
+ // IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host);
+ // foreach (IPAddress uaddr in uaddrs)
+ // {
+ // if (uaddr.Equals(peer.Address))
+ // {
+ // return true;
+ // }
+ // }
+
+ // m_log.WarnFormat(
+ // "[GRID AGENT INVENTORY]: Rejecting request since source {0} was not in the list of trusted sources",
+ // peer);
+
+ // return false;
+ // }
+ // else
+ // {
+ // return true;
+ // }
+ //}
+
+ ///
+ /// Check that the source of an inventory request for a particular agent is a current session belonging to
+ /// that agent.
+ ///
+ ///
+ ///
+ ///
+ public bool CheckAuthSession(string session_id, string avatar_id)
+ {
+ if (m_doLookup)
+ {
+ m_log.InfoFormat("[HGStandaloneInvService]: checking authed session {0} {1}", session_id, avatar_id);
+ UUID userID = UUID.Zero;
+ UUID sessionID = UUID.Zero;
+ UUID.TryParse(avatar_id, out userID);
+ UUID.TryParse(session_id, out sessionID);
+ if (userID.Equals(UUID.Zero) || sessionID.Equals(UUID.Zero))
+ {
+ m_log.Info("[HGStandaloneInvService]: Invalid user or session id " + avatar_id + "; " + session_id);
+ return false;
+ }
+ UserProfileData userProfile = m_userService.GetUserProfile(userID);
+ if (userProfile != null && userProfile.CurrentAgent != null &&
+ userProfile.CurrentAgent.SessionID == sessionID)
+ {
+ m_log.Info("[HGStandaloneInvService]: user is logged in and session is valid. Authorizing access.");
+ return true;
+ }
+
+ m_log.Warn("[HGStandaloneInvService]: unknown user or session_id, request rejected");
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ }
+}
diff --git a/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneInventoryService.cs b/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneInventoryService.cs
new file mode 100644
index 0000000..7203b88
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Hypergrid/HGStandaloneInventoryService.cs
@@ -0,0 +1,315 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Reflection;
+
+using log4net;
+using Nini.Config;
+
+using OpenMetaverse;
+
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Servers;
+using OpenSim.Region.Environment.Interfaces;
+using OpenSim.Region.Environment.Scenes;
+
+namespace OpenSim.Region.Environment.Modules.Hypergrid
+{
+ public class HGStandaloneInventoryService : IRegionModule
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static bool initialized = false;
+ private static bool enabled = false;
+
+ Scene m_scene;
+ InventoryService m_inventoryService;
+
+ #region IRegionModule interface
+
+ public void Initialise(Scene scene, IConfigSource config)
+ {
+ if (!initialized)
+ {
+ initialized = true;
+ m_scene = scene;
+
+ // This module is only on for standalones
+ enabled = !config.Configs["Startup"].GetBoolean("gridmode", true) && config.Configs["Startup"].GetBoolean("hypergrid", false);
+ }
+ }
+
+ public void PostInitialise()
+ {
+ if (enabled)
+ {
+ m_log.Info("[HGStandaloneInvService]: Starting...");
+ m_inventoryService = new InventoryService(m_scene);
+ }
+ }
+
+ public void Close()
+ {
+ }
+
+ public string Name
+ {
+ get { return "HGStandaloneInventoryService"; }
+ }
+
+ public bool IsSharedModule
+ {
+ get { return true; }
+ }
+
+ #endregion
+
+ }
+
+ public class InventoryService
+ {
+ private InventoryServiceBase m_inventoryService;
+ private IUserService m_userService;
+ private bool m_doLookup = false;
+
+ public bool DoLookup
+ {
+ get { return m_doLookup; }
+ set { m_doLookup = value; }
+ }
+ private static readonly ILog m_log
+ = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ public InventoryService(Scene m_scene)
+ {
+ m_inventoryService = (InventoryServiceBase)m_scene.CommsManager.SecureInventoryService;
+ m_userService = m_scene.CommsManager.UserService;
+ AddHttpHandlers(m_scene);
+
+ }
+
+ protected void AddHttpHandlers(Scene m_scene)
+ {
+ m_scene.AddStreamHandler(
+ new RestDeserialiseSecureHandler(
+ "POST", "/GetInventory/", GetUserInventory, CheckAuthSession));
+
+ m_scene.AddStreamHandler(
+ new RestDeserialiseSecureHandler(
+ "POST", "/NewFolder/", m_inventoryService.AddFolder, CheckAuthSession));
+
+ m_scene.AddStreamHandler(
+ new RestDeserialiseSecureHandler(
+ "POST", "/UpdateFolder/", m_inventoryService.UpdateFolder, CheckAuthSession));
+
+ m_scene.AddStreamHandler(
+ new RestDeserialiseSecureHandler(
+ "POST", "/MoveFolder/", m_inventoryService.MoveFolder, CheckAuthSession));
+
+ m_scene.AddStreamHandler(
+ new RestDeserialiseSecureHandler(
+ "POST", "/PurgeFolder/", m_inventoryService.PurgeFolder, CheckAuthSession));
+
+ m_scene.AddStreamHandler(
+ new RestDeserialiseSecureHandler(
+ "POST", "/NewItem/", m_inventoryService.AddItem, CheckAuthSession));
+
+ m_scene.AddStreamHandler(
+ new RestDeserialiseSecureHandler(
+ "POST", "/DeleteItem/", m_inventoryService.DeleteItem, CheckAuthSession));
+
+ //// WARNING: Root folders no longer just delivers the root and immediate child folders (e.g
+ //// system folders such as Objects, Textures), but it now returns the entire inventory skeleton.
+ //// It would have been better to rename this request, but complexities in the BaseHttpServer
+ //// (e.g. any http request not found is automatically treated as an xmlrpc request) make it easier
+ //// to do this for now.
+ //m_scene.AddStreamHandler(
+ // new RestDeserialiseTrustedHandler>
+ // ("POST", "/RootFolders/", GetInventorySkeleton, CheckTrustSource));
+
+ //// for persistent active gestures
+ //m_scene.AddStreamHandler(
+ // new RestDeserialiseTrustedHandler>
+ // ("POST", "/ActiveGestures/", GetActiveGestures, CheckTrustSource));
+ }
+
+
+ /////
+ ///// Check that the source of an inventory request is one that we trust.
+ /////
+ /////
+ /////
+ //public bool CheckTrustSource(IPEndPoint peer)
+ //{
+ // if (m_doLookup)
+ // {
+ // m_log.InfoFormat("[GRID AGENT INVENTORY]: Checking trusted source {0}", peer);
+ // UriBuilder ub = new UriBuilder(m_userserver_url);
+ // IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host);
+ // foreach (IPAddress uaddr in uaddrs)
+ // {
+ // if (uaddr.Equals(peer.Address))
+ // {
+ // return true;
+ // }
+ // }
+
+ // m_log.WarnFormat(
+ // "[GRID AGENT INVENTORY]: Rejecting request since source {0} was not in the list of trusted sources",
+ // peer);
+
+ // return false;
+ // }
+ // else
+ // {
+ // return true;
+ // }
+ //}
+
+ ///
+ /// Check that the source of an inventory request for a particular agent is a current session belonging to
+ /// that agent.
+ ///
+ ///
+ ///
+ ///
+ public bool CheckAuthSession(string session_id, string avatar_id)
+ {
+ if (m_doLookup)
+ {
+ m_log.InfoFormat("[HGStandaloneInvService]: checking authed session {0} {1}", session_id, avatar_id);
+ UUID userID = UUID.Zero;
+ UUID sessionID = UUID.Zero;
+ UUID.TryParse(avatar_id, out userID);
+ UUID.TryParse(session_id, out sessionID);
+ if (userID.Equals(UUID.Zero) || sessionID.Equals(UUID.Zero))
+ {
+ m_log.Info("[HGStandaloneInvService]: Invalid user or session id " + avatar_id + "; " + session_id);
+ return false;
+ }
+ UserProfileData userProfile = m_userService.GetUserProfile(userID);
+ if (userProfile != null && userProfile.CurrentAgent != null &&
+ userProfile.CurrentAgent.SessionID == sessionID)
+ {
+ m_log.Info("[HGStandaloneInvService]: user is logged in and session is valid. Authorizing access.");
+ return true;
+ }
+
+ m_log.Warn("[HGStandaloneInvService]: unknown user or session_id, request rejected");
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+
+ ///
+ /// Return a user's entire inventory
+ ///
+ ///
+ /// The user's inventory. If an inventory cannot be found then an empty collection is returned.
+ public InventoryCollection GetUserInventory(Guid rawUserID)
+ {
+ UUID userID = new UUID(rawUserID);
+
+ m_log.Info("[HGStandaloneInvService]: Processing request for inventory of " + userID);
+
+ // Uncomment me to simulate a slow responding inventory server
+ //Thread.Sleep(16000);
+
+ InventoryCollection invCollection = new InventoryCollection();
+
+ List allFolders = ((InventoryServiceBase)m_inventoryService).GetInventorySkeleton(userID);
+
+ if (null == allFolders)
+ {
+ m_log.WarnFormat("[HGStandaloneInvService]: No inventory found for user {0}", rawUserID);
+
+ return invCollection;
+ }
+
+ List allItems = new List();
+
+ foreach (InventoryFolderBase folder in allFolders)
+ {
+ List items = ((InventoryServiceBase)m_inventoryService).RequestFolderItems(folder.ID);
+
+ if (items != null)
+ {
+ allItems.InsertRange(0, items);
+ }
+ }
+
+ invCollection.UserID = userID;
+ invCollection.Folders = allFolders;
+ invCollection.Items = allItems;
+
+ // foreach (InventoryFolderBase folder in invCollection.Folders)
+ // {
+ // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back folder {0} {1}", folder.Name, folder.ID);
+ // }
+ //
+ // foreach (InventoryItemBase item in invCollection.Items)
+ // {
+ // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back item {0} {1}, folder {2}", item.Name, item.ID, item.Folder);
+ // }
+
+ m_log.InfoFormat(
+ "[HGStandaloneInvService]: Sending back inventory response to user {0} containing {1} folders and {2} items",
+ invCollection.UserID, invCollection.Folders.Count, invCollection.Items.Count);
+
+ return invCollection;
+ }
+
+ ///
+ /// Guid to UUID wrapper for same name IInventoryServices method
+ ///
+ ///
+ ///
+ public List GetInventorySkeleton(Guid rawUserID)
+ {
+ UUID userID = new UUID(rawUserID);
+ return ((InventoryServiceBase)m_inventoryService).GetInventorySkeleton(userID);
+ }
+
+ public List GetActiveGestures(Guid rawUserID)
+ {
+ UUID userID = new UUID(rawUserID);
+
+ m_log.InfoFormat("[HGStandaloneInvService]: fetching active gestures for user {0}", userID);
+
+ return ((InventoryServiceBase)m_inventoryService).GetActiveGestures(userID);
+ }
+ }
+}
diff --git a/OpenSim/Region/Environment/Modules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/Environment/Modules/Hypergrid/HGWorldMapModule.cs
new file mode 100644
index 0000000..7f8f285
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Hypergrid/HGWorldMapModule.cs
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Net;
+using System.Reflection;
+using System.Threading;
+using OpenMetaverse;
+using OpenMetaverse.Imaging;
+using OpenMetaverse.StructuredData;
+using log4net;
+using Nini.Config;
+using Nwc.XmlRpc;
+
+using OpenSim.Framework;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Communications.Capabilities;
+using OpenSim.Framework.Servers;
+using OpenSim.Region.Environment.Interfaces;
+using OpenSim.Region.Environment.Modules.World.WorldMap;
+using OpenSim.Region.Environment.Scenes;
+using OpenSim.Region.Environment.Types;
+using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
+
+using OSD = OpenMetaverse.StructuredData.OSD;
+using OSDMap = OpenMetaverse.StructuredData.OSDMap;
+using OSDArray = OpenMetaverse.StructuredData.OSDArray;
+
+namespace OpenSim.Region.Environment.Modules.Hypergrid
+{
+ public class HGWorldMapModule : WorldMapModule, IRegionModule
+ {
+ private static readonly ILog m_log =
+ LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ #region IRegionModule Members
+
+ public override void Initialise(Scene scene, IConfigSource config)
+ {
+ IConfig startupConfig = config.Configs["Startup"];
+ if (startupConfig.GetString("WorldMapModule", "WorldMap") == "HGWorldMap")
+ m_Enabled = true;
+
+ if (!m_Enabled)
+ return;
+ m_log.Info("[HGMap] Initializing...");
+ m_scene = scene;
+ }
+
+
+ public override string Name
+ {
+ get { return "HGWorldMap"; }
+ }
+
+
+ #endregion
+
+ ///
+ /// Requests map blocks in area of minX, maxX, minY, MaxY in world cordinates
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
+ {
+ //
+ // WARNING!!! COPY & PASTE FROM SUPERCLASS
+ // The only difference is at the very end
+ //
+
+ m_log.Info("[HGMap]: Request map blocks " + minX + "-" + maxX + " " + minY + "-" + maxY);
+
+ //m_scene.ForEachScenePresence(delegate (ScenePresence sp) {
+ // if (!sp.IsChildAgent && sp.UUID == remoteClient.AgentId)
+ // {
+ // Console.WriteLine("XXX Root agent");
+ // DoRequestMapBlocks(remoteClient, minX, minY, maxX, maxY, flag);
+ // }
+ //};
+
+ List mapBlocks;
+ if ((flag & 0x10000) != 0) // user clicked on the map a tile that isn't visible
+ {
+ List response = new List();
+
+ // this should return one mapblock at most. But make sure: Look whether the one we requested is in there
+ mapBlocks = m_scene.SceneGridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
+ if (mapBlocks != null)
+ {
+ foreach (MapBlockData block in mapBlocks)
+ {
+ if (block.X == minX && block.Y == minY)
+ {
+ // found it => add it to response
+ response.Add(block);
+ break;
+ }
+ }
+ }
+ response = mapBlocks;
+ if (response.Count == 0)
+ {
+ // response still empty => couldn't find the map-tile the user clicked on => tell the client
+ MapBlockData block = new MapBlockData();
+ block.X = (ushort)minX;
+ block.Y = (ushort)minY;
+ block.Access = 254; // == not there
+ response.Add(block);
+ }
+ remoteClient.SendMapBlock(response, 0);
+ }
+ else
+ {
+ // normal mapblock request. Use the provided values
+ mapBlocks = m_scene.SceneGridService.RequestNeighbourMapBlocks(minX - 4, minY - 4, maxX + 4, maxY + 4);
+
+ // Different from super
+ FillInMap(mapBlocks, minX, minY, maxX, maxY);
+ //
+
+ remoteClient.SendMapBlock(mapBlocks, flag);
+ }
+ }
+
+
+ private void FillInMap(List mapBlocks, int minX, int minY, int maxX, int maxY)
+ {
+ for (int x = minX; x <= maxX; x++)
+ for (int y = minY; y <= maxY; y++)
+ {
+ MapBlockData mblock = mapBlocks.Find(delegate(MapBlockData mb) { return ((mb.X == x) && (mb.Y == y)); });
+ if (mblock == null)
+ {
+ mblock = new MapBlockData();
+ mblock.X = (ushort)x;
+ mblock.Y = (ushort)y;
+ mblock.Name = "";
+ mblock.Access = 254; // not here???
+ mblock.MapImageId = UUID.Zero;
+ mapBlocks.Add(mblock);
+ }
+ }
+ }
+ }
+}
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 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+
+using log4net;
+using Nini.Config;
+using OpenMetaverse;
+
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Servers;
+using OpenSim.Region.Environment;
+using OpenSim.Region.Environment.Scenes;
+
+//using HyperGrid.Framework;
+//using OpenSim.Region.Communications.Hypergrid;
+
+namespace OpenSim.Region.Environment.Scenes.Hypergrid
+{
+ public class HGAssetMapper
+ {
+ #region Fields
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ // This maps between asset server URLs and asset server clients
+ private Dictionary m_assetServers = new Dictionary();
+
+ // This maps between asset UUIDs and asset servers
+ private Dictionary m_assetMap = new Dictionary();
+
+ private Scene m_scene;
+ #endregion
+
+ #region Constructor
+
+ public HGAssetMapper(Scene scene)
+ {
+ m_scene = scene;
+ }
+
+ #endregion
+
+ #region Internal functions
+
+ private string UserAssetURL(UUID userID)
+ {
+ CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
+ if (uinfo != null)
+ return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI;
+ return null;
+ }
+
+ private bool IsHomeUser(UUID userID)
+ {
+ CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
+
+ if (uinfo != null)
+ {
+ //if ((uinfo.UserProfile.UserAssetURI == null) || (uinfo.UserProfile.UserAssetURI == "") ||
+ // uinfo.UserProfile.UserAssetURI.Equals(m_scene.CommsManager.NetworkServersInfo.AssetURL))
+ if (HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI))
+ {
+ m_log.Debug("[HGScene]: Home user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
+ return true;
+ }
+ }
+
+ m_log.Debug("[HGScene]: Foreign user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
+ return false;
+ }
+
+ private bool IsInAssetMap(UUID uuid)
+ {
+ return m_assetMap.ContainsKey(uuid);
+ }
+
+ private bool FetchAsset(GridAssetClient asscli, UUID assetID, bool isTexture)
+ {
+ // I'm not going over 3 seconds since this will be blocking processing of all the other inbound
+ // packets from the client.
+ int pollPeriod = 200;
+ int maxPolls = 15;
+
+ AssetBase asset;
+
+ // Maybe it came late, and it's already here. Check first.
+ if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset))
+ {
+ m_log.Debug("[HGScene]: Asset already in asset cache. " + assetID);
+ return true;
+ }
+
+
+ asscli.RequestAsset(assetID, isTexture);
+
+ do
+ {
+ Thread.Sleep(pollPeriod);
+
+ if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset) && (asset != null))
+ {
+ m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Name + " " + assetID);
+ // I think I need to store it in the asset DB too.
+ // For now, let me just do it for textures and scripts
+ if (((AssetType)asset.Type == AssetType.Texture) ||
+ ((AssetType)asset.Type == AssetType.LSLBytecode) ||
+ ((AssetType)asset.Type == AssetType.LSLText))
+ {
+ AssetBase asset1 = new AssetBase();
+ Copy(asset, asset1);
+ m_scene.AssetCache.AssetServer.StoreAsset(asset1);
+ }
+ return true;
+ }
+ } while (--maxPolls > 0);
+
+ m_log.WarnFormat("[HGScene]: {0} {1} was not received before the retrieval timeout was reached",
+ isTexture ? "texture" : "asset", assetID.ToString());
+
+ return false;
+ }
+
+ private bool PostAsset(GridAssetClient asscli, UUID assetID)
+ {
+ AssetBase asset1;
+ m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset1);
+
+ if (asset1 != null)
+ {
+ // See long comment in AssetCache.AddAsset
+ if (!asset1.Temporary || asset1.Local)
+ {
+ // The asset cache returns instances of subclasses of AssetBase:
+ // TextureImage or AssetInfo. So in passing them to the remote
+ // server we first need to convert this to instances of AssetBase,
+ // which is the serializable class for assets.
+ AssetBase asset = new AssetBase();
+ Copy(asset1, asset);
+
+ asscli.StoreAsset(asset);
+ }
+ return true;
+ }
+ else
+ m_log.Warn("[HGScene]: Tried to post asset to remote server, but asset not in local cache.");
+
+ return false;
+ }
+
+ private void Copy(AssetBase from, AssetBase to)
+ {
+ to.Data = from.Data;
+ to.Description = from.Description;
+ to.FullID = from.FullID;
+ to.ID = from.ID;
+ to.Local = from.Local;
+ to.Name = from.Name;
+ to.Temporary = from.Temporary;
+ to.Type = from.Type;
+
+ }
+
+ private void _guardedAdd(Dictionary lst, UUID obj, bool val)
+ {
+ if (!lst.ContainsKey(obj))
+ lst.Add(obj, val);
+ }
+
+ private void SniffTextureUUIDs(Dictionary uuids, SceneObjectGroup sog)
+ {
+ try
+ {
+ _guardedAdd(uuids, sog.RootPart.Shape.Textures.DefaultTexture.TextureID, true);
+ }
+ catch (Exception) { }
+
+ foreach (Primitive.TextureEntryFace tface in sog.RootPart.Shape.Textures.FaceTextures)
+ {
+ try
+ {
+ _guardedAdd(uuids, tface.TextureID, true);
+ }
+ catch (Exception) { }
+ }
+
+ foreach (SceneObjectPart sop in sog.Children.Values)
+ {
+ try
+ {
+ _guardedAdd(uuids, sop.Shape.Textures.DefaultTexture.TextureID, true);
+ }
+ catch (Exception) { }
+ foreach (Primitive.TextureEntryFace tface in sop.Shape.Textures.FaceTextures)
+ {
+ try
+ {
+ _guardedAdd(uuids, tface.TextureID, true);
+ }
+ catch (Exception) { }
+ }
+ }
+ }
+
+ private void SniffTaskInventoryUUIDs(Dictionary uuids, SceneObjectGroup sog)
+ {
+ TaskInventoryDictionary tinv = sog.RootPart.TaskInventory;
+
+ foreach (TaskInventoryItem titem in tinv.Values)
+ {
+ uuids.Add(titem.AssetID, (InventoryType)titem.Type == InventoryType.Texture);
+ }
+ }
+
+ private Dictionary SniffUUIDs(AssetBase asset)
+ {
+ Dictionary uuids = new Dictionary();
+ if ((asset != null) && ((AssetType)asset.Type == AssetType.Object))
+ {
+ string ass_str = Utils.BytesToString(asset.Data);
+ SceneObjectGroup sog = new SceneObjectGroup(ass_str, true);
+
+ SniffTextureUUIDs(uuids, sog);
+
+ // We need to sniff further...
+ SniffTaskInventoryUUIDs(uuids, sog);
+
+ }
+
+ return uuids;
+ }
+
+ private Dictionary SniffUUIDs(UUID assetID)
+ {
+ Dictionary uuids = new Dictionary();
+
+ AssetBase asset;
+ m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset);
+
+ return SniffUUIDs(asset);
+ }
+
+ private void Dump(Dictionary lst)
+ {
+ m_log.Debug("XXX -------- UUID DUMP ------- XXX");
+ foreach (KeyValuePair kvp in lst)
+ m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")");
+ m_log.Debug("XXX -------- UUID DUMP ------- XXX");
+ }
+
+ #endregion
+
+
+ #region Public interface
+
+ public void Get(UUID itemID, UUID ownerID)
+ {
+ if (!IsInAssetMap(itemID) && !IsHomeUser(ownerID))
+ {
+ // Get the item from the remote asset server onto the local AssetCache
+ // and place an entry in m_assetMap
+
+ GridAssetClient asscli = null;
+ string userAssetURL = UserAssetURL(ownerID);
+ if (userAssetURL != null)
+ {
+ m_assetServers.TryGetValue(userAssetURL, out asscli);
+ if (asscli == null)
+ {
+ m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
+ asscli = new GridAssetClient(userAssetURL);
+ asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
+ m_assetServers.Add(userAssetURL, asscli);
+ }
+
+ m_log.Debug("[HGScene]: Fetching object " + itemID + " to asset server " + userAssetURL);
+ bool success = FetchAsset(asscli, itemID, false); // asscli.RequestAsset(item.ItemID, false);
+
+ // OK, now fetch the inside.
+ Dictionary ids = SniffUUIDs(itemID);
+ Dump(ids);
+ foreach (KeyValuePair kvp in ids)
+ FetchAsset(asscli, kvp.Key, kvp.Value);
+
+
+ if (success)
+ {
+ m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL);
+ m_assetMap.Add(itemID, asscli);
+ }
+ else
+ m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL);
+ }
+ else
+ m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
+ }
+ }
+
+ public void Post(UUID itemID, UUID ownerID)
+ {
+ if (!IsHomeUser(ownerID))
+ {
+ // Post the item from the local AssetCache ontp the remote asset server
+ // and place an entry in m_assetMap
+
+ GridAssetClient asscli = null;
+ string userAssetURL = UserAssetURL(ownerID);
+ if (userAssetURL != null)
+ {
+ m_assetServers.TryGetValue(userAssetURL, out asscli);
+ if (asscli == null)
+ {
+ m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
+ asscli = new GridAssetClient(userAssetURL);
+ asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
+ m_assetServers.Add(userAssetURL, asscli);
+ }
+ m_log.Debug("[HGScene]: Posting object " + itemID + " to asset server " + userAssetURL);
+ bool success = PostAsset(asscli, itemID);
+
+ // Now the inside
+ Dictionary ids = SniffUUIDs(itemID);
+ Dump(ids);
+ foreach (KeyValuePair kvp in ids)
+ PostAsset(asscli, kvp.Key);
+
+ if (success)
+ {
+ m_log.Debug("[HGScene]: Successfully posted item to remote asset server " + userAssetURL);
+ m_assetMap.Add(itemID, asscli);
+ }
+ else
+ m_log.Warn("[HGScene]: Could not post asset to remote asset server " + userAssetURL);
+
+ //if (!m_assetMap.ContainsKey(itemID))
+ // m_assetMap.Add(itemID, asscli);
+ }
+ else
+ m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
+
+ }
+ }
+
+ #endregion
+
+ }
+}
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 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+
+using log4net;
+using Nini.Config;
+using OpenMetaverse;
+
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Servers;
+using OpenSim.Region.Environment;
+using OpenSim.Region.Environment.Scenes;
+
+namespace OpenSim.Region.Environment.Scenes.Hypergrid
+{
+ public partial class HGScene : Scene
+ {
+ #region Fields
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private HGAssetMapper m_assMapper;
+
+ #endregion
+
+ #region Constructors
+
+ public HGScene(RegionInfo regInfo, AgentCircuitManager authen,
+ CommunicationsManager commsMan, SceneCommunicationService sceneGridService,
+ AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer,
+ ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
+ bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
+ : base(regInfo, authen, commsMan, sceneGridService, assetCach, storeManager, httpServer, moduleLoader,
+ dumpAssetsToFile, physicalPrim, SeeIntoRegionFromNeighbor, config, simulatorVersion)
+ {
+ m_log.Info("[HGScene]: Starting HGScene.");
+ m_assMapper = new HGAssetMapper(this);
+
+ EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
+ }
+
+ #endregion
+
+ #region Event handlers
+
+ public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
+ {
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(avatarID);
+ if (userInfo != null)
+ {
+ m_assMapper.Post(assetID, avatarID);
+ }
+ }
+
+ #endregion
+
+ #region Overrides of Scene.Inventory methods
+
+ ///
+ /// CapsUpdateInventoryItemAsset
+ ///
+ public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
+ {
+ UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
+
+ UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0);
+
+ return newAssetID;
+ }
+
+ ///
+ /// DeleteToInventory
+ ///
+ public override UUID DeleteToInventory(int destination, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient)
+ {
+ UUID assetID = base.DeleteToInventory(destination, folderID, objectGroup, remoteClient);
+
+ if (!assetID.Equals(UUID.Zero))
+ {
+ UploadInventoryItem(remoteClient.AgentId, assetID, "", 0);
+ }
+ else
+ m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
+
+ return assetID;
+ }
+
+ ///
+ /// RezObject
+ ///
+ public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
+ UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
+ bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
+ {
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+ if (userInfo != null)
+ {
+ if (userInfo.RootFolder != null)
+ {
+ InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
+
+ if (item != null)
+ {
+ m_assMapper.Get(item.AssetID, remoteClient.AgentId);
+
+ }
+ }
+ }
+
+ // OK, we're done fetching. Pass it up to the default RezObject
+ return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
+ RezSelected, RemoveItem, fromTaskID, attachment);
+
+ }
+
+
+ #endregion
+
+ }
+
+}
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 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+
+using OpenMetaverse;
+
+using OpenSim.Framework;
+
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Region.Environment;
+using OpenSim.Region.Environment.Scenes;
+using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
+
+namespace OpenSim.Region.Environment.Scenes.Hypergrid
+{
+ public partial class HGScene : Scene
+ {
+ ///
+ /// Teleport an avatar to their home region
+ ///
+ ///
+ ///
+ public override void TeleportClientHome(UUID agentId, IClientAPI client)
+ {
+ m_log.Debug("[HGScene]: TeleportClientHome " + client.FirstName + " " + client.LastName);
+
+ CachedUserInfo uinfo = CommsManager.UserProfileCacheService.GetUserDetails(agentId);
+ UserProfileData UserProfile = uinfo.UserProfile;
+
+ if (UserProfile != null)
+ {
+ RegionInfo regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegion);
+ //if (regionInfo != null)
+ //{
+ // UserProfile.HomeRegionID = regionInfo.RegionID;
+ // //CommsManager.UserService.UpdateUserProfile(UserProfile);
+ //}
+ if (regionInfo == null)
+ {
+ // can't find the Home region: Tell viewer and abort
+ client.SendTeleportFailed("Your home-region could not be found.");
+ return;
+ }
+ RequestTeleportLocation(
+ client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt,
+ (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome));
+ }
+ }
+
+ }
+}
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 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+
+using OpenMetaverse;
+
+using log4net;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Region.Environment.Scenes;
+using OpenSim.Region.Environment;
+using OpenSim.Region.Interfaces;
+using OSD = OpenMetaverse.StructuredData.OSD;
+
+namespace OpenSim.Region.Environment.Scenes.Hypergrid
+{
+ public class HGSceneCommunicationService : SceneCommunicationService
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private IHyperlink m_hg;
+
+ public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan)
+ {
+ m_hg = hg;
+ }
+
+
+ ///
+ /// Try to teleport an agent to a new region.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position,
+ Vector3 lookAt, uint teleportFlags)
+ {
+ if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID))
+ return;
+
+ bool destRegionUp = false;
+
+ IEventQueue eq = avatar.Scene.RequestModuleInterface();
+
+ if (regionHandle == m_regionInfo.RegionHandle)
+ {
+ // Teleport within the same region
+ if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0)
+ {
+ Vector3 emergencyPos = new Vector3(128, 128, 128);
+
+ m_log.WarnFormat(
+ "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
+ position, avatar.Name, avatar.UUID, emergencyPos);
+ position = emergencyPos;
+ }
+ // TODO: Get proper AVG Height
+ float localAVHeight = 1.56f;
+ float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y);
+ float newPosZ = posZLimit + localAVHeight;
+ if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
+ {
+ position.Z = newPosZ;
+ }
+
+ // Only send this if the event queue is null
+ if (eq == null)
+ avatar.ControllingClient.SendTeleportLocationStart();
+
+
+ avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
+ avatar.Teleport(position);
+ }
+ else
+ {
+ RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle);
+ if (reg != null)
+ {
+ ///
+ /// Hypergrid mod start
+ ///
+ ///
+ bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle);
+ bool isHomeUser = true;
+ ulong realHandle = regionHandle;
+ CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID);
+ if (uinfo != null)
+ {
+ isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI);
+ realHandle = m_hg.FindRegionHandle(regionHandle);
+ Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString());
+ }
+ ///
+ /// Hypergrid mod stop
+ ///
+ ///
+
+ if (eq == null)
+ avatar.ControllingClient.SendTeleportLocationStart();
+
+ AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
+ agent.BaseFolder = UUID.Zero;
+ agent.InventoryFolder = UUID.Zero;
+ agent.startpos = position;
+ agent.child = true;
+
+ if (reg.RemotingAddress != "" && reg.RemotingPort != 0)
+ {
+ // region is remote. see if it is up
+ destRegionUp = m_commsProvider.InterRegion.CheckRegion(reg.RemotingAddress, reg.RemotingPort);
+ }
+ else
+ {
+ // assume local regions are always up
+ destRegionUp = true;
+ }
+
+ if (destRegionUp)
+ {
+ // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
+ // both regions
+ if (avatar.ParentID != (uint)0)
+ avatar.StandUp();
+ if (!avatar.ValidateAttachments())
+ {
+ avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
+ return;
+ }
+
+ // the avatar.Close below will clear the child region list. We need this below for (possibly)
+ // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
+ List childRegions = new List(avatar.GetKnownRegionList());
+ // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
+ // failure at this point (unlike a border crossing failure). So perhaps this can never fail
+ // once we reach here...
+ avatar.Scene.RemoveCapsHandler(avatar.UUID);
+ agent.child = false;
+ m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent);
+
+ m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
+ position, false);
+ Thread.Sleep(2000);
+ AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo();
+
+ // TODO Should construct this behind a method
+ string capsPath =
+ "http://" + reg.ExternalHostName + ":" + reg.HttpPort
+ + "/CAPS/" + circuitdata.CapsPath + "0000/";
+
+ m_log.DebugFormat(
+ "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID);
+
+
+ ///
+ /// Hypergrid mod: realHandle instead of reg.RegionHandle
+ ///
+ ///
+ if (eq != null)
+ {
+ OSD Item = EventQueueHelper.TeleportFinishEvent(realHandle, 13, reg.ExternalEndPoint,
+ 4, teleportFlags, capsPath, avatar.UUID);
+ eq.Enqueue(Item, avatar.UUID);
+ }
+ else
+ {
+ avatar.ControllingClient.SendRegionTeleport(realHandle, 13, reg.ExternalEndPoint, 4,
+ teleportFlags, capsPath);
+ }
+ ///
+ /// Hypergrid mod stop
+ ///
+
+ avatar.MakeChildAgent();
+ Thread.Sleep(7000);
+ avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
+ if (KiPrimitive != null)
+ {
+ KiPrimitive(avatar.LocalId);
+ }
+
+ avatar.Close();
+
+ uint newRegionX = (uint)(reg.RegionHandle >> 40);
+ uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
+ uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
+ uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
+ ///
+ /// Hypergrid mod: extra check for isHyperLink
+ ///
+ if ((Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) || isHyperLink)
+ {
+ //SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList());
+ SendCloseChildAgentConnections(avatar.UUID, childRegions);
+ CloseConnection(avatar.UUID);
+ }
+ // if (teleport success) // seems to be always success here
+ // the user may change their profile information in other region,
+ // so the userinfo in UserProfileCache is not reliable any more, delete it
+ if (avatar.Scene.NeedSceneCacheClear(avatar.UUID))
+ m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID);
+ m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID);
+ }
+ else
+ {
+ avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
+ }
+ }
+ else
+ {
+ // TP to a place that doesn't exist (anymore)
+ // Inform the viewer about that
+ avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore");
+
+ // and set the map-tile to '(Offline)'
+ uint regX, regY;
+ Utils.LongToUInts(regionHandle, out regX, out regY);
+
+ MapBlockData block = new MapBlockData();
+ block.X = (ushort)(regX / Constants.RegionSize);
+ block.Y = (ushort)(regY / Constants.RegionSize);
+ block.Access = 254; // == not there
+
+ List blocks = new List();
+ blocks.Add(block);
+ avatar.ControllingClient.SendMapBlock(blocks, 0);
+ }
+ }
+ }
+
+ }
+}
--
cgit v1.1