From 43b2ff1d112174c36bb18caf353945afc6390840 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Fri, 1 Aug 2008 18:49:48 +0000 Subject: * Drop cached inventory from the local region when a user crosses out into a remote region * May resolves inventory problems that occur when the user moves between two regions` * e.g. if the user moves to a second region, adds an inventory item, moves back to the original region then tries to manipulate that item * Not yet implemented for teleport --- .../Communications/Cache/CachedUserInfo.cs | 17 ++++++++- .../Cache/UserProfileCacheService.cs | 12 +++---- OpenSim/Framework/RegionInfo.cs | 42 +++++++++++----------- OpenSim/Framework/Servers/BaseHttpServer.cs | 2 +- OpenSim/Region/Environment/Scenes/Scene.cs | 7 ++-- .../Scenes/SceneCommunicationService.cs | 2 ++ OpenSim/Region/Environment/Scenes/ScenePresence.cs | 39 +++++++++++++++++--- 7 files changed, 83 insertions(+), 38 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs index 025b934..d85eda0 100644 --- a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs +++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs @@ -75,7 +75,7 @@ namespace OpenSim.Framework.Communications.Cache private readonly IList m_pendingRequests = new List(); /// - /// The root folder of this user's inventory. Returns null if the inventory has not yet been received. + /// The root folder of this user's inventory. Returns null if the root folder has not yet been received. /// public InventoryFolderImpl RootFolder { get { return m_rootFolder; } } private InventoryFolderImpl m_rootFolder; @@ -183,6 +183,21 @@ namespace OpenSim.Framework.Communications.Cache } } } + + /// + /// Drop all cached inventory. + /// + public void DropInventory() + { + // Make sure there aren't pending requests around when we do this + // FIXME: There is still a race condition where an inventory operation can be requested (since these aren't being locked). + // Will have to extend locking to exclude this very soon. + lock (m_pendingRequests) + { + m_hasReceivedInventory = false; + m_rootFolder = null; + } + } /// /// Callback invoked when the inventory is received from an async request to the inventory service diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs index ac52535..5045c97 100644 --- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs +++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs @@ -118,21 +118,19 @@ namespace OpenSim.Framework.Communications.Cache /// /// /// true if the user was successfully removed, false otherwise - public bool RemoveUser(LLUUID userID) + public bool RemoveUser(LLUUID userId) { lock (m_userProfiles) { - if (m_userProfiles.ContainsKey(userID)) + if (m_userProfiles.ContainsKey(userId)) { - m_userProfiles.Remove(userID); + m_log.DebugFormat("[USER CACHE]: Removing user {0}", userId); + m_userProfiles.Remove(userId); return true; } - else - { - m_log.ErrorFormat("[USER CACHE]: Tried to remove the profile of user {0}, but this was not in the scene", userID); - } } + m_log.ErrorFormat("[USER CACHE]: Tried to remove the profile of user {0}, but this was not in the scene", userId); return false; } diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index ee64bf2..1d9d9ec 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -41,20 +41,34 @@ namespace OpenSim.Framework // private static readonly log4net.ILog m_log // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - protected bool Allow_Alternate_Ports; - public bool m_allow_alternate_ports; - protected string m_externalHostName; - - /// + /// /// The port by which http communication occurs with the region (most noticeably, CAPS communication) - /// + /// + public uint HttpPort + { + get { return m_httpPort; } + set { m_httpPort = value; } + } protected uint m_httpPort; + + /// + /// A well-formed URI for the host region server (namely "http://" + ExternalHostName) + /// + public string ServerURI + { + get { return m_serverURI; } + set { m_serverURI = value; } + } + protected string m_serverURI; + protected bool Allow_Alternate_Ports; + public bool m_allow_alternate_ports; + protected string m_externalHostName; + protected IPEndPoint m_internalEndPoint; protected uint? m_regionLocX; protected uint? m_regionLocY; - protected uint m_remotingPort; - protected string m_serverURI; + protected uint m_remotingPort; public LLUUID RegionID = LLUUID.Zero; public string RemotingAddress; @@ -101,18 +115,6 @@ namespace OpenSim.Framework set { m_remotingPort = value; } } - public uint HttpPort - { - get { return m_httpPort; } - set { m_httpPort = value; } - } - - public string ServerURI - { - get { return m_serverURI; } - set { m_serverURI = value; } - } - /// /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw. /// diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index f8b4ccb..eba49e4 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -195,7 +195,7 @@ namespace OpenSim.Framework.Servers string path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); - // m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); + //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); if (TryGetStreamHandler(handlerKey, out requestHandler)) { diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index c4078c9..f81248b 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1976,7 +1976,7 @@ namespace OpenSim.Region.Environment.Scenes #region Add/Remove Avatar Methods /// - /// + /// Register the new client with the scene /// /// @@ -1991,7 +1991,7 @@ namespace OpenSim.Region.Environment.Scenes if (m_restorePresences.ContainsKey(client.AgentId)) { - m_log.Info("[REGION]: Restore Scene Presence"); + m_log.Info("[REGION]: Restoring Scene Presence"); presence = m_restorePresences[client.AgentId]; m_restorePresences.Remove(client.AgentId); @@ -2015,9 +2015,8 @@ namespace OpenSim.Region.Environment.Scenes } else { - m_log.Info("[REGION]: Add New Scene Presence"); + m_log.Info("[REGION]: Adding New Scene Presence"); - //CommsManager.UserProfileCacheService.AddNewUser(client.AgentId); CommsManager.UserProfileCacheService.AddNewUser(client); CreateAndAddScenePresence(client, child); diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index b9bf42b..b35e60f 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -557,8 +557,10 @@ namespace OpenSim.Region.Environment.Scenes LLVector3 lookAt, uint flags) { bool destRegionUp = false; + if (regionHandle == m_regionInfo.RegionHandle) { + // Teleport within the same region avatar.ControllingClient.SendTeleportLocationStart(); avatar.ControllingClient.SendLocalTeleport(position, lookAt, flags); avatar.Teleport(position); diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 221da0e..bb3d953 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -35,6 +35,7 @@ using libsecondlife; using libsecondlife.Packets; using log4net; using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; using OpenSim.Region.Environment.Types; using OpenSim.Region.Physics.Manager; @@ -646,7 +647,7 @@ namespace OpenSim.Region.Environment.Scenes /// when an agent departs this region for a neighbor, this gets called. /// /// It doesn't get called for a teleport. Reason being, an agent that - /// teleports out may not be anywhere near this region + /// teleports out may not end up anywhere near this region /// public void MakeChildAgent() { @@ -1877,6 +1878,7 @@ namespace OpenSim.Region.Environment.Scenes { if (IsChildAgent) return; + LLVector3 pos2 = AbsolutePosition; LLVector3 vel = Velocity; @@ -1947,10 +1949,30 @@ namespace OpenSim.Region.Environment.Scenes // in case both scenes are being hosted on the same region server. Messy m_scene.RemoveCapsHandler(UUID); newpos = newpos + (vel); - bool res = + + bool crossingToRemoteRegion = neighbourRegion.ExternalHostName != m_scene.RegionInfo.ExternalHostName; + if (crossingToRemoteRegion) + { + m_scene.CommsManager.UserProfileCacheService.RemoveUser(UUID); + } + else + { + CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(UUID); + + if (userInfo != null) + { + userInfo.DropInventory(); + } + else + { + m_log.WarnFormat("[SCENE PRESENCE]: No cached user info found for {0} {1} on leaving region", Name, UUID); + } + } + + bool crossingSuccessful = m_scene.InformNeighbourOfCrossing(neighbourHandle, m_controllingClient.AgentId, newpos, - m_physicsActor.Flying); - if (res) + m_physicsActor.Flying); + if (crossingSuccessful) { AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); @@ -1965,12 +1987,19 @@ namespace OpenSim.Region.Environment.Scenes m_controllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint, capsPath); MakeChildAgent(); - CrossAttachmentsIntoNewRegion(neighbourHandle); + CrossAttachmentsIntoNewRegion(neighbourHandle); + m_scene.SendKillObject(m_localId); m_scene.NotifyMyCoarseLocationChange(); } else { + // Restore the user structures that we needed to delete before asking the receiving region to complete the crossing + if (crossingToRemoteRegion) + m_scene.CommsManager.UserProfileCacheService.AddNewUser(m_controllingClient); + + m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(UUID); + m_scene.AddCapsHandler(UUID); } } -- cgit v1.1