* 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
0.6.0-stable
Justin Clarke Casey 2008-08-01 18:49:48 +00:00
parent de4e3bfede
commit 43b2ff1d11
7 changed files with 83 additions and 38 deletions

View File

@ -75,7 +75,7 @@ namespace OpenSim.Framework.Communications.Cache
private readonly IList<IInventoryRequest> m_pendingRequests = new List<IInventoryRequest>(); private readonly IList<IInventoryRequest> m_pendingRequests = new List<IInventoryRequest>();
/// <summary> /// <summary>
/// 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.
/// </summary> /// </summary>
public InventoryFolderImpl RootFolder { get { return m_rootFolder; } } public InventoryFolderImpl RootFolder { get { return m_rootFolder; } }
private InventoryFolderImpl m_rootFolder; private InventoryFolderImpl m_rootFolder;
@ -183,6 +183,21 @@ namespace OpenSim.Framework.Communications.Cache
} }
} }
} }
/// <summary>
/// Drop all cached inventory.
/// </summary>
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;
}
}
/// <summary> /// <summary>
/// Callback invoked when the inventory is received from an async request to the inventory service /// Callback invoked when the inventory is received from an async request to the inventory service

View File

@ -118,21 +118,19 @@ namespace OpenSim.Framework.Communications.Cache
/// </summary> /// </summary>
/// <param name="userID"></param> /// <param name="userID"></param>
/// <returns>true if the user was successfully removed, false otherwise</returns> /// <returns>true if the user was successfully removed, false otherwise</returns>
public bool RemoveUser(LLUUID userID) public bool RemoveUser(LLUUID userId)
{ {
lock (m_userProfiles) 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; 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; return false;
} }

View File

@ -41,20 +41,34 @@ namespace OpenSim.Framework
// private static readonly log4net.ILog m_log // private static readonly log4net.ILog m_log
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The port by which http communication occurs with the region (most noticeably, CAPS communication)
/// </summary>
public uint HttpPort
{
get { return m_httpPort; }
set { m_httpPort = value; }
}
protected uint m_httpPort;
/// <summary>
/// A well-formed URI for the host region server (namely "http://" + ExternalHostName)
/// </summary>
public string ServerURI
{
get { return m_serverURI; }
set { m_serverURI = value; }
}
protected string m_serverURI;
protected bool Allow_Alternate_Ports; protected bool Allow_Alternate_Ports;
public bool m_allow_alternate_ports; public bool m_allow_alternate_ports;
protected string m_externalHostName; protected string m_externalHostName;
/// <value>
/// The port by which http communication occurs with the region (most noticeably, CAPS communication)
/// </value>
protected uint m_httpPort;
protected IPEndPoint m_internalEndPoint; protected IPEndPoint m_internalEndPoint;
protected uint? m_regionLocX; protected uint? m_regionLocX;
protected uint? m_regionLocY; protected uint? m_regionLocY;
protected uint m_remotingPort; protected uint m_remotingPort;
protected string m_serverURI;
public LLUUID RegionID = LLUUID.Zero; public LLUUID RegionID = LLUUID.Zero;
public string RemotingAddress; public string RemotingAddress;
@ -101,18 +115,6 @@ namespace OpenSim.Framework
set { m_remotingPort = value; } 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; }
}
/// <value> /// <value>
/// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw. /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw.
/// ///

View File

@ -195,7 +195,7 @@ namespace OpenSim.Framework.Servers
string path = request.RawUrl; string path = request.RawUrl;
string handlerKey = GetHandlerKey(request.HttpMethod, path); 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)) if (TryGetStreamHandler(handlerKey, out requestHandler))
{ {

View File

@ -1976,7 +1976,7 @@ namespace OpenSim.Region.Environment.Scenes
#region Add/Remove Avatar Methods #region Add/Remove Avatar Methods
/// <summary> /// <summary>
/// /// Register the new client with the scene
/// </summary> /// </summary>
/// <param name="client"></param /// <param name="client"></param
/// <param name="child"></param> /// <param name="child"></param>
@ -1991,7 +1991,7 @@ namespace OpenSim.Region.Environment.Scenes
if (m_restorePresences.ContainsKey(client.AgentId)) 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]; presence = m_restorePresences[client.AgentId];
m_restorePresences.Remove(client.AgentId); m_restorePresences.Remove(client.AgentId);
@ -2015,9 +2015,8 @@ namespace OpenSim.Region.Environment.Scenes
} }
else 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); CommsManager.UserProfileCacheService.AddNewUser(client);
CreateAndAddScenePresence(client, child); CreateAndAddScenePresence(client, child);

View File

@ -557,8 +557,10 @@ namespace OpenSim.Region.Environment.Scenes
LLVector3 lookAt, uint flags) LLVector3 lookAt, uint flags)
{ {
bool destRegionUp = false; bool destRegionUp = false;
if (regionHandle == m_regionInfo.RegionHandle) if (regionHandle == m_regionInfo.RegionHandle)
{ {
// Teleport within the same region
avatar.ControllingClient.SendTeleportLocationStart(); avatar.ControllingClient.SendTeleportLocationStart();
avatar.ControllingClient.SendLocalTeleport(position, lookAt, flags); avatar.ControllingClient.SendLocalTeleport(position, lookAt, flags);
avatar.Teleport(position); avatar.Teleport(position);

View File

@ -35,6 +35,7 @@ using libsecondlife;
using libsecondlife.Packets; using libsecondlife.Packets;
using log4net; using log4net;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Region.Environment.Types; using OpenSim.Region.Environment.Types;
using OpenSim.Region.Physics.Manager; 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. /// 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 /// 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
/// </summary> /// </summary>
public void MakeChildAgent() public void MakeChildAgent()
{ {
@ -1877,6 +1878,7 @@ namespace OpenSim.Region.Environment.Scenes
{ {
if (IsChildAgent) if (IsChildAgent)
return; return;
LLVector3 pos2 = AbsolutePosition; LLVector3 pos2 = AbsolutePosition;
LLVector3 vel = Velocity; 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 // in case both scenes are being hosted on the same region server. Messy
m_scene.RemoveCapsHandler(UUID); m_scene.RemoveCapsHandler(UUID);
newpos = newpos + (vel); 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_scene.InformNeighbourOfCrossing(neighbourHandle, m_controllingClient.AgentId, newpos,
m_physicsActor.Flying); m_physicsActor.Flying);
if (res) if (crossingSuccessful)
{ {
AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo();
@ -1965,12 +1987,19 @@ namespace OpenSim.Region.Environment.Scenes
m_controllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint, m_controllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint,
capsPath); capsPath);
MakeChildAgent(); MakeChildAgent();
CrossAttachmentsIntoNewRegion(neighbourHandle); CrossAttachmentsIntoNewRegion(neighbourHandle);
m_scene.SendKillObject(m_localId); m_scene.SendKillObject(m_localId);
m_scene.NotifyMyCoarseLocationChange(); m_scene.NotifyMyCoarseLocationChange();
} }
else 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); m_scene.AddCapsHandler(UUID);
} }
} }