Merge branch 'TeleportWork'
commit
97bcb59bee
|
@ -91,7 +91,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
|||
public void RemoveForClient()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID spId = TestHelpers.ParseTail(0x1);
|
||||
|
||||
|
|
|
@ -512,7 +512,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// We still perform a force close inside the sync lock since this is intended to attempt close where
|
||||
// there is some unidentified connection problem, not where we have issues due to deadlock
|
||||
if (!IsActive && !force)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[CLIENT]: Not attempting to close inactive client {0} in {1} since force flag is not set",
|
||||
Name, m_scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
IsActive = false;
|
||||
CloseWithoutChecks();
|
||||
|
|
|
@ -1799,9 +1799,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
if (!client.SceneAgent.IsChildAgent)
|
||||
client.Kick("Simulator logged you out due to connection timeout.");
|
||||
|
||||
client.CloseWithoutChecks();
|
||||
}
|
||||
|
||||
m_scene.IncomingCloseAgent(client.AgentId, true);
|
||||
}
|
||||
|
||||
private void IncomingPacketHandler()
|
||||
|
@ -2142,7 +2142,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if (!client.IsLoggingOut)
|
||||
{
|
||||
client.IsLoggingOut = true;
|
||||
client.Close();
|
||||
m_scene.IncomingCloseAgent(client.AgentId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
|||
public void TestLogoutClientDueToAck()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
TestHelpers.EnableLogging();
|
||||
|
||||
IniConfigSource ics = new IniConfigSource();
|
||||
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
|
||||
|
|
|
@ -1064,8 +1064,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// Now let's make it officially a child agent
|
||||
sp.MakeChildAgent();
|
||||
|
||||
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
|
||||
// May still need to signal neighbours whether child agents may need closing irrespective of whether this
|
||||
// one needed closing. Neighbour regions also contain logic to prevent a close if a subsequent move or
|
||||
// teleport re-established the child connection.
|
||||
//
|
||||
// It may be possible to also close child agents after a pause but one needs to be very careful about
|
||||
// race conditions between different regions on rapid teleporting (e.g. from A1 to a non-neighbour B, back
|
||||
// to a neighbour A2 then off to a non-neighbour C. Also, closing child agents early may be more compatible
|
||||
// with complicated scenarios where there a mixture of V1 and V2 teleports, though this is conjecture. It's
|
||||
// easier to close immediately and greatly reduce the scope of race conditions if possible.
|
||||
sp.CloseChildAgents(newRegionX, newRegionY);
|
||||
|
||||
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
|
||||
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
|
||||
{
|
||||
sp.DoNotCloseAfterTeleport = false;
|
||||
|
@ -1081,14 +1091,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
if (!sp.DoNotCloseAfterTeleport)
|
||||
{
|
||||
// OK, it got this agent. Let's close everything
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.Name);
|
||||
sp.CloseChildAgents(newRegionX, newRegionY);
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing agent {0} in {1}", sp.Name, Scene.Name);
|
||||
sp.Scene.IncomingCloseAgent(sp.UUID, false);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.Name);
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {1}", sp.Name, Scene.Name);
|
||||
sp.DoNotCloseAfterTeleport = false;
|
||||
}
|
||||
}
|
||||
|
@ -1863,10 +1871,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles);
|
||||
List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
|
||||
|
||||
//Dump("Current Neighbors", neighbourHandles);
|
||||
//Dump("Previous Neighbours", previousRegionNeighbourHandles);
|
||||
//Dump("New Neighbours", newRegions);
|
||||
//Dump("Old Neighbours", oldRegions);
|
||||
// Dump("Current Neighbors", neighbourHandles);
|
||||
// Dump("Previous Neighbours", previousRegionNeighbourHandles);
|
||||
// Dump("New Neighbours", newRegions);
|
||||
// Dump("Old Neighbours", oldRegions);
|
||||
|
||||
/// Update the scene presence's known regions here on this region
|
||||
sp.DropOldNeighbours(oldRegions);
|
||||
|
@ -1874,8 +1882,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
/// Collect as many seeds as possible
|
||||
Dictionary<ulong, string> seeds;
|
||||
if (sp.Scene.CapsModule != null)
|
||||
seeds
|
||||
= new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
|
||||
seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
|
||||
else
|
||||
seeds = new Dictionary<ulong, string>();
|
||||
|
||||
|
@ -1945,6 +1952,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
newAgent = true;
|
||||
else
|
||||
newAgent = false;
|
||||
// continue;
|
||||
|
||||
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
|
||||
{
|
||||
|
|
|
@ -562,7 +562,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
|||
if (!Scene.TeleportClientHome(user, s.ControllingClient))
|
||||
{
|
||||
s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out.");
|
||||
s.ControllingClient.Close();
|
||||
Scene.IncomingCloseAgent(s.UUID, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -797,7 +797,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
|||
if (!Scene.TeleportClientHome(prey, s.ControllingClient))
|
||||
{
|
||||
s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
|
||||
s.ControllingClient.Close();
|
||||
Scene.IncomingCloseAgent(s.UUID, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -820,7 +820,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
|||
if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient))
|
||||
{
|
||||
p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
|
||||
p.ControllingClient.Close();
|
||||
Scene.IncomingCloseAgent(p.UUID, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public SynchronizeSceneHandler SynchronizeScene;
|
||||
|
||||
/// <summary>
|
||||
/// Used to prevent simultaneous calls to RemoveClient() for the same agent from interfering with each other.
|
||||
/// Used to prevent simultaneous calls to code that adds and removes agents.
|
||||
/// </summary>
|
||||
private object m_removeClientLock = new object();
|
||||
|
||||
|
@ -1312,7 +1312,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Thread.Sleep(500);
|
||||
|
||||
// Stop all client threads.
|
||||
ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
|
||||
ForEachScenePresence(delegate(ScenePresence avatar) { IncomingCloseAgent(avatar.UUID, false); });
|
||||
|
||||
m_log.Debug("[SCENE]: Persisting changed objects");
|
||||
EventManager.TriggerSceneShuttingDown(this);
|
||||
|
@ -2972,7 +2972,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
|
||||
|
||||
sp.ControllingClient.Close();
|
||||
IncomingCloseAgent(sp.UUID, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3384,35 +3384,36 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public override void RemoveClient(UUID agentID, bool closeChildAgents)
|
||||
{
|
||||
// CheckHeartbeat();
|
||||
bool isChildAgent = false;
|
||||
AgentCircuitData acd;
|
||||
AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID);
|
||||
|
||||
lock (m_removeClientLock)
|
||||
// Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
|
||||
// in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
|
||||
// However, will keep for now just in case.
|
||||
if (acd == null)
|
||||
{
|
||||
acd = m_authenticateHandler.GetAgentCircuitData(agentID);
|
||||
m_log.ErrorFormat(
|
||||
"[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name);
|
||||
|
||||
if (acd == null)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We remove the acd up here to avoid later race conditions if two RemoveClient() calls occurred
|
||||
// simultaneously.
|
||||
// We also need to remove by agent ID since NPCs will have no circuit code.
|
||||
m_authenticateHandler.RemoveCircuit(agentID);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_authenticateHandler.RemoveCircuit(agentID);
|
||||
}
|
||||
|
||||
// TODO: Can we now remove this lock?
|
||||
lock (acd)
|
||||
{
|
||||
bool isChildAgent = false;
|
||||
|
||||
ScenePresence avatar = GetScenePresence(agentID);
|
||||
|
||||
// Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
|
||||
// in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
|
||||
// However, will keep for now just in case.
|
||||
if (avatar == null)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
m_log.ErrorFormat(
|
||||
"[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
|
||||
|
||||
return;
|
||||
|
@ -3424,7 +3425,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Removing {0} agent {1} {2} from {3}",
|
||||
(isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
|
||||
isChildAgent ? "child" : "root", avatar.Name, agentID, Name);
|
||||
|
||||
// Don't do this to root agents, it's not nice for the viewer
|
||||
if (closeChildAgents && isChildAgent)
|
||||
|
@ -3587,13 +3588,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
|
||||
/// the LLUDP stack).
|
||||
/// </remarks>
|
||||
/// <param name="agent">CircuitData of the agent who is connecting</param>
|
||||
/// <param name="acd">CircuitData of the agent who is connecting</param>
|
||||
/// <param name="reason">Outputs the reason for the false response on this string</param>
|
||||
/// <param name="requirePresenceLookup">True for normal presence. False for NPC
|
||||
/// or other applications where a full grid/Hypergrid presence may not be required.</param>
|
||||
/// <returns>True if the region accepts this agent. False if it does not. False will
|
||||
/// also return a reason.</returns>
|
||||
public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup)
|
||||
public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, out string reason, bool requirePresenceLookup)
|
||||
{
|
||||
bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
|
||||
(teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
|
||||
|
@ -3613,15 +3614,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_log.DebugFormat(
|
||||
"[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})",
|
||||
RegionInfo.RegionName,
|
||||
(agent.child ? "child" : "root"),
|
||||
agent.firstname,
|
||||
agent.lastname,
|
||||
agent.AgentID,
|
||||
agent.circuitcode,
|
||||
agent.IPAddress,
|
||||
agent.Viewer,
|
||||
(acd.child ? "child" : "root"),
|
||||
acd.firstname,
|
||||
acd.lastname,
|
||||
acd.AgentID,
|
||||
acd.circuitcode,
|
||||
acd.IPAddress,
|
||||
acd.Viewer,
|
||||
((TPFlags)teleportFlags).ToString(),
|
||||
agent.startpos
|
||||
acd.startpos
|
||||
);
|
||||
|
||||
if (!LoginsEnabled)
|
||||
|
@ -3639,7 +3640,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
foreach (string viewer in m_AllowedViewers)
|
||||
{
|
||||
if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower())
|
||||
if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower())
|
||||
{
|
||||
ViewerDenied = false;
|
||||
break;
|
||||
|
@ -3656,7 +3657,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
foreach (string viewer in m_BannedViewers)
|
||||
{
|
||||
if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower())
|
||||
if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower())
|
||||
{
|
||||
ViewerDenied = true;
|
||||
break;
|
||||
|
@ -3668,61 +3669,112 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Access denied for {0} {1} using {2}",
|
||||
agent.firstname, agent.lastname, agent.Viewer);
|
||||
acd.firstname, acd.lastname, acd.Viewer);
|
||||
reason = "Access denied, your viewer is banned by the region owner";
|
||||
return false;
|
||||
}
|
||||
|
||||
ILandObject land;
|
||||
ScenePresence sp;
|
||||
|
||||
lock (agent)
|
||||
lock (m_removeClientLock)
|
||||
{
|
||||
ScenePresence sp = GetScenePresence(agent.AgentID);
|
||||
sp = GetScenePresence(acd.AgentID);
|
||||
|
||||
if (sp != null)
|
||||
// We need to ensure that we are not already removing the scene presence before we ask it not to be
|
||||
// closed.
|
||||
if (sp != null && sp.IsChildAgent && sp.LifecycleState == ScenePresenceState.Running)
|
||||
{
|
||||
if (!sp.IsChildAgent)
|
||||
{
|
||||
// We have a root agent. Is it in transit?
|
||||
if (!EntityTransferModule.IsInTransit(sp.UUID))
|
||||
{
|
||||
// We have a zombie from a crashed session.
|
||||
// Or the same user is trying to be root twice here, won't work.
|
||||
// Kill it.
|
||||
m_log.WarnFormat(
|
||||
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
|
||||
sp.Name, sp.UUID, RegionInfo.RegionName);
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Reusing existing child scene presence for {0} in {1}", sp.Name, Name);
|
||||
|
||||
if (sp.ControllingClient != null)
|
||||
sp.ControllingClient.Close(true);
|
||||
|
||||
sp = null;
|
||||
}
|
||||
//else
|
||||
// m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName);
|
||||
}
|
||||
else
|
||||
// In the case where, for example, an A B C D region layout, an avatar may
|
||||
// teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
|
||||
// renews the lease on the child agent at B, we must make sure that the close from A does not succeed.
|
||||
if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle))
|
||||
{
|
||||
// We have a child agent here
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.",
|
||||
sp.Name, Name);
|
||||
|
||||
sp.DoNotCloseAfterTeleport = true;
|
||||
//m_log.WarnFormat("[SCENE]: Existing child scene presence for {0} {1} in {2}", sp.Name, sp.UUID, RegionInfo.RegionName);
|
||||
}
|
||||
else if (EntityTransferModule.IsInTransit(sp.UUID))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt previous end-of-teleport close.",
|
||||
sp.Name, Name);
|
||||
|
||||
sp.DoNotCloseAfterTeleport = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to poll here in case we are currently deleting an sp. Letting threads run over each other will
|
||||
// allow unpredictable things to happen.
|
||||
if (sp != null)
|
||||
{
|
||||
const int polls = 10;
|
||||
const int pollInterval = 1000;
|
||||
int pollsLeft = polls;
|
||||
|
||||
while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0)
|
||||
Thread.Sleep(pollInterval);
|
||||
|
||||
if (sp.LifecycleState == ScenePresenceState.Removing)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.",
|
||||
sp.Name, Name, polls * pollInterval / 1000);
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (polls != pollsLeft)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.",
|
||||
sp.Name, Name, polls * pollInterval / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: can we remove this lock?
|
||||
lock (acd)
|
||||
{
|
||||
if (sp != null && !sp.IsChildAgent)
|
||||
{
|
||||
// We have a root agent. Is it in transit?
|
||||
if (!EntityTransferModule.IsInTransit(sp.UUID))
|
||||
{
|
||||
// We have a zombie from a crashed session.
|
||||
// Or the same user is trying to be root twice here, won't work.
|
||||
// Kill it.
|
||||
m_log.WarnFormat(
|
||||
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
|
||||
sp.Name, sp.UUID, RegionInfo.RegionName);
|
||||
|
||||
if (sp.ControllingClient != null)
|
||||
IncomingCloseAgent(sp.UUID, true);
|
||||
|
||||
sp = null;
|
||||
}
|
||||
//else
|
||||
// m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
// Optimistic: add or update the circuit data with the new agent circuit data and teleport flags.
|
||||
// We need the circuit data here for some of the subsequent checks. (groups, for example)
|
||||
// If the checks fail, we remove the circuit.
|
||||
agent.teleportFlags = teleportFlags;
|
||||
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
|
||||
acd.teleportFlags = teleportFlags;
|
||||
m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd);
|
||||
|
||||
land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
|
||||
land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y);
|
||||
|
||||
// On login test land permisions
|
||||
if (vialogin)
|
||||
{
|
||||
if (land != null && !TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
|
||||
if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y))
|
||||
{
|
||||
m_authenticateHandler.RemoveCircuit(agent.circuitcode);
|
||||
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3733,9 +3785,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
try
|
||||
{
|
||||
if (!VerifyUserPresence(agent, out reason))
|
||||
if (!VerifyUserPresence(acd, out reason))
|
||||
{
|
||||
m_authenticateHandler.RemoveCircuit(agent.circuitcode);
|
||||
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3744,16 +3796,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_log.ErrorFormat(
|
||||
"[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
|
||||
|
||||
m_authenticateHandler.RemoveCircuit(agent.circuitcode);
|
||||
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!AuthorizeUser(agent, SeeIntoRegion, out reason))
|
||||
if (!AuthorizeUser(acd, SeeIntoRegion, out reason))
|
||||
{
|
||||
m_authenticateHandler.RemoveCircuit(agent.circuitcode);
|
||||
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3762,19 +3814,19 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_log.ErrorFormat(
|
||||
"[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
|
||||
|
||||
m_authenticateHandler.RemoveCircuit(agent.circuitcode);
|
||||
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
|
||||
RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
|
||||
agent.AgentID, agent.circuitcode);
|
||||
Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname,
|
||||
acd.AgentID, acd.circuitcode);
|
||||
|
||||
if (CapsModule != null)
|
||||
{
|
||||
CapsModule.SetAgentCapsSeeds(agent);
|
||||
CapsModule.CreateCaps(agent.AgentID);
|
||||
CapsModule.SetAgentCapsSeeds(acd);
|
||||
CapsModule.CreateCaps(acd.AgentID);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3787,14 +3839,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
|
||||
agent.AgentID, RegionInfo.RegionName);
|
||||
acd.AgentID, RegionInfo.RegionName);
|
||||
|
||||
sp.AdjustKnownSeeds();
|
||||
|
||||
if (CapsModule != null)
|
||||
{
|
||||
CapsModule.SetAgentCapsSeeds(agent);
|
||||
CapsModule.CreateCaps(agent.AgentID);
|
||||
CapsModule.SetAgentCapsSeeds(acd);
|
||||
CapsModule.CreateCaps(acd.AgentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3802,23 +3854,23 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// Try caching an incoming user name much earlier on to see if this helps with an issue
|
||||
// where HG users are occasionally seen by others as "Unknown User" because their UUIDName
|
||||
// request for the HG avatar appears to trigger before the user name is cached.
|
||||
CacheUserName(null, agent);
|
||||
CacheUserName(null, acd);
|
||||
}
|
||||
|
||||
if (vialogin)
|
||||
{
|
||||
// CleanDroppedAttachments();
|
||||
|
||||
if (TestBorderCross(agent.startpos, Cardinals.E))
|
||||
if (TestBorderCross(acd.startpos, Cardinals.E))
|
||||
{
|
||||
Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E);
|
||||
agent.startpos.X = crossedBorder.BorderLine.Z - 1;
|
||||
Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E);
|
||||
acd.startpos.X = crossedBorder.BorderLine.Z - 1;
|
||||
}
|
||||
|
||||
if (TestBorderCross(agent.startpos, Cardinals.N))
|
||||
if (TestBorderCross(acd.startpos, Cardinals.N))
|
||||
{
|
||||
Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.N);
|
||||
agent.startpos.Y = crossedBorder.BorderLine.Z - 1;
|
||||
Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N);
|
||||
acd.startpos.Y = crossedBorder.BorderLine.Z - 1;
|
||||
}
|
||||
|
||||
//Mitigate http://opensimulator.org/mantis/view.php?id=3522
|
||||
|
@ -3828,39 +3880,39 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
lock (EastBorders)
|
||||
{
|
||||
if (agent.startpos.X > EastBorders[0].BorderLine.Z)
|
||||
if (acd.startpos.X > EastBorders[0].BorderLine.Z)
|
||||
{
|
||||
m_log.Warn("FIX AGENT POSITION");
|
||||
agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
|
||||
if (agent.startpos.Z > 720)
|
||||
agent.startpos.Z = 720;
|
||||
acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
|
||||
if (acd.startpos.Z > 720)
|
||||
acd.startpos.Z = 720;
|
||||
}
|
||||
}
|
||||
lock (NorthBorders)
|
||||
{
|
||||
if (agent.startpos.Y > NorthBorders[0].BorderLine.Z)
|
||||
if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
|
||||
{
|
||||
m_log.Warn("FIX Agent POSITION");
|
||||
agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
|
||||
if (agent.startpos.Z > 720)
|
||||
agent.startpos.Z = 720;
|
||||
acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
|
||||
if (acd.startpos.Z > 720)
|
||||
acd.startpos.Z = 720;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (agent.startpos.X > EastBorders[0].BorderLine.Z)
|
||||
if (acd.startpos.X > EastBorders[0].BorderLine.Z)
|
||||
{
|
||||
m_log.Warn("FIX AGENT POSITION");
|
||||
agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
|
||||
if (agent.startpos.Z > 720)
|
||||
agent.startpos.Z = 720;
|
||||
acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
|
||||
if (acd.startpos.Z > 720)
|
||||
acd.startpos.Z = 720;
|
||||
}
|
||||
if (agent.startpos.Y > NorthBorders[0].BorderLine.Z)
|
||||
if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
|
||||
{
|
||||
m_log.Warn("FIX Agent POSITION");
|
||||
agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
|
||||
if (agent.startpos.Z > 720)
|
||||
agent.startpos.Z = 720;
|
||||
acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
|
||||
if (acd.startpos.Z > 720)
|
||||
acd.startpos.Z = 720;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3876,12 +3928,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
// We have multiple SpawnPoints, Route the agent to a random or sequential one
|
||||
if (SpawnPointRouting == "random")
|
||||
agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation(
|
||||
acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation(
|
||||
telehub.AbsolutePosition,
|
||||
telehub.GroupRotation
|
||||
);
|
||||
else
|
||||
agent.startpos = spawnpoints[SpawnPoint()].GetLocation(
|
||||
acd.startpos = spawnpoints[SpawnPoint()].GetLocation(
|
||||
telehub.AbsolutePosition,
|
||||
telehub.GroupRotation
|
||||
);
|
||||
|
@ -3889,7 +3941,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
else
|
||||
{
|
||||
// We have a single SpawnPoint and will route the agent to it
|
||||
agent.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
|
||||
acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3900,7 +3952,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
|
||||
{
|
||||
agent.startpos = land.LandData.UserLocation;
|
||||
acd.startpos = land.LandData.UserLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4360,11 +4412,51 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </param>
|
||||
public bool IncomingCloseAgent(UUID agentID, bool force)
|
||||
{
|
||||
//m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
|
||||
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
|
||||
if (presence != null)
|
||||
ScenePresence sp;
|
||||
|
||||
lock (m_removeClientLock)
|
||||
{
|
||||
presence.ControllingClient.Close(force);
|
||||
sp = GetScenePresence(agentID);
|
||||
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in {1}",
|
||||
agentID, Name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sp.LifecycleState != ScenePresenceState.Running)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Called RemoveClient() for {0} in {1} but presence is already in state {2}",
|
||||
sp.Name, Name, sp.LifecycleState);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
|
||||
// teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
|
||||
// want to obey this close since C may have renewed the child agent lease on B.
|
||||
if (sp.DoNotCloseAfterTeleport)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection",
|
||||
sp.IsChildAgent ? "child" : "root", sp.Name, Name);
|
||||
|
||||
// Need to reset the flag so that a subsequent close after another teleport can succeed.
|
||||
sp.DoNotCloseAfterTeleport = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sp.LifecycleState = ScenePresenceState.Removing;
|
||||
}
|
||||
|
||||
if (sp != null)
|
||||
{
|
||||
sp.ControllingClient.Close(force);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public class ScenePresence : EntityBase, IScenePresence
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// ~ScenePresence()
|
||||
// {
|
||||
// m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name);
|
||||
|
@ -85,10 +87,27 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_scene.EventManager.TriggerScenePresenceUpdated(this);
|
||||
}
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public PresenceType PresenceType { get; private set; }
|
||||
|
||||
private ScenePresenceStateMachine m_stateMachine;
|
||||
|
||||
/// <summary>
|
||||
/// The current state of this presence. Governs only the existence lifecycle. See ScenePresenceStateMachine
|
||||
/// for more details.
|
||||
/// </summary>
|
||||
public ScenePresenceState LifecycleState
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_stateMachine.GetState();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
m_stateMachine.SetState(value);
|
||||
}
|
||||
}
|
||||
|
||||
// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
|
||||
private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
|
||||
private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
|
||||
|
@ -811,6 +830,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
SetDirectionVectors();
|
||||
|
||||
Appearance = appearance;
|
||||
|
||||
m_stateMachine = new ScenePresenceStateMachine(this);
|
||||
}
|
||||
|
||||
public void RegisterToEvents()
|
||||
|
@ -879,7 +900,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public void MakeRootAgent(Vector3 pos, bool isFlying)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
m_log.InfoFormat(
|
||||
"[SCENE]: Upgrading child to root agent for {0} in {1}",
|
||||
Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
|
@ -887,6 +908,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
IsChildAgent = false;
|
||||
|
||||
// Must reset this here so that a teleport to a region next to an existing region does not keep the flag
|
||||
// set and prevent the close of the connection on a subsequent re-teleport.
|
||||
// Should not be needed if we are not trying to tell this region to close
|
||||
// DoNotCloseAfterTeleport = false;
|
||||
|
||||
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
|
||||
if (gm != null)
|
||||
Grouptitle = gm.GetGroupTitle(m_uuid);
|
||||
|
@ -3738,6 +3764,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// m_reprioritizationTimer.Dispose();
|
||||
|
||||
RemoveFromPhysicalScene();
|
||||
|
||||
LifecycleState = ScenePresenceState.Removed;
|
||||
}
|
||||
|
||||
public void AddAttachment(SceneObjectGroup gobj)
|
||||
|
|
Loading…
Reference in New Issue