diff options
Diffstat (limited to 'OpenSim/Region/Framework')
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using Nini.Config; | 30 | using Nini.Config; |
30 | using NUnit.Framework; | 31 | using NUnit.Framework; |
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.CoreModules.Framework; | ||
33 | using OpenSim.Region.CoreModules.Framework.EntityTransfer; | 35 | using OpenSim.Region.CoreModules.Framework.EntityTransfer; |
34 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 36 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
35 | using OpenSim.Region.CoreModules.World.Land; | 37 | using 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] |