Merge branch 'master' of /home/opensim/var/repo/opensim
commit
26c332f5f2
|
@ -46,6 +46,29 @@ using Nini.Config;
|
||||||
|
|
||||||
namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The possible states that an agent can be in when its being transferred between regions.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a state machine.
|
||||||
|
///
|
||||||
|
/// [Entry] => Preparing
|
||||||
|
/// Preparing => { Transferring || CleaningUp || [Exit] }
|
||||||
|
/// Transferring => { ReceivedAtDestination || CleaningUp }
|
||||||
|
/// ReceivedAtDestination => CleaningUp
|
||||||
|
/// CleaningUp => [Exit]
|
||||||
|
///
|
||||||
|
/// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
|
||||||
|
/// However, any state can transition to CleaningUp if the teleport has failed.
|
||||||
|
/// </remarks>
|
||||||
|
enum AgentTransferState
|
||||||
|
{
|
||||||
|
Preparing, // The agent is being prepared for transfer
|
||||||
|
Transferring, // The agent is in the process of being transferred to a destination
|
||||||
|
ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
|
||||||
|
CleaningUp // The agent is being changed to child/removed after a transfer
|
||||||
|
}
|
||||||
|
|
||||||
public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
|
public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -68,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
protected Scene m_scene;
|
protected Scene m_scene;
|
||||||
|
|
||||||
protected List<UUID> m_agentsInTransit;
|
private Dictionary<UUID, AgentTransferState> m_agentsInTransit;
|
||||||
|
|
||||||
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
|
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
|
||||||
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
|
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
|
||||||
|
@ -120,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
MaxTransferDistance = DefaultMaxTransferDistance;
|
MaxTransferDistance = DefaultMaxTransferDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_agentsInTransit = new List<UUID>();
|
m_agentsInTransit = new Dictionary<UUID, AgentTransferState>();
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,17 +282,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
position.Z = newPosZ;
|
position.Z = newPosZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
|
||||||
|
|
||||||
sp.ControllingClient.SendTeleportStart(teleportFlags);
|
sp.ControllingClient.SendTeleportStart(teleportFlags);
|
||||||
|
|
||||||
sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
|
sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
|
||||||
sp.Velocity = Vector3.Zero;
|
sp.Velocity = Vector3.Zero;
|
||||||
sp.Teleport(position);
|
sp.Teleport(position);
|
||||||
|
|
||||||
|
UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination);
|
||||||
|
|
||||||
foreach (SceneObjectGroup grp in sp.GetAttachments())
|
foreach (SceneObjectGroup grp in sp.GetAttachments())
|
||||||
{
|
{
|
||||||
sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
|
sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
|
||||||
ResetFromTransit(sp.UUID);
|
ResetFromTransit(sp.UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,6 +536,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Past this point we have to attempt clean up if the teleport fails, so update transfer state.
|
||||||
|
UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
|
||||||
|
|
||||||
// OK, it got this agent. Let's close some child agents
|
// OK, it got this agent. Let's close some child agents
|
||||||
sp.CloseChildAgents(newRegionX, newRegionY);
|
sp.CloseChildAgents(newRegionX, newRegionY);
|
||||||
|
|
||||||
|
@ -598,6 +629,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
|
||||||
|
|
||||||
// For backwards compatibility
|
// For backwards compatibility
|
||||||
if (version == "Unknown" || version == string.Empty)
|
if (version == "Unknown" || version == string.Empty)
|
||||||
{
|
{
|
||||||
|
@ -624,8 +657,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
// We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
|
// We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
|
||||||
// they regard the new region as the current region after receiving the AgentMovementComplete
|
// they regard the new region as the current region after receiving the AgentMovementComplete
|
||||||
// response. If close is sent before then, it will cause the viewer to quit instead.
|
// response. If close is sent before then, it will cause the viewer to quit instead.
|
||||||
// However, if this delay is longer, then a viewer can teleport back to this region and experience
|
//
|
||||||
// a failure because the old ScenePresence has not yet been cleaned up.
|
// This sleep can be increased if necessary. However, whilst it's active,
|
||||||
|
// an agent cannot teleport back to this region if it has teleported away.
|
||||||
Thread.Sleep(2000);
|
Thread.Sleep(2000);
|
||||||
|
|
||||||
sp.Close();
|
sp.Close();
|
||||||
|
@ -644,6 +678,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
"[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
|
"[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
|
||||||
sp.UUID);
|
sp.UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResetFromTransit(sp.UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
|
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
|
||||||
|
@ -1089,6 +1125,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
|
Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
|
||||||
|
|
||||||
agent.RemoveFromPhysicalScene();
|
agent.RemoveFromPhysicalScene();
|
||||||
|
|
||||||
SetInTransit(agent.UUID);
|
SetInTransit(agent.UUID);
|
||||||
|
|
||||||
AgentData cAgent = new AgentData();
|
AgentData cAgent = new AgentData();
|
||||||
|
@ -1100,6 +1137,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
// We don't need the callback anymnore
|
// We don't need the callback anymnore
|
||||||
cAgent.CallbackURI = String.Empty;
|
cAgent.CallbackURI = String.Empty;
|
||||||
|
|
||||||
|
// Beyond this point, extra cleanup is needed beyond removing transit state
|
||||||
|
UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
|
||||||
|
|
||||||
if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
|
if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
|
||||||
{
|
{
|
||||||
// region doesn't take it
|
// region doesn't take it
|
||||||
|
@ -1142,7 +1182,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUCCESS!
|
// SUCCESS!
|
||||||
|
UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
|
||||||
|
|
||||||
|
// Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
|
||||||
|
UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
|
||||||
|
|
||||||
agent.MakeChildAgent();
|
agent.MakeChildAgent();
|
||||||
|
|
||||||
|
// FIXME: Possibly this should occur lower down after other commands to close other agents,
|
||||||
|
// but not sure yet what the side effects would be.
|
||||||
ResetFromTransit(agent.UUID);
|
ResetFromTransit(agent.UUID);
|
||||||
|
|
||||||
// now we have a child agent in this region. Request all interesting data about other (root) agents
|
// now we have a child agent in this region. Request all interesting data about other (root) agents
|
||||||
|
@ -1622,7 +1670,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
#region Agent Arrived
|
#region Agent Arrived
|
||||||
public void AgentArrivedAtDestination(UUID id)
|
public void AgentArrivedAtDestination(UUID id)
|
||||||
{
|
{
|
||||||
ResetFromTransit(id);
|
lock (m_agentsInTransit)
|
||||||
|
{
|
||||||
|
if (!m_agentsInTransit.ContainsKey(id))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but no teleport request is active",
|
||||||
|
m_scene.RegionInfo.RegionName, id);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AgentTransferState currentState = m_agentsInTransit[id];
|
||||||
|
|
||||||
|
if (currentState == AgentTransferState.ReceivedAtDestination)
|
||||||
|
{
|
||||||
|
// An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification.
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but notification has already previously been received",
|
||||||
|
m_scene.RegionInfo.RegionName, id);
|
||||||
|
}
|
||||||
|
else if (currentState != AgentTransferState.Transferring)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat(
|
||||||
|
"[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but agent is in transfer state {2}",
|
||||||
|
m_scene.RegionInfo.RegionName, id, currentState);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -1964,10 +2042,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
#region Misc
|
#region Misc
|
||||||
|
|
||||||
protected bool WaitForCallback(UUID id)
|
private bool WaitForCallback(UUID id)
|
||||||
{
|
{
|
||||||
|
lock (m_agentsInTransit)
|
||||||
|
{
|
||||||
|
if (!IsInTransit(id))
|
||||||
|
throw new Exception(
|
||||||
|
string.Format(
|
||||||
|
"Asked to wait for destination callback for agent with ID {0} but it is not in transit"));
|
||||||
|
|
||||||
|
AgentTransferState currentState = m_agentsInTransit[id];
|
||||||
|
|
||||||
|
if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination)
|
||||||
|
throw new Exception(
|
||||||
|
string.Format(
|
||||||
|
"Asked to wait for destination callback for agent with ID {0} but it is in state {1}",
|
||||||
|
currentState));
|
||||||
|
}
|
||||||
|
|
||||||
int count = 200;
|
int count = 200;
|
||||||
while (m_agentsInTransit.Contains(id) && count-- > 0)
|
|
||||||
|
// There should be no race condition here since no other code should be removing the agent transfer or
|
||||||
|
// changing the state to another other than Transferring => ReceivedAtDestination.
|
||||||
|
while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0)
|
||||||
{
|
{
|
||||||
// m_log.Debug(" >>> Waiting... " + count);
|
// m_log.Debug(" >>> Waiting... " + count);
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
|
@ -1977,17 +2074,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set that an agent is in the process of being teleported.
|
/// Set that an agent is in transit.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name='id'>The ID of the agent being teleported</param>
|
/// <param name='id'>The ID of the agent being teleported</param>
|
||||||
/// <returns>true if the agent was not already in transit, false if it was</returns>
|
/// <returns>true if the agent was not already in transit, false if it was</returns>
|
||||||
protected bool SetInTransit(UUID id)
|
private bool SetInTransit(UUID id)
|
||||||
{
|
{
|
||||||
lock (m_agentsInTransit)
|
lock (m_agentsInTransit)
|
||||||
{
|
{
|
||||||
if (!m_agentsInTransit.Contains(id))
|
if (!m_agentsInTransit.ContainsKey(id))
|
||||||
{
|
{
|
||||||
m_agentsInTransit.Add(id);
|
m_agentsInTransit[id] = AgentTransferState.Preparing;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1996,29 +2093,73 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show whether the given agent is being teleported.
|
/// Updates the state of an agent that is already in transit.
|
||||||
/// </summary>
|
|
||||||
/// <returns>true if the agent is in the process of being teleported, false otherwise.</returns>
|
|
||||||
/// <param name='id'>The agent ID</para></param>
|
|
||||||
public bool IsInTransit(UUID id)
|
|
||||||
{
|
|
||||||
lock (m_agentsInTransit)
|
|
||||||
return m_agentsInTransit.Contains(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set that an agent is no longer being teleported.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name='id'></param>
|
||||||
|
/// <param name='newState'></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <param name='id'>
|
/// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
|
||||||
/// true if the agent was flagged as being teleported when this method was called, false otherwise
|
private void UpdateInTransit(UUID id, AgentTransferState newState)
|
||||||
/// </param>
|
|
||||||
protected bool ResetFromTransit(UUID id)
|
|
||||||
{
|
{
|
||||||
lock (m_agentsInTransit)
|
lock (m_agentsInTransit)
|
||||||
{
|
{
|
||||||
if (m_agentsInTransit.Contains(id))
|
// Illegal to try and update an agent that's not actually in transit.
|
||||||
|
if (!m_agentsInTransit.ContainsKey(id))
|
||||||
|
throw new Exception(string.Format("Agent with ID {0} is not registered as in transit", id));
|
||||||
|
|
||||||
|
AgentTransferState oldState = m_agentsInTransit[id];
|
||||||
|
|
||||||
|
bool transitionOkay = false;
|
||||||
|
|
||||||
|
if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
|
||||||
|
transitionOkay = true;
|
||||||
|
else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
|
||||||
|
transitionOkay = true;
|
||||||
|
else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
|
||||||
|
transitionOkay = true;
|
||||||
|
|
||||||
|
if (transitionOkay)
|
||||||
|
m_agentsInTransit[id] = newState;
|
||||||
|
else
|
||||||
|
throw new Exception(
|
||||||
|
string.Format(
|
||||||
|
"Agent with ID {0} is not allowed to move from old transit state {1} to new state {2}",
|
||||||
|
id, oldState, newState));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsInTransit(UUID id)
|
||||||
|
{
|
||||||
|
lock (m_agentsInTransit)
|
||||||
|
return m_agentsInTransit.ContainsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes an agent from the transit state machine.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='id'></param>
|
||||||
|
/// <returns>true if the agent was flagged as being teleported when this method was called, false otherwise</returns>
|
||||||
|
private bool ResetFromTransit(UUID id)
|
||||||
|
{
|
||||||
|
lock (m_agentsInTransit)
|
||||||
|
{
|
||||||
|
if (m_agentsInTransit.ContainsKey(id))
|
||||||
{
|
{
|
||||||
|
AgentTransferState state = m_agentsInTransit[id];
|
||||||
|
|
||||||
|
if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination)
|
||||||
|
{
|
||||||
|
// FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed
|
||||||
|
// to be handled properly - ResetFromTransit() could be invoked at any step along the process
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[ENTITY TRANSFER MODULE]: Agent with ID should not exit directly from state {1}, should go to {2} state first",
|
||||||
|
state, AgentTransferState.CleaningUp);
|
||||||
|
|
||||||
|
// throw new Exception(
|
||||||
|
// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first",
|
||||||
|
// state, AgentTransferState.CleaningUp);
|
||||||
|
}
|
||||||
|
|
||||||
m_agentsInTransit.Remove(id);
|
m_agentsInTransit.Remove(id);
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
|
|
|
@ -226,13 +226,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
return m_remoteConnector.RetrieveAgent(destination, id, out agent);
|
return m_remoteConnector.RetrieveAgent(destination, id, out agent);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
|
||||||
{
|
{
|
||||||
reason = "Communications failure";
|
reason = "Communications failure";
|
||||||
version = "Unknown";
|
version = "Unknown";
|
||||||
|
|
||||||
if (destination == null)
|
if (destination == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -245,7 +245,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||||
return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason);
|
return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ReleaseAgent(UUID origin, UUID id, string uri)
|
public bool ReleaseAgent(UUID origin, UUID id, string uri)
|
||||||
|
|
|
@ -77,8 +77,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show whether the given agent is being teleported.
|
/// Show whether the given agent is being teleported.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>true if the agent is in the process of being teleported, false otherwise.</returns>
|
|
||||||
/// <param name='id'>The agent ID</para></param>
|
/// <param name='id'>The agent ID</para></param>
|
||||||
|
/// <returns>true if the agent is in the process of being teleported, false otherwise.</returns>
|
||||||
bool IsInTransit(UUID id);
|
bool IsInTransit(UUID id);
|
||||||
|
|
||||||
bool Cross(ScenePresence agent, bool isFlying);
|
bool Cross(ScenePresence agent, bool isFlying);
|
||||||
|
|
|
@ -5212,10 +5212,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (EntityTransferModule.IsInTransit(agentID))
|
if (EntityTransferModule.IsInTransit(agentID))
|
||||||
{
|
{
|
||||||
reason = "Agent is already in transit on this region";
|
reason = "Agent is still in transit from this region";
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.WarnFormat(
|
||||||
"[SCENE]: Denying agent {0} entry into {1} since region already has them registered as in transit",
|
"[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit",
|
||||||
agentID, RegionInfo.RegionName);
|
agentID, RegionInfo.RegionName);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -144,13 +144,16 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
|
|
||||||
responsedata["int_response_code"] = HttpStatusCode.OK;
|
responsedata["int_response_code"] = HttpStatusCode.OK;
|
||||||
|
|
||||||
OSDMap resp = new OSDMap(2);
|
OSDMap resp = new OSDMap(3);
|
||||||
|
|
||||||
resp["success"] = OSD.FromBoolean(result);
|
resp["success"] = OSD.FromBoolean(result);
|
||||||
resp["reason"] = OSD.FromString(reason);
|
resp["reason"] = OSD.FromString(reason);
|
||||||
resp["version"] = OSD.FromString(version);
|
resp["version"] = OSD.FromString(version);
|
||||||
|
|
||||||
responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
|
// We must preserve defaults here, otherwise a false "success" will not be put into the JSON map!
|
||||||
|
responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp, true);
|
||||||
|
|
||||||
|
// Console.WriteLine("str_response_string [{0}]", responsedata["str_response_string"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, UUID regionID)
|
protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, UUID regionID)
|
||||||
|
|
|
@ -320,29 +320,40 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
{
|
{
|
||||||
OSDMap data = (OSDMap)result["_Result"];
|
OSDMap data = (OSDMap)result["_Result"];
|
||||||
|
|
||||||
|
// FIXME: If there is a _Result map then it's the success key here that indicates the true success
|
||||||
|
// or failure, not the sibling result node.
|
||||||
|
success = data["success"];
|
||||||
|
|
||||||
reason = data["reason"].AsString();
|
reason = data["reason"].AsString();
|
||||||
if (data["version"] != null && data["version"].AsString() != string.Empty)
|
if (data["version"] != null && data["version"].AsString() != string.Empty)
|
||||||
version = data["version"].AsString();
|
version = data["version"].AsString();
|
||||||
|
|
||||||
m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1} version {2} ({3})", uri, success, version, data["version"].AsString());
|
m_log.DebugFormat(
|
||||||
|
"[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}, reason {2}, version {3} ({4})",
|
||||||
|
uri, success, reason, version, data["version"].AsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
if (result.ContainsKey("Message"))
|
// If we don't check this then OpenSimulator 0.7.3.1 and some period before will never see the
|
||||||
|
// actual failure message
|
||||||
|
if (!result.ContainsKey("_Result"))
|
||||||
{
|
{
|
||||||
string message = result["Message"].AsString();
|
if (result.ContainsKey("Message"))
|
||||||
if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region
|
|
||||||
{
|
{
|
||||||
m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored");
|
string message = result["Message"].AsString();
|
||||||
return true;
|
if (message == "Service request failed: [MethodNotAllowed] MethodNotAllowed") // Old style region
|
||||||
}
|
{
|
||||||
|
m_log.Info("[REMOTE SIMULATION CONNECTOR]: The above web util error was caused by a TP to a sim that doesn't support QUERYACCESS and can be ignored");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
reason = result["Message"];
|
reason = result["Message"];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reason = "Communications failure";
|
reason = "Communications failure";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -352,7 +363,7 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] QueryAcess failed with exception; {0}",e.ToString());
|
m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] QueryAcesss failed with exception; {0}",e.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue