Merge branch 'TeleportWork'
commit
97bcb59bee
|
@ -91,7 +91,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
public void RemoveForClient()
|
public void RemoveForClient()
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
// log4net.Config.XmlConfigurator.Configure();
|
// TestHelpers.EnableLogging();
|
||||||
|
|
||||||
UUID spId = TestHelpers.ParseTail(0x1);
|
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
|
// 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
|
// there is some unidentified connection problem, not where we have issues due to deadlock
|
||||||
if (!IsActive && !force)
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IsActive = false;
|
IsActive = false;
|
||||||
CloseWithoutChecks();
|
CloseWithoutChecks();
|
||||||
|
|
|
@ -1799,9 +1799,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
if (!client.SceneAgent.IsChildAgent)
|
if (!client.SceneAgent.IsChildAgent)
|
||||||
client.Kick("Simulator logged you out due to connection timeout.");
|
client.Kick("Simulator logged you out due to connection timeout.");
|
||||||
|
|
||||||
client.CloseWithoutChecks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_scene.IncomingCloseAgent(client.AgentId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IncomingPacketHandler()
|
private void IncomingPacketHandler()
|
||||||
|
@ -2142,7 +2142,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (!client.IsLoggingOut)
|
if (!client.IsLoggingOut)
|
||||||
{
|
{
|
||||||
client.IsLoggingOut = true;
|
client.IsLoggingOut = true;
|
||||||
client.Close();
|
m_scene.IncomingCloseAgent(client.AgentId, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
public void TestLogoutClientDueToAck()
|
public void TestLogoutClientDueToAck()
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
// TestHelpers.EnableLogging();
|
TestHelpers.EnableLogging();
|
||||||
|
|
||||||
IniConfigSource ics = new IniConfigSource();
|
IniConfigSource ics = new IniConfigSource();
|
||||||
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
|
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
|
// Now let's make it officially a child agent
|
||||||
sp.MakeChildAgent();
|
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))
|
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
|
||||||
{
|
{
|
||||||
sp.DoNotCloseAfterTeleport = false;
|
sp.DoNotCloseAfterTeleport = false;
|
||||||
|
@ -1081,14 +1091,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
if (!sp.DoNotCloseAfterTeleport)
|
if (!sp.DoNotCloseAfterTeleport)
|
||||||
{
|
{
|
||||||
// OK, it got this agent. Let's close everything
|
// 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);
|
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing agent {0} in {1}", sp.Name, Scene.Name);
|
||||||
sp.CloseChildAgents(newRegionX, newRegionY);
|
|
||||||
sp.Scene.IncomingCloseAgent(sp.UUID, false);
|
sp.Scene.IncomingCloseAgent(sp.UUID, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
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;
|
sp.DoNotCloseAfterTeleport = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1863,10 +1871,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles);
|
List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles);
|
||||||
List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
|
List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
|
||||||
|
|
||||||
//Dump("Current Neighbors", neighbourHandles);
|
// Dump("Current Neighbors", neighbourHandles);
|
||||||
//Dump("Previous Neighbours", previousRegionNeighbourHandles);
|
// Dump("Previous Neighbours", previousRegionNeighbourHandles);
|
||||||
//Dump("New Neighbours", newRegions);
|
// Dump("New Neighbours", newRegions);
|
||||||
//Dump("Old Neighbours", oldRegions);
|
// Dump("Old Neighbours", oldRegions);
|
||||||
|
|
||||||
/// Update the scene presence's known regions here on this region
|
/// Update the scene presence's known regions here on this region
|
||||||
sp.DropOldNeighbours(oldRegions);
|
sp.DropOldNeighbours(oldRegions);
|
||||||
|
@ -1874,8 +1882,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
/// Collect as many seeds as possible
|
/// Collect as many seeds as possible
|
||||||
Dictionary<ulong, string> seeds;
|
Dictionary<ulong, string> seeds;
|
||||||
if (sp.Scene.CapsModule != null)
|
if (sp.Scene.CapsModule != null)
|
||||||
seeds
|
seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
|
||||||
= new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
|
|
||||||
else
|
else
|
||||||
seeds = new Dictionary<ulong, string>();
|
seeds = new Dictionary<ulong, string>();
|
||||||
|
|
||||||
|
@ -1945,6 +1952,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
newAgent = true;
|
newAgent = true;
|
||||||
else
|
else
|
||||||
newAgent = false;
|
newAgent = false;
|
||||||
|
// continue;
|
||||||
|
|
||||||
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
|
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -562,7 +562,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||||
if (!Scene.TeleportClientHome(user, s.ControllingClient))
|
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.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))
|
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.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))
|
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.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;
|
public SynchronizeSceneHandler SynchronizeScene;
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
private object m_removeClientLock = new object();
|
private object m_removeClientLock = new object();
|
||||||
|
|
||||||
|
@ -1312,7 +1312,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
|
|
||||||
// Stop all client threads.
|
// 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");
|
m_log.Debug("[SCENE]: Persisting changed objects");
|
||||||
EventManager.TriggerSceneShuttingDown(this);
|
EventManager.TriggerSceneShuttingDown(this);
|
||||||
|
@ -2972,7 +2972,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
|
PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
|
||||||
|
|
||||||
sp.ControllingClient.Close();
|
IncomingCloseAgent(sp.UUID, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3384,35 +3384,36 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public override void RemoveClient(UUID agentID, bool closeChildAgents)
|
public override void RemoveClient(UUID agentID, bool closeChildAgents)
|
||||||
{
|
{
|
||||||
// CheckHeartbeat();
|
AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID);
|
||||||
bool isChildAgent = false;
|
|
||||||
AgentCircuitData acd;
|
|
||||||
|
|
||||||
lock (m_removeClientLock)
|
|
||||||
{
|
|
||||||
acd = m_authenticateHandler.GetAgentCircuitData(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 (acd == null)
|
if (acd == null)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
|
m_log.ErrorFormat(
|
||||||
|
"[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
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);
|
m_authenticateHandler.RemoveCircuit(agentID);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// TODO: Can we now remove this lock?
|
||||||
lock (acd)
|
lock (acd)
|
||||||
{
|
{
|
||||||
|
bool isChildAgent = false;
|
||||||
|
|
||||||
ScenePresence avatar = GetScenePresence(agentID);
|
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)
|
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);
|
"[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -3424,7 +3425,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[SCENE]: Removing {0} agent {1} {2} from {3}",
|
"[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
|
// Don't do this to root agents, it's not nice for the viewer
|
||||||
if (closeChildAgents && isChildAgent)
|
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
|
/// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
|
||||||
/// the LLUDP stack).
|
/// the LLUDP stack).
|
||||||
/// </remarks>
|
/// </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="reason">Outputs the reason for the false response on this string</param>
|
||||||
/// <param name="requirePresenceLookup">True for normal presence. False for NPC
|
/// <param name="requirePresenceLookup">True for normal presence. False for NPC
|
||||||
/// or other applications where a full grid/Hypergrid presence may not be required.</param>
|
/// 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
|
/// <returns>True if the region accepts this agent. False if it does not. False will
|
||||||
/// also return a reason.</returns>
|
/// 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 ||
|
bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
|
||||||
(teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
|
(teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
|
||||||
|
@ -3613,15 +3614,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.DebugFormat(
|
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})",
|
"[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})",
|
||||||
RegionInfo.RegionName,
|
RegionInfo.RegionName,
|
||||||
(agent.child ? "child" : "root"),
|
(acd.child ? "child" : "root"),
|
||||||
agent.firstname,
|
acd.firstname,
|
||||||
agent.lastname,
|
acd.lastname,
|
||||||
agent.AgentID,
|
acd.AgentID,
|
||||||
agent.circuitcode,
|
acd.circuitcode,
|
||||||
agent.IPAddress,
|
acd.IPAddress,
|
||||||
agent.Viewer,
|
acd.Viewer,
|
||||||
((TPFlags)teleportFlags).ToString(),
|
((TPFlags)teleportFlags).ToString(),
|
||||||
agent.startpos
|
acd.startpos
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!LoginsEnabled)
|
if (!LoginsEnabled)
|
||||||
|
@ -3639,7 +3640,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
foreach (string viewer in m_AllowedViewers)
|
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;
|
ViewerDenied = false;
|
||||||
break;
|
break;
|
||||||
|
@ -3656,7 +3657,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
foreach (string viewer in m_BannedViewers)
|
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;
|
ViewerDenied = true;
|
||||||
break;
|
break;
|
||||||
|
@ -3668,20 +3669,78 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[SCENE]: Access denied for {0} {1} using {2}",
|
"[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";
|
reason = "Access denied, your viewer is banned by the region owner";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ILandObject land;
|
ILandObject land;
|
||||||
|
ScenePresence sp;
|
||||||
|
|
||||||
lock (agent)
|
lock (m_removeClientLock)
|
||||||
{
|
{
|
||||||
ScenePresence sp = GetScenePresence(agent.AgentID);
|
sp = GetScenePresence(acd.AgentID);
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SCENE]: Reusing existing child scene presence for {0} in {1}", sp.Name, Name);
|
||||||
|
|
||||||
|
// 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))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.",
|
||||||
|
sp.Name, Name);
|
||||||
|
|
||||||
|
sp.DoNotCloseAfterTeleport = true;
|
||||||
|
}
|
||||||
|
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)
|
if (sp != null)
|
||||||
{
|
{
|
||||||
if (!sp.IsChildAgent)
|
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?
|
// We have a root agent. Is it in transit?
|
||||||
if (!EntityTransferModule.IsInTransit(sp.UUID))
|
if (!EntityTransferModule.IsInTransit(sp.UUID))
|
||||||
|
@ -3694,35 +3753,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
sp.Name, sp.UUID, RegionInfo.RegionName);
|
sp.Name, sp.UUID, RegionInfo.RegionName);
|
||||||
|
|
||||||
if (sp.ControllingClient != null)
|
if (sp.ControllingClient != null)
|
||||||
sp.ControllingClient.Close(true);
|
IncomingCloseAgent(sp.UUID, true);
|
||||||
|
|
||||||
sp = null;
|
sp = null;
|
||||||
}
|
}
|
||||||
//else
|
//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);
|
// 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
|
|
||||||
{
|
|
||||||
// We have a child agent here
|
|
||||||
sp.DoNotCloseAfterTeleport = true;
|
|
||||||
//m_log.WarnFormat("[SCENE]: Existing child scene presence for {0} {1} in {2}", sp.Name, sp.UUID, RegionInfo.RegionName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimistic: add or update the circuit data with the new agent circuit data and teleport flags.
|
// 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)
|
// We need the circuit data here for some of the subsequent checks. (groups, for example)
|
||||||
// If the checks fail, we remove the circuit.
|
// If the checks fail, we remove the circuit.
|
||||||
agent.teleportFlags = teleportFlags;
|
acd.teleportFlags = teleportFlags;
|
||||||
m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
|
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
|
// On login test land permisions
|
||||||
if (vialogin)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3733,9 +3785,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!VerifyUserPresence(agent, out reason))
|
if (!VerifyUserPresence(acd, out reason))
|
||||||
{
|
{
|
||||||
m_authenticateHandler.RemoveCircuit(agent.circuitcode);
|
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3744,16 +3796,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
|
"[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
|
||||||
|
|
||||||
m_authenticateHandler.RemoveCircuit(agent.circuitcode);
|
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3762,19 +3814,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
|
"[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
|
||||||
|
|
||||||
m_authenticateHandler.RemoveCircuit(agent.circuitcode);
|
m_authenticateHandler.RemoveCircuit(acd.circuitcode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
|
"[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,
|
Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname,
|
||||||
agent.AgentID, agent.circuitcode);
|
acd.AgentID, acd.circuitcode);
|
||||||
|
|
||||||
if (CapsModule != null)
|
if (CapsModule != null)
|
||||||
{
|
{
|
||||||
CapsModule.SetAgentCapsSeeds(agent);
|
CapsModule.SetAgentCapsSeeds(acd);
|
||||||
CapsModule.CreateCaps(agent.AgentID);
|
CapsModule.CreateCaps(acd.AgentID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3787,14 +3839,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
|
"[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
|
||||||
agent.AgentID, RegionInfo.RegionName);
|
acd.AgentID, RegionInfo.RegionName);
|
||||||
|
|
||||||
sp.AdjustKnownSeeds();
|
sp.AdjustKnownSeeds();
|
||||||
|
|
||||||
if (CapsModule != null)
|
if (CapsModule != null)
|
||||||
{
|
{
|
||||||
CapsModule.SetAgentCapsSeeds(agent);
|
CapsModule.SetAgentCapsSeeds(acd);
|
||||||
CapsModule.CreateCaps(agent.AgentID);
|
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
|
// 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
|
// 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.
|
// request for the HG avatar appears to trigger before the user name is cached.
|
||||||
CacheUserName(null, agent);
|
CacheUserName(null, acd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vialogin)
|
if (vialogin)
|
||||||
{
|
{
|
||||||
// CleanDroppedAttachments();
|
// CleanDroppedAttachments();
|
||||||
|
|
||||||
if (TestBorderCross(agent.startpos, Cardinals.E))
|
if (TestBorderCross(acd.startpos, Cardinals.E))
|
||||||
{
|
{
|
||||||
Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E);
|
Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E);
|
||||||
agent.startpos.X = crossedBorder.BorderLine.Z - 1;
|
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);
|
Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N);
|
||||||
agent.startpos.Y = crossedBorder.BorderLine.Z - 1;
|
acd.startpos.Y = crossedBorder.BorderLine.Z - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Mitigate http://opensimulator.org/mantis/view.php?id=3522
|
//Mitigate http://opensimulator.org/mantis/view.php?id=3522
|
||||||
|
@ -3828,39 +3880,39 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
lock (EastBorders)
|
lock (EastBorders)
|
||||||
{
|
{
|
||||||
if (agent.startpos.X > EastBorders[0].BorderLine.Z)
|
if (acd.startpos.X > EastBorders[0].BorderLine.Z)
|
||||||
{
|
{
|
||||||
m_log.Warn("FIX AGENT POSITION");
|
m_log.Warn("FIX AGENT POSITION");
|
||||||
agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
|
acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
|
||||||
if (agent.startpos.Z > 720)
|
if (acd.startpos.Z > 720)
|
||||||
agent.startpos.Z = 720;
|
acd.startpos.Z = 720;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lock (NorthBorders)
|
lock (NorthBorders)
|
||||||
{
|
{
|
||||||
if (agent.startpos.Y > NorthBorders[0].BorderLine.Z)
|
if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
|
||||||
{
|
{
|
||||||
m_log.Warn("FIX Agent POSITION");
|
m_log.Warn("FIX Agent POSITION");
|
||||||
agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
|
acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
|
||||||
if (agent.startpos.Z > 720)
|
if (acd.startpos.Z > 720)
|
||||||
agent.startpos.Z = 720;
|
acd.startpos.Z = 720;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
if (agent.startpos.X > EastBorders[0].BorderLine.Z)
|
if (acd.startpos.X > EastBorders[0].BorderLine.Z)
|
||||||
{
|
{
|
||||||
m_log.Warn("FIX AGENT POSITION");
|
m_log.Warn("FIX AGENT POSITION");
|
||||||
agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
|
acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
|
||||||
if (agent.startpos.Z > 720)
|
if (acd.startpos.Z > 720)
|
||||||
agent.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");
|
m_log.Warn("FIX Agent POSITION");
|
||||||
agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
|
acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
|
||||||
if (agent.startpos.Z > 720)
|
if (acd.startpos.Z > 720)
|
||||||
agent.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
|
// We have multiple SpawnPoints, Route the agent to a random or sequential one
|
||||||
if (SpawnPointRouting == "random")
|
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.AbsolutePosition,
|
||||||
telehub.GroupRotation
|
telehub.GroupRotation
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
agent.startpos = spawnpoints[SpawnPoint()].GetLocation(
|
acd.startpos = spawnpoints[SpawnPoint()].GetLocation(
|
||||||
telehub.AbsolutePosition,
|
telehub.AbsolutePosition,
|
||||||
telehub.GroupRotation
|
telehub.GroupRotation
|
||||||
);
|
);
|
||||||
|
@ -3889,7 +3941,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We have a single SpawnPoint and will route the agent to it
|
// 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;
|
return true;
|
||||||
|
@ -3900,7 +3952,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
|
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>
|
/// </param>
|
||||||
public bool IncomingCloseAgent(UUID agentID, bool force)
|
public bool IncomingCloseAgent(UUID agentID, bool force)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
|
ScenePresence sp;
|
||||||
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
|
|
||||||
if (presence != null)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public class ScenePresence : EntityBase, IScenePresence
|
public class ScenePresence : EntityBase, IScenePresence
|
||||||
{
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
// ~ScenePresence()
|
// ~ScenePresence()
|
||||||
// {
|
// {
|
||||||
// m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name);
|
// m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name);
|
||||||
|
@ -85,10 +87,27 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_scene.EventManager.TriggerScenePresenceUpdated(this);
|
m_scene.EventManager.TriggerScenePresenceUpdated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
public PresenceType PresenceType { get; private set; }
|
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 byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
|
||||||
private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
|
private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
|
||||||
private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
|
private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
|
||||||
|
@ -811,6 +830,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SetDirectionVectors();
|
SetDirectionVectors();
|
||||||
|
|
||||||
Appearance = appearance;
|
Appearance = appearance;
|
||||||
|
|
||||||
|
m_stateMachine = new ScenePresenceStateMachine(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterToEvents()
|
public void RegisterToEvents()
|
||||||
|
@ -879,7 +900,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void MakeRootAgent(Vector3 pos, bool isFlying)
|
public void MakeRootAgent(Vector3 pos, bool isFlying)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.InfoFormat(
|
||||||
"[SCENE]: Upgrading child to root agent for {0} in {1}",
|
"[SCENE]: Upgrading child to root agent for {0} in {1}",
|
||||||
Name, m_scene.RegionInfo.RegionName);
|
Name, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
@ -887,6 +908,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
IsChildAgent = false;
|
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>();
|
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
|
||||||
if (gm != null)
|
if (gm != null)
|
||||||
Grouptitle = gm.GetGroupTitle(m_uuid);
|
Grouptitle = gm.GetGroupTitle(m_uuid);
|
||||||
|
@ -3738,6 +3764,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// m_reprioritizationTimer.Dispose();
|
// m_reprioritizationTimer.Dispose();
|
||||||
|
|
||||||
RemoveFromPhysicalScene();
|
RemoveFromPhysicalScene();
|
||||||
|
|
||||||
|
LifecycleState = ScenePresenceState.Removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddAttachment(SceneObjectGroup gobj)
|
public void AddAttachment(SceneObjectGroup gobj)
|
||||||
|
|
Loading…
Reference in New Issue