From 3891a8946bb72c9256d8de4185bf4a72c90be859 Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Mon, 22 Jul 2013 11:54:35 -0700
Subject: New Teleport protocol (V2), still compatible with V1 and older.
(version of the destination is being checked) In this new protocol, and as
committed before, the viewer is not sent
EnableSimulator/EstablishChildCommunication for the destination. Instead, it
is sent TeleportFinish directly. TeleportFinish, in turn, makes the viewer
send a UserCircuitCode packet followed by CompleteMovementIntoRegion packet.
These 2 packets tend to occur one after the other almost immediately to the
point that when CMIR arrives the client is not even connected yet and that
packet is ignored (there might have been some race conditions here before);
then the viewer sends CMIR again within 5-8 secs. But the delay between them
may be higher in busier regions, which may lead to race conditions. This
commit improves the process so there are are no race conditions at the
destination. CompleteMovement (triggered by the viewer) waits until Update
has been sent from the origin. Update, in turn, waits until there is a *root*
scene presence -- so making sure CompleteMovement has run MakeRoot. In other
words, there are two threadlets at the destination, one from the viewer and
one from the origin region, waiting for each other to do the right thing.
That makes it safe to close the agent at the origin upon return of the Update
call without having to wait for callback, because we are absolutely sure that
the viewer knows it is in th new region. Note also that in the V1 protocol,
the destination was getting UseCircuitCode from the viewer twice -- once on
EstablishAgentCommunication and then again on TeleportFinish. The second UCC
was being ignored, but it shows how we were not following the expected
steps...
---
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 33 ++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 6433878..891e04e 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -29,7 +29,9 @@ using System;
using System.Xml;
using System.Collections.Generic;
using System.Reflection;
+using System.Threading;
using System.Timers;
+using Timer = System.Timers.Timer;
using OpenMetaverse;
using log4net;
using Nini.Config;
@@ -1311,6 +1313,26 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
}
+ private bool WaitForUpdateAgent(IClientAPI client)
+ {
+ // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero
+ int count = 20;
+ while (m_originRegionID.Equals(UUID.Zero) && count-- > 0)
+ {
+ m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.RegionInfo.RegionName);
+ Thread.Sleep(200);
+ }
+
+ if (m_originRegionID.Equals(UUID.Zero))
+ {
+ // Movement into region will fail
+ m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived", client.Name);
+ return false;
+ }
+
+ return true;
+ }
+
///
/// Complete Avatar's movement into the region.
///
@@ -1328,6 +1350,12 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
+ if (m_teleportFlags != TeleportFlags.ViaLogin)
+ // Let's wait until UpdateAgent (called by departing region) is done
+ if (!WaitForUpdateAgent(client))
+ // The sending region never sent the UpdateAgent data, we have to refuse
+ return;
+
Vector3 look = Velocity;
if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
@@ -1348,10 +1376,11 @@ namespace OpenSim.Region.Framework.Scenes
bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
MakeRootAgent(AbsolutePosition, flying);
+
+ // Tell the client that we're totally ready
ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
+
// Remember in HandleUseCircuitCode, we delayed this to here
- // This will also send the initial data to clients when TP to a neighboring region.
- // Not ideal, but until we know we're TP-ing from a neighboring region, there's not much we can do
if (m_teleportFlags > 0)
SendInitialDataToMe();
--
cgit v1.1
From 261512606d77747701934e80e150bd55454571f2 Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Mon, 22 Jul 2013 14:23:50 -0700
Subject: Improve the opening test in CompleteMovement, to account for multiple
flags besides ViaLogin.
---
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 891e04e..edd49eb 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1350,7 +1350,7 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
- if (m_teleportFlags != TeleportFlags.ViaLogin)
+ if ((m_teleportFlags & TeleportFlags.ViaLogin) != 0)
// Let's wait until UpdateAgent (called by departing region) is done
if (!WaitForUpdateAgent(client))
// The sending region never sent the UpdateAgent data, we have to refuse
--
cgit v1.1
From 879cbb45753bf3f3144512748acd8faf120fc626 Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Mon, 22 Jul 2013 14:35:14 -0700
Subject: This commit message intentionally left blank (last commit was
idiotic)
---
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index edd49eb..7f24174 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1350,7 +1350,8 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
- if ((m_teleportFlags & TeleportFlags.ViaLogin) != 0)
+ // Make sure it's not a login agent. We don't want to wait for updates during login
+ if ((m_teleportFlags & TeleportFlags.ViaLogin) == 0)
// Let's wait until UpdateAgent (called by departing region) is done
if (!WaitForUpdateAgent(client))
// The sending region never sent the UpdateAgent data, we have to refuse
--
cgit v1.1
From 4e5c7bdeb3222edeff8fbf8c01ce0b5916473e46 Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Mon, 22 Jul 2013 22:00:20 -0700
Subject: Moved TriggerOnMakeRootAgent back to the end of MakeRootAgent, to see
if that eliminates the temporary placement at infinity upon TPs
---
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 7f24174..f9190d9 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1013,9 +1013,8 @@ namespace OpenSim.Region.Framework.Scenes
// recorded, which stops the input from being processed.
MovementFlag = 0;
- // DIVA NOTE: I moved TriggerOnMakeRootAgent out of here and into the end of
- // CompleteMovement. We don't want modules doing heavy computation before CompleteMovement
- // is over.
+ m_scene.EventManager.TriggerOnMakeRootAgent(this);
+
}
public int GetStateSource()
@@ -1437,10 +1436,6 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
- // DIVA NOTE: moved this here from MakeRoot. We don't want modules making heavy
- // computations before CompleteMovement is over
- m_scene.EventManager.TriggerOnMakeRootAgent(this);
-
}
///
--
cgit v1.1