aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs31
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs107
4 files changed, 138 insertions, 8 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index b70e9df..4dc724d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -552,12 +552,29 @@ namespace OpenSim.Region.Framework.Scenes
552 552
553 av.IsInTransit = true; 553 av.IsInTransit = true;
554 554
555 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; 555 // A temporary measure to allow regression tests to work.
556 d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); 556 // Quite possibly, all BeginInvoke() calls should be replaced by Util.FireAndForget
557 // or similar since BeginInvoke() always uses the system threadpool to launch
558 // threads rather than any replace threadpool that we might be using.
559 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
560 {
561 entityTransfer.CrossAgentToNewRegionAsync(av, val, destination, av.Flying, version);
562 CrossAgentToNewRegionCompleted(av);
563 }
564 else
565 {
566 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
567 d.BeginInvoke(
568 av, val, destination, av.Flying, version,
569 ar => CrossAgentToNewRegionCompleted(d.EndInvoke(ar)), null);
570 }
557 } 571 }
558 else 572 else
573 {
559 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); 574 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val);
575 }
560 } 576 }
577
561 avsToCross.Clear(); 578 avsToCross.Clear();
562 return; 579 return;
563 } 580 }
@@ -630,11 +647,8 @@ namespace OpenSim.Region.Framework.Scenes
630 set { RootPart.Velocity = value; } 647 set { RootPart.Velocity = value; }
631 } 648 }
632 649
633 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 650 private void CrossAgentToNewRegionCompleted(ScenePresence agent)
634 { 651 {
635 CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
636 ScenePresence agent = icon.EndInvoke(iar);
637
638 //// If the cross was successful, this agent is a child agent 652 //// If the cross was successful, this agent is a child agent
639 if (agent.IsChildAgent) 653 if (agent.IsChildAgent)
640 { 654 {
@@ -1698,10 +1712,15 @@ namespace OpenSim.Region.Framework.Scenes
1698 /// <returns></returns> 1712 /// <returns></returns>
1699 public SceneObjectGroup Copy(bool userExposed) 1713 public SceneObjectGroup Copy(bool userExposed)
1700 { 1714 {
1715 // FIXME: This is dangerous since it's easy to forget to reset some references when necessary and end up
1716 // with bugs that only occur in some circumstances (e.g. crossing between regions on the same simulator
1717 // but not between regions on different simulators). Really, all copying should be done explicitly.
1701 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); 1718 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
1719
1702 dupe.Backup = false; 1720 dupe.Backup = false;
1703 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>(); 1721 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
1704 dupe.m_sittingAvatars = new List<UUID>(); 1722 dupe.m_sittingAvatars = new List<UUID>();
1723 dupe.m_linkedAvatars = new List<ScenePresence>();
1705 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); 1724 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
1706 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; 1725 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum;
1707 1726
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index db4e285..c06175e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1753,7 +1753,11 @@ namespace OpenSim.Region.Framework.Scenes
1753 /// <returns></returns> 1753 /// <returns></returns>
1754 public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed) 1754 public SceneObjectPart Copy(uint localID, UUID AgentID, UUID GroupID, int linkNum, bool userExposed)
1755 { 1755 {
1756 // FIXME: This is dangerous since it's easy to forget to reset some references when necessary and end up
1757 // with bugs that only occur in some circumstances (e.g. crossing between regions on the same simulator
1758 // but not between regions on different simulators). Really, all copying should be done explicitly.
1756 SceneObjectPart dupe = (SceneObjectPart)MemberwiseClone(); 1759 SceneObjectPart dupe = (SceneObjectPart)MemberwiseClone();
1760
1757 dupe.m_shape = m_shape.Copy(); 1761 dupe.m_shape = m_shape.Copy();
1758 dupe.m_regionHandle = m_regionHandle; 1762 dupe.m_regionHandle = m_regionHandle;
1759 if (userExposed) 1763 if (userExposed)
@@ -1799,6 +1803,8 @@ namespace OpenSim.Region.Framework.Scenes
1799 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 1803 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
1800 dupe.Shape.ExtraParams = extraP; 1804 dupe.Shape.ExtraParams = extraP;
1801 1805
1806 dupe.m_sittingAvatars = new HashSet<OpenMetaverse.UUID>();
1807
1802 // safeguard actual copy is done in sog.copy 1808 // safeguard actual copy is done in sog.copy
1803 dupe.KeyframeMotion = null; 1809 dupe.KeyframeMotion = null;
1804 dupe.PayPrice = (int[])PayPrice.Clone(); 1810 dupe.PayPrice = (int[])PayPrice.Clone();
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 080cdb4..6386a45 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1023,6 +1023,7 @@ namespace OpenSim.Region.Framework.Scenes
1023 else 1023 else
1024 { 1024 {
1025 part.ParentGroup.AddAvatar(UUID); 1025 part.ParentGroup.AddAvatar(UUID);
1026 part.AddSittingAvatar(UUID);
1026 if (part.SitTargetPosition != Vector3.Zero) 1027 if (part.SitTargetPosition != Vector3.Zero)
1027 part.SitTargetAvatar = UUID; 1028 part.SitTargetAvatar = UUID;
1028 // ParentPosition = part.GetWorldPosition(); 1029 // ParentPosition = part.GetWorldPosition();
@@ -2848,7 +2849,6 @@ namespace OpenSim.Region.Framework.Scenes
2848 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2849 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2849 } 2850 }
2850 2851
2851
2852 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2852 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2853 { 2853 {
2854 if (IsChildAgent) 2854 if (IsChildAgent)
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
index 4d07741..d65b0b6 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
@@ -26,10 +26,12 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using Nini.Config; 30using Nini.Config;
30using NUnit.Framework; 31using NUnit.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
32using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.CoreModules.Framework;
33using OpenSim.Region.CoreModules.Framework.EntityTransfer; 35using OpenSim.Region.CoreModules.Framework.EntityTransfer;
34using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 36using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
35using OpenSim.Region.CoreModules.World.Land; 37using OpenSim.Region.CoreModules.World.Land;
@@ -101,7 +103,110 @@ namespace OpenSim.Region.Framework.Scenes.Tests
101 /// Test cross with no prim limit module. 103 /// Test cross with no prim limit module.
102 /// </summary> 104 /// </summary>
103 /// <remarks> 105 /// <remarks>
104 /// XXX: This test may be better off in a specific PrimLimitsModuleTest class in optional module tests in the 106 /// Possibly this should belong in ScenePresenceCrossingTests, though here it is the object that is being moved
107 /// where the avatar is just a passenger.
108 /// </remarks>
109 [Test]
110 public void TestCrossOnSameSimulatorWithSittingAvatar()
111 {
112 TestHelpers.InMethod();
113// TestHelpers.EnableLogging();
114
115 UUID userId = TestHelpers.ParseTail(0x1);
116 int sceneObjectIdTail = 0x2;
117 Vector3 so1StartPos = new Vector3(128, 10, 20);
118
119 EntityTransferModule etmA = new EntityTransferModule();
120 EntityTransferModule etmB = new EntityTransferModule();
121 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
122
123 IConfigSource config = new IniConfigSource();
124 IConfig modulesConfig = config.AddConfig("Modules");
125 modulesConfig.Set("EntityTransferModule", etmA.Name);
126 modulesConfig.Set("SimulationServices", lscm.Name);
127 IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
128
129 // In order to run a single threaded regression test we do not want the entity transfer module waiting
130 // for a callback from the destination scene before removing its avatar data.
131 entityTransferConfig.Set("wait_for_callback", false);
132
133 SceneHelpers sh = new SceneHelpers();
134 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
135 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999);
136
137 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
138 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
139 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
140
141 SceneObjectGroup so1 = SceneHelpers.AddSceneObject(sceneA, 1, userId, "", sceneObjectIdTail);
142 UUID so1Id = so1.UUID;
143 so1.AbsolutePosition = so1StartPos;
144
145 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
146 TestClient tc = new TestClient(acd, sceneA);
147 List<TestClient> destinationTestClients = new List<TestClient>();
148 EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
149
150 ScenePresence sp1SceneA = SceneHelpers.AddScenePresence(sceneA, tc, acd);
151 sp1SceneA.AbsolutePosition = so1StartPos;
152 sp1SceneA.HandleAgentRequestSit(sp1SceneA.ControllingClient, sp1SceneA.UUID, so1.UUID, Vector3.Zero);
153
154 // Cross
155 sceneA.SceneGraph.UpdatePrimGroupPosition(
156 so1.LocalId, new Vector3(so1StartPos.X, so1StartPos.Y - 20, so1StartPos.Z), userId);
157
158 SceneObjectGroup so1PostCross;
159
160 {
161 ScenePresence sp1SceneAPostCross = sceneA.GetScenePresence(userId);
162 Assert.IsTrue(sp1SceneAPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly false");
163
164 ScenePresence sp1SceneBPostCross = sceneB.GetScenePresence(userId);
165 TestClient sceneBTc = ((TestClient)sp1SceneBPostCross.ControllingClient);
166 sceneBTc.CompleteMovement();
167
168 Assert.IsFalse(sp1SceneBPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true");
169 Assert.IsTrue(sp1SceneBPostCross.IsSatOnObject);
170
171 Assert.IsNull(sceneA.GetSceneObjectGroup(so1Id), "uck");
172 so1PostCross = sceneB.GetSceneObjectGroup(so1Id);
173 Assert.NotNull(so1PostCross);
174 Assert.AreEqual(1, so1PostCross.GetSittingAvatarsCount());
175 Assert.AreEqual(1, so1PostCross.GetLinkedAvatars().Count);
176 }
177
178 Vector3 so1PostCrossPos = so1PostCross.AbsolutePosition;
179
180// Console.WriteLine("CRISSCROSS");
181
182 // Recross
183 sceneB.SceneGraph.UpdatePrimGroupPosition(
184 so1PostCross.LocalId, new Vector3(so1PostCrossPos.X, so1PostCrossPos.Y + 20, so1PostCrossPos.Z), userId);
185
186 {
187 ScenePresence sp1SceneBPostReCross = sceneB.GetScenePresence(userId);
188 Assert.IsTrue(sp1SceneBPostReCross.IsChildAgent, "sp1SceneBPostReCross.IsChildAgent unexpectedly false");
189
190 ScenePresence sp1SceneAPostReCross = sceneA.GetScenePresence(userId);
191 TestClient sceneATc = ((TestClient)sp1SceneAPostReCross.ControllingClient);
192 sceneATc.CompleteMovement();
193
194 Assert.IsFalse(sp1SceneAPostReCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true");
195 Assert.IsTrue(sp1SceneAPostReCross.IsSatOnObject);
196
197 Assert.IsNull(sceneB.GetSceneObjectGroup(so1Id), "uck2");
198 SceneObjectGroup so1PostReCross = sceneA.GetSceneObjectGroup(so1Id);
199 Assert.NotNull(so1PostReCross);
200 Assert.AreEqual(1, so1PostReCross.GetSittingAvatarsCount());
201 Assert.AreEqual(1, so1PostReCross.GetLinkedAvatars().Count);
202 }
203 }
204
205 /// <summary>
206 /// Test cross with no prim limit module.
207 /// </summary>
208 /// <remarks>
209 /// XXX: This test may FCbe better off in a specific PrimLimitsModuleTest class in optional module tests in the
105 /// future (though it is configured as active by default, so not really optional). 210 /// future (though it is configured as active by default, so not really optional).
106 /// </remarks> 211 /// </remarks>
107 [Test] 212 [Test]