aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs93
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs63
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs88
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs15
11 files changed, 251 insertions, 88 deletions
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 6e8eb91..7f06e82 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -148,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes
148 /// Triggered when a new presence is added to the scene 148 /// Triggered when a new presence is added to the scene
149 /// </summary> 149 /// </summary>
150 /// <remarks> 150 /// <remarks>
151 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both 151 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewAgent"/> which is used by both
152 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see> 152 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
153 /// </remarks> 153 /// </remarks>
154 public event OnNewPresenceDelegate OnNewPresence; 154 public event OnNewPresenceDelegate OnNewPresence;
@@ -159,7 +159,7 @@ namespace OpenSim.Region.Framework.Scenes
159 /// Triggered when a presence is removed from the scene 159 /// Triggered when a presence is removed from the scene
160 /// </summary> 160 /// </summary>
161 /// <remarks> 161 /// <remarks>
162 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both 162 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewAgent"/> which is used by both
163 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see> 163 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
164 /// 164 ///
165 /// Triggered under per-agent lock. So if you want to perform any long-running operations, please 165 /// Triggered under per-agent lock. So if you want to perform any long-running operations, please
@@ -1107,7 +1107,7 @@ namespace OpenSim.Region.Framework.Scenes
1107 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessMoneyTransferRequest"/> 1107 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessMoneyTransferRequest"/>
1108 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientGridEvents"/> 1108 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientGridEvents"/>
1109 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientEvents"/> 1109 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientEvents"/>
1110 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> 1110 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewAgent"/>
1111 /// </remarks> 1111 /// </remarks>
1112 public event MoneyTransferEvent OnMoneyTransfer; 1112 public event MoneyTransferEvent OnMoneyTransfer;
1113 1113
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 4337b5a..659bde9 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -507,6 +507,9 @@ namespace OpenSim.Region.Framework.Scenes
507 // This MAY be problematic, if it is, another solution 507 // This MAY be problematic, if it is, another solution
508 // needs to be found. If inventory item flags are updated 508 // needs to be found. If inventory item flags are updated
509 // the viewer's notion of the item needs to be refreshed. 509 // the viewer's notion of the item needs to be refreshed.
510 //
511 // In other situations we cannot send out a bulk update here, since this will cause editing of clothing to start
512 // failing frequently. Possibly this is a race with a separate transaction that uploads the asset.
510 if (sendUpdate) 513 if (sendUpdate)
511 remoteClient.SendBulkUpdateInventory(item); 514 remoteClient.SendBulkUpdateInventory(item);
512 } 515 }
@@ -2393,6 +2396,13 @@ namespace OpenSim.Region.Framework.Scenes
2393 sourcePart.Inventory.RemoveInventoryItem(item.ItemID); 2396 sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
2394 } 2397 }
2395 2398
2399
2400 if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
2401 {
2402 group.RootPart.AttachedPos = group.AbsolutePosition;
2403 group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
2404 }
2405
2396 group.FromPartID = sourcePart.UUID; 2406 group.FromPartID = sourcePart.UUID;
2397 AddNewSceneObject(group, true, pos, rot, vel); 2407 AddNewSceneObject(group, true, pos, rot, vel);
2398 2408
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index d6d2df4..21036d8 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -751,6 +751,7 @@ namespace OpenSim.Region.Framework.Scenes
751 m_config = config; 751 m_config = config;
752 MinFrameTime = 0.089f; 752 MinFrameTime = 0.089f;
753 MinMaintenanceTime = 1; 753 MinMaintenanceTime = 1;
754 SeeIntoRegion = true;
754 755
755 Random random = new Random(); 756 Random random = new Random();
756 757
@@ -863,6 +864,7 @@ namespace OpenSim.Region.Framework.Scenes
863 //Animation states 864 //Animation states
864 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 865 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
865 866
867 SeeIntoRegion = startupConfig.GetBoolean("see_into_region", SeeIntoRegion);
866 868
867 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20); 869 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
868 870
@@ -1338,7 +1340,7 @@ namespace OpenSim.Region.Framework.Scenes
1338 Thread.Sleep(500); 1340 Thread.Sleep(500);
1339 1341
1340 // Stop all client threads. 1342 // Stop all client threads.
1341 ForEachScenePresence(delegate(ScenePresence avatar) { IncomingCloseAgent(avatar.UUID, false); }); 1343 ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); });
1342 1344
1343 m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); 1345 m_log.Debug("[SCENE]: TriggerSceneShuttingDown");
1344 EventManager.TriggerSceneShuttingDown(this); 1346 EventManager.TriggerSceneShuttingDown(this);
@@ -2953,7 +2955,7 @@ namespace OpenSim.Region.Framework.Scenes
2953 2955
2954 #region Add/Remove Avatar Methods 2956 #region Add/Remove Avatar Methods
2955 2957
2956 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2958 public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
2957 { 2959 {
2958 ScenePresence sp; 2960 ScenePresence sp;
2959 bool vialogin; 2961 bool vialogin;
@@ -2961,7 +2963,7 @@ namespace OpenSim.Region.Framework.Scenes
2961 2963
2962 // Validation occurs in LLUDPServer 2964 // Validation occurs in LLUDPServer
2963 // 2965 //
2964 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with 2966 // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with
2965 // each other. In practice, this does not currently occur in the code. 2967 // each other. In practice, this does not currently occur in the code.
2966 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2968 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2967 2969
@@ -2969,9 +2971,9 @@ namespace OpenSim.Region.Framework.Scenes
2969 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point 2971 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2970 // whilst connecting). 2972 // whilst connecting).
2971 // 2973 //
2972 // It would be easier to lock across all NewUserConnection(), AddNewClient() and 2974 // It would be easier to lock across all NewUserConnection(), AddNewAgent() and
2973 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service 2975 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2974 // response in some module listening to AddNewClient()) from holding up unrelated agent calls. 2976 // response in some module listening to AddNewAgent()) from holding up unrelated agent calls.
2975 // 2977 //
2976 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all 2978 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2977 // AddNewClient() operations (though not other ops). 2979 // AddNewClient() operations (though not other ops).
@@ -2988,7 +2990,7 @@ namespace OpenSim.Region.Framework.Scenes
2988 2990
2989 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2991 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2990 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2992 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2991 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2993 // other problems, and possibly the code calling AddNewAgent() should ensure that no client is already
2992 // connected. 2994 // connected.
2993 if (sp == null) 2995 if (sp == null)
2994 { 2996 {
@@ -3021,6 +3023,9 @@ namespace OpenSim.Region.Framework.Scenes
3021 3023
3022 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 3024 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
3023 // client is for a root or child agent. 3025 // client is for a root or child agent.
3026 // XXX: This may be better set for a new client before that client is added to the client manager.
3027 // But need to know what happens in the case where a ScenePresence is already present (and if this
3028 // actually occurs).
3024 client.SceneAgent = sp; 3029 client.SceneAgent = sp;
3025 3030
3026 // This is currently also being done earlier in NewUserConnection for real users to see if this 3031 // This is currently also being done earlier in NewUserConnection for real users to see if this
@@ -3130,7 +3135,7 @@ namespace OpenSim.Region.Framework.Scenes
3130 { 3135 {
3131 PresenceService.LogoutAgent(sp.ControllingClient.SessionId); 3136 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
3132 3137
3133 IncomingCloseAgent(sp.UUID, false); 3138 CloseAgent(sp.UUID, false);
3134 } 3139 }
3135 3140
3136 // BANG! SLASH! 3141 // BANG! SLASH!
@@ -3554,7 +3559,7 @@ namespace OpenSim.Region.Framework.Scenes
3554 /// <param name='closeChildAgents'> 3559 /// <param name='closeChildAgents'>
3555 /// Close the neighbour child agents associated with this client. 3560 /// Close the neighbour child agents associated with this client.
3556 /// </param> 3561 /// </param>
3557 public override void RemoveClient(UUID agentID, bool closeChildAgents) 3562 public void RemoveClient(UUID agentID, bool closeChildAgents)
3558 { 3563 {
3559 AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); 3564 AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3560 3565
@@ -3940,7 +3945,7 @@ namespace OpenSim.Region.Framework.Scenes
3940 sp.Name, sp.UUID, RegionInfo.RegionName); 3945 sp.Name, sp.UUID, RegionInfo.RegionName);
3941 3946
3942 if (sp.ControllingClient != null) 3947 if (sp.ControllingClient != null)
3943 IncomingCloseAgent(sp.UUID, true); 3948 CloseAgent(sp.UUID, true);
3944 3949
3945 sp = null; 3950 sp = null;
3946 } 3951 }
@@ -4024,19 +4029,6 @@ namespace OpenSim.Region.Framework.Scenes
4024 // Let the SP know how we got here. This has a lot of interesting 4029 // Let the SP know how we got here. This has a lot of interesting
4025 // uses down the line. 4030 // uses down the line.
4026 sp.TeleportFlags = (TPFlags)teleportFlags; 4031 sp.TeleportFlags = (TPFlags)teleportFlags;
4027
4028 // We must carry out a further authorization check if there's an
4029 // attempt to make a child agent into a root agent, since SeeIntoRegion may have allowed a child
4030 // agent to login to a region where a full avatar would not be allowed.
4031 //
4032 // We determine whether this is a CreateAgent for a future non-child agent by inspecting
4033 // TeleportFlags, which will be default for a child connection. This relies on input from the source
4034 // region.
4035 if (sp.TeleportFlags != TPFlags.Default)
4036 {
4037 if (!AuthorizeUser(acd, false, out reason))
4038 return false;
4039 }
4040 4032
4041 if (sp.IsChildAgent) 4033 if (sp.IsChildAgent)
4042 { 4034 {
@@ -4469,7 +4461,7 @@ namespace OpenSim.Region.Framework.Scenes
4469 /// <param name="cAgentData">Agent that contains all of the relevant things about an agent. 4461 /// <param name="cAgentData">Agent that contains all of the relevant things about an agent.
4470 /// Appearance, animations, position, etc.</param> 4462 /// Appearance, animations, position, etc.</param>
4471 /// <returns>true if we handled it.</returns> 4463 /// <returns>true if we handled it.</returns>
4472 public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData) 4464 public virtual bool IncomingUpdateChildAgent(AgentData cAgentData)
4473 { 4465 {
4474 m_log.DebugFormat( 4466 m_log.DebugFormat(
4475 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 4467 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
@@ -4487,7 +4479,7 @@ namespace OpenSim.Region.Framework.Scenes
4487 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 4479 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
4488 if (nearestParcel == null) 4480 if (nearestParcel == null)
4489 { 4481 {
4490 m_log.DebugFormat( 4482 m_log.InfoFormat(
4491 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", 4483 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel",
4492 cAgentData.AgentID, RegionInfo.RegionName); 4484 cAgentData.AgentID, RegionInfo.RegionName);
4493 4485
@@ -4497,7 +4489,7 @@ namespace OpenSim.Region.Framework.Scenes
4497 // We have to wait until the viewer contacts this region 4489 // We have to wait until the viewer contacts this region
4498 // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol) 4490 // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol)
4499 // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send 4491 // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send
4500 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence. 4492 // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence.
4501 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); 4493 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
4502 4494
4503 if (sp != null) 4495 if (sp != null)
@@ -4512,7 +4504,7 @@ namespace OpenSim.Region.Framework.Scenes
4512 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID)); 4504 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID));
4513 } 4505 }
4514 4506
4515 sp.ChildAgentDataUpdate(cAgentData); 4507 sp.UpdateChildAgent(cAgentData);
4516 4508
4517 int ntimes = 20; 4509 int ntimes = 20;
4518 if (cAgentData.SenderWantsToWaitForRoot) 4510 if (cAgentData.SenderWantsToWaitForRoot)
@@ -4520,9 +4512,14 @@ namespace OpenSim.Region.Framework.Scenes
4520 while (sp.IsChildAgent && ntimes-- > 0) 4512 while (sp.IsChildAgent && ntimes-- > 0)
4521 Thread.Sleep(1000); 4513 Thread.Sleep(1000);
4522 4514
4523 m_log.DebugFormat( 4515 if (sp.IsChildAgent)
4524 "[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits", 4516 m_log.WarnFormat(
4525 sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", Name, 20 - ntimes); 4517 "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}",
4518 sp.Name, sp.UUID, Name);
4519 else
4520 m_log.InfoFormat(
4521 "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits",
4522 sp.Name, sp.UUID, Name, 20 - ntimes);
4526 4523
4527 if (sp.IsChildAgent) 4524 if (sp.IsChildAgent)
4528 return false; 4525 return false;
@@ -4540,7 +4537,7 @@ namespace OpenSim.Region.Framework.Scenes
4540 /// </summary> 4537 /// </summary>
4541 /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param> 4538 /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param>
4542 /// <returns>true if we handled it.</returns> 4539 /// <returns>true if we handled it.</returns>
4543 public virtual bool IncomingChildAgentDataUpdate(AgentPosition cAgentData) 4540 public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData)
4544 { 4541 {
4545 //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName); 4542 //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName);
4546 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); 4543 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
@@ -4560,7 +4557,7 @@ namespace OpenSim.Region.Framework.Scenes
4560 uint tRegionX = RegionInfo.RegionLocX; 4557 uint tRegionX = RegionInfo.RegionLocX;
4561 uint tRegionY = RegionInfo.RegionLocY; 4558 uint tRegionY = RegionInfo.RegionLocY;
4562 //Send Data to ScenePresence 4559 //Send Data to ScenePresence
4563 childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); 4560 childAgentUpdate.UpdateChildAgent(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
4564 // Not Implemented: 4561 // Not Implemented:
4565 //TODO: Do we need to pass the message on to one of our neighbors? 4562 //TODO: Do we need to pass the message on to one of our neighbors?
4566 } 4563 }
@@ -4610,7 +4607,7 @@ namespace OpenSim.Region.Framework.Scenes
4610 /// <param name="force"></param> 4607 /// <param name="force"></param>
4611 /// <param name="auth_token"></param> 4608 /// <param name="auth_token"></param>
4612 /// <returns></returns> 4609 /// <returns></returns>
4613 public bool IncomingCloseAgent(UUID agentID, bool force, string auth_token) 4610 public bool CloseAgent(UUID agentID, bool force, string auth_token)
4614 { 4611 {
4615 //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token); 4612 //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token);
4616 4613
@@ -4628,7 +4625,7 @@ namespace OpenSim.Region.Framework.Scenes
4628 4625
4629 if (acd.SessionID.ToString() == auth_token) 4626 if (acd.SessionID.ToString() == auth_token)
4630 { 4627 {
4631 return IncomingCloseAgent(agentID, force); 4628 return CloseAgent(agentID, force);
4632 } 4629 }
4633 else 4630 else
4634 { 4631 {
@@ -4640,27 +4637,27 @@ namespace OpenSim.Region.Framework.Scenes
4640 return false; 4637 return false;
4641 } 4638 }
4642 4639
4643 public bool IncomingCloseAgent(UUID agentID) 4640// public bool IncomingCloseAgent(UUID agentID)
4644 { 4641// {
4645 return IncomingCloseAgent(agentID, false); 4642// return IncomingCloseAgent(agentID, false);
4646 } 4643// }
4647 4644
4648 public bool IncomingCloseChildAgent(UUID agentID) 4645// public bool IncomingCloseChildAgent(UUID agentID)
4649 { 4646// {
4650 return IncomingCloseAgent(agentID, true); 4647// return IncomingCloseAgent(agentID, true);
4651 } 4648// }
4652 4649
4653 /// <summary> 4650 /// <summary>
4654 /// Tell a single agent to prepare to close. 4651 /// Tell a single client to prepare to close.
4655 /// </summary> 4652 /// </summary>
4656 /// <remarks> 4653 /// <remarks>
4657 /// This should only be called if we may close the agent but there will be some delay in so doing. Meant for 4654 /// This should only be called if we may close the client but there will be some delay in so doing. Meant for
4658 /// internal use - other callers should almost certainly called IncomingCloseAgent(). 4655 /// internal use - other callers should almost certainly called CloseClient().
4659 /// </remarks> 4656 /// </remarks>
4660 /// <param name="sp"></param> 4657 /// <param name="sp"></param>
4661 /// <returns>true if pre-close state notification was successful. false if the agent 4658 /// <returns>true if pre-close state notification was successful. false if the agent
4662 /// was not in a state where it could transition to pre-close.</returns> 4659 /// was not in a state where it could transition to pre-close.</returns>
4663 public bool IncomingPreCloseAgent(ScenePresence sp) 4660 public bool IncomingPreCloseClient(ScenePresence sp)
4664 { 4661 {
4665 lock (m_removeClientLock) 4662 lock (m_removeClientLock)
4666 { 4663 {
@@ -4702,7 +4699,7 @@ namespace OpenSim.Region.Framework.Scenes
4702 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to 4699 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4703 /// force unless you are absolutely sure that the agent is dead and a normal close is not working. 4700 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4704 /// </param> 4701 /// </param>
4705 public bool IncomingCloseAgent(UUID agentID, bool force) 4702 public override bool CloseAgent(UUID agentID, bool force)
4706 { 4703 {
4707 ScenePresence sp; 4704 ScenePresence sp;
4708 4705
@@ -4713,7 +4710,7 @@ namespace OpenSim.Region.Framework.Scenes
4713 if (sp == null) 4710 if (sp == null)
4714 { 4711 {
4715 m_log.DebugFormat( 4712 m_log.DebugFormat(
4716 "[SCENE]: Called IncomingCloseAgent() with agent ID {0} but no such presence is in {1}", 4713 "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}",
4717 agentID, Name); 4714 agentID, Name);
4718 4715
4719 return false; 4716 return false;
@@ -4722,7 +4719,7 @@ namespace OpenSim.Region.Framework.Scenes
4722 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove) 4719 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove)
4723 { 4720 {
4724 m_log.DebugFormat( 4721 m_log.DebugFormat(
4725 "[SCENE]: Called IncomingCloseAgent() for {0} in {1} but presence is already in state {2}", 4722 "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}",
4726 sp.Name, Name, sp.LifecycleState); 4723 sp.Name, Name, sp.LifecycleState);
4727 4724
4728 return false; 4725 return false;
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 1dac676..9354a88 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -217,21 +217,9 @@ namespace OpenSim.Region.Framework.Scenes
217 217
218 #region Add/Remove Agent/Avatar 218 #region Add/Remove Agent/Avatar
219 219
220 public abstract ISceneAgent AddNewClient(IClientAPI client, PresenceType type); 220 public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type);
221 221
222 /// <summary> 222 public abstract bool CloseAgent(UUID agentID, bool force);
223 /// Remove the given client from the scene.
224 /// </summary>
225 /// <remarks>
226 /// Only clientstack code should call this directly. All other code should call IncomingCloseAgent() instead
227 /// to properly operate the state machine and avoid race conditions with other close requests (such as directly
228 /// from viewers).
229 /// </remarks>
230 /// <param name='agentID'>ID of agent to close</param>
231 /// <param name='closeChildAgents'>
232 /// Close the neighbour child agents associated with this client.
233 /// </param>
234 public abstract void RemoveClient(UUID agentID, bool closeChildAgents);
235 223
236 public bool TryGetScenePresence(UUID agentID, out object scenePresence) 224 public bool TryGetScenePresence(UUID agentID, out object scenePresence)
237 { 225 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index cf03d7c..66b42a1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2960,6 +2960,26 @@ namespace OpenSim.Region.Framework.Scenes
2960 //ParentGroup.RootPart.m_groupPosition = newpos; 2960 //ParentGroup.RootPart.m_groupPosition = newpos;
2961 } 2961 }
2962 2962
2963 if (pa != null && ParentID != 0 && ParentGroup != null)
2964 {
2965 // Special case where a child object is requesting property updates.
2966 // This happens when linksets are modified to use flexible links rather than
2967 // the default links.
2968 // The simulator code presumes that child parts are only modified by scripts
2969 // so the logic for changing position/rotation/etc does not take into
2970 // account the physical object actually moving.
2971 // This code updates the offset position and rotation of the child and then
2972 // lets the update code push the update to the viewer.
2973 // Since physics engines do not normally generate this event for linkset children,
2974 // this code will not be active unless you have a specially configured
2975 // physics engine.
2976 Quaternion invRootRotation = Quaternion.Normalize(Quaternion.Inverse(ParentGroup.RootPart.RotationOffset));
2977 m_offsetPosition = pa.Position - m_groupPosition;
2978 RotationOffset = pa.Orientation * invRootRotation;
2979 // m_log.DebugFormat("{0} PhysicsRequestingTerseUpdate child: pos={1}, rot={2}, offPos={3}, offRot={4}",
2980 // "[SCENE OBJECT PART]", pa.Position, pa.Orientation, m_offsetPosition, RotationOffset);
2981 }
2982
2963 ScheduleTerseUpdate(); 2983 ScheduleTerseUpdate();
2964 } 2984 }
2965 2985
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 183d8d1..9f330fd 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -320,7 +320,21 @@ namespace OpenSim.Region.Framework.Scenes
320 /// </summary> 320 /// </summary>
321 private string m_callbackURI; 321 private string m_callbackURI;
322 322
323 public UUID m_originRegionID; 323 /// <summary>
324 /// Records the region from which this presence originated, if not from login.
325 /// </summary>
326 /// <remarks>
327 /// Also acts as a signal in the teleport V2 process to release UpdateAgent after a viewer has triggered
328 /// CompleteMovement and made the previous child agent a root agent.
329 /// </remarks>
330 private UUID m_originRegionID;
331
332 /// <summary>
333 /// This object is used as a lock before accessing m_originRegionID to make sure that every thread is seeing
334 /// the very latest value and not using some cached version. Cannot make m_originRegionID itself volatite as
335 /// it is a value type.
336 /// </summary>
337 private object m_originRegionIDAccessLock = new object();
324 338
325 /// <summary> 339 /// <summary>
326 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent 340 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
@@ -975,11 +989,11 @@ namespace OpenSim.Region.Framework.Scenes
975 /// This method is on the critical path for transferring an avatar from one region to another. Delay here 989 /// This method is on the critical path for transferring an avatar from one region to another. Delay here
976 /// delays that crossing. 990 /// delays that crossing.
977 /// </summary> 991 /// </summary>
978 public void MakeRootAgent(Vector3 pos, bool isFlying) 992 private void MakeRootAgent(Vector3 pos, bool isFlying)
979 { 993 {
980 m_log.InfoFormat( 994// m_log.InfoFormat(
981 "[SCENE]: Upgrading child to root agent for {0} in {1}", 995// "[SCENE]: Upgrading child to root agent for {0} in {1}",
982 Name, m_scene.RegionInfo.RegionName); 996// Name, m_scene.RegionInfo.RegionName);
983 997
984 if (ParentUUID != UUID.Zero) 998 if (ParentUUID != UUID.Zero)
985 { 999 {
@@ -1545,15 +1559,26 @@ namespace OpenSim.Region.Framework.Scenes
1545 1559
1546 private bool WaitForUpdateAgent(IClientAPI client) 1560 private bool WaitForUpdateAgent(IClientAPI client)
1547 { 1561 {
1548 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero 1562 // Before the source region executes UpdateAgent
1563 // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination,
1564 // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the
1565 // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero
1549 int count = 50; 1566 int count = 50;
1550 while (m_originRegionID.Equals(UUID.Zero) && count-- > 0) 1567 UUID originID;
1568
1569 lock (m_originRegionIDAccessLock)
1570 originID = m_originRegionID;
1571
1572 while (originID.Equals(UUID.Zero) && count-- > 0)
1551 { 1573 {
1574 lock (m_originRegionIDAccessLock)
1575 originID = m_originRegionID;
1576
1552 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); 1577 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name);
1553 Thread.Sleep(200); 1578 Thread.Sleep(200);
1554 } 1579 }
1555 1580
1556 if (m_originRegionID.Equals(UUID.Zero)) 1581 if (originID.Equals(UUID.Zero))
1557 { 1582 {
1558 // Movement into region will fail 1583 // Movement into region will fail
1559 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); 1584 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name);
@@ -1576,9 +1601,9 @@ namespace OpenSim.Region.Framework.Scenes
1576 { 1601 {
1577// DateTime startTime = DateTime.Now; 1602// DateTime startTime = DateTime.Now;
1578 1603
1579 m_log.DebugFormat( 1604 m_log.InfoFormat(
1580 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", 1605 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
1581 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); 1606 client.Name, Scene.Name, AbsolutePosition);
1582 1607
1583 // Make sure it's not a login agent. We don't want to wait for updates during login 1608 // Make sure it's not a login agent. We don't want to wait for updates during login
1584 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) 1609 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
@@ -1633,7 +1658,12 @@ namespace OpenSim.Region.Framework.Scenes
1633 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", 1658 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1634 client.Name, client.AgentId, m_callbackURI); 1659 client.Name, client.AgentId, m_callbackURI);
1635 1660
1636 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); 1661 UUID originID;
1662
1663 lock (m_originRegionIDAccessLock)
1664 originID = m_originRegionID;
1665
1666 Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
1637 m_callbackURI = null; 1667 m_callbackURI = null;
1638 } 1668 }
1639// else 1669// else
@@ -3089,7 +3119,7 @@ namespace OpenSim.Region.Framework.Scenes
3089 // If we are using the the cached appearance then send it out to everyone 3119 // If we are using the the cached appearance then send it out to everyone
3090 if (cachedappearance) 3120 if (cachedappearance)
3091 { 3121 {
3092 m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); 3122 m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name);
3093 3123
3094 // If the avatars baked textures are all in the cache, then we have a 3124 // If the avatars baked textures are all in the cache, then we have a
3095 // complete appearance... send it out, if not, then we'll send it when 3125 // complete appearance... send it out, if not, then we'll send it when
@@ -3553,7 +3583,7 @@ namespace OpenSim.Region.Framework.Scenes
3553 3583
3554 #region Child Agent Updates 3584 #region Child Agent Updates
3555 3585
3556 public void ChildAgentDataUpdate(AgentData cAgentData) 3586 public void UpdateChildAgent(AgentData cAgentData)
3557 { 3587 {
3558// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); 3588// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
3559 if (!IsChildAgent) 3589 if (!IsChildAgent)
@@ -3563,15 +3593,17 @@ namespace OpenSim.Region.Framework.Scenes
3563 } 3593 }
3564 3594
3565 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3595 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3596
3566 private void RaiseUpdateThrottles() 3597 private void RaiseUpdateThrottles()
3567 { 3598 {
3568 m_scene.EventManager.TriggerThrottleUpdate(this); 3599 m_scene.EventManager.TriggerThrottleUpdate(this);
3569 } 3600 }
3601
3570 /// <summary> 3602 /// <summary>
3571 /// This updates important decision making data about a child agent 3603 /// This updates important decision making data about a child agent
3572 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3604 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
3573 /// </summary> 3605 /// </summary>
3574 public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) 3606 public void UpdateChildAgent(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY)
3575 { 3607 {
3576 if (!IsChildAgent) 3608 if (!IsChildAgent)
3577 return; 3609 return;
@@ -3679,7 +3711,8 @@ namespace OpenSim.Region.Framework.Scenes
3679 3711
3680 private void CopyFrom(AgentData cAgent) 3712 private void CopyFrom(AgentData cAgent)
3681 { 3713 {
3682 m_originRegionID = cAgent.RegionID; 3714 lock (m_originRegionIDAccessLock)
3715 m_originRegionID = cAgent.RegionID;
3683 3716
3684 m_callbackURI = cAgent.CallbackURI; 3717 m_callbackURI = cAgent.CallbackURI;
3685// m_log.DebugFormat( 3718// m_log.DebugFormat(
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 68918d3..bc51b32 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -365,6 +365,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
365 m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound); 365 m_SOPXmlProcessors.Add("CollisionSound", ProcessCollisionSound);
366 m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume); 366 m_SOPXmlProcessors.Add("CollisionSoundVolume", ProcessCollisionSoundVolume);
367 m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl); 367 m_SOPXmlProcessors.Add("MediaUrl", ProcessMediaUrl);
368 m_SOPXmlProcessors.Add("AttachedPos", ProcessAttachedPos);
368 m_SOPXmlProcessors.Add("DynAttrs", ProcessDynAttrs); 369 m_SOPXmlProcessors.Add("DynAttrs", ProcessDynAttrs);
369 m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation); 370 m_SOPXmlProcessors.Add("TextureAnimation", ProcessTextureAnimation);
370 m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); 371 m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
@@ -443,6 +444,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
443 m_ShapeXmlProcessors.Add("ProfileEnd", ProcessShpProfileEnd); 444 m_ShapeXmlProcessors.Add("ProfileEnd", ProcessShpProfileEnd);
444 m_ShapeXmlProcessors.Add("ProfileHollow", ProcessShpProfileHollow); 445 m_ShapeXmlProcessors.Add("ProfileHollow", ProcessShpProfileHollow);
445 m_ShapeXmlProcessors.Add("Scale", ProcessShpScale); 446 m_ShapeXmlProcessors.Add("Scale", ProcessShpScale);
447 m_ShapeXmlProcessors.Add("LastAttachPoint", ProcessShpLastAttach);
446 m_ShapeXmlProcessors.Add("State", ProcessShpState); 448 m_ShapeXmlProcessors.Add("State", ProcessShpState);
447 m_ShapeXmlProcessors.Add("ProfileShape", ProcessShpProfileShape); 449 m_ShapeXmlProcessors.Add("ProfileShape", ProcessShpProfileShape);
448 m_ShapeXmlProcessors.Add("HollowShape", ProcessShpHollowShape); 450 m_ShapeXmlProcessors.Add("HollowShape", ProcessShpHollowShape);
@@ -798,6 +800,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
798 obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty); 800 obj.MediaUrl = reader.ReadElementContentAsString("MediaUrl", String.Empty);
799 } 801 }
800 802
803 private static void ProcessAttachedPos(SceneObjectPart obj, XmlTextReader reader)
804 {
805 obj.AttachedPos = Util.ReadVector(reader, "AttachedPos");
806 }
807
801 private static void ProcessDynAttrs(SceneObjectPart obj, XmlTextReader reader) 808 private static void ProcessDynAttrs(SceneObjectPart obj, XmlTextReader reader)
802 { 809 {
803 obj.DynAttrs.ReadXml(reader); 810 obj.DynAttrs.ReadXml(reader);
@@ -1099,6 +1106,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1099 shp.State = (byte)reader.ReadElementContentAsInt("State", String.Empty); 1106 shp.State = (byte)reader.ReadElementContentAsInt("State", String.Empty);
1100 } 1107 }
1101 1108
1109 private static void ProcessShpLastAttach(PrimitiveBaseShape shp, XmlTextReader reader)
1110 {
1111 shp.LastAttachPoint = (byte)reader.ReadElementContentAsInt("LastAttachPoint", String.Empty);
1112 }
1113
1102 private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader) 1114 private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader)
1103 { 1115 {
1104 shp.ProfileShape = Util.ReadEnum<ProfileShape>(reader, "ProfileShape"); 1116 shp.ProfileShape = Util.ReadEnum<ProfileShape>(reader, "ProfileShape");
@@ -1345,6 +1357,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1345 writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); 1357 writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString());
1346 if (sop.MediaUrl != null) 1358 if (sop.MediaUrl != null)
1347 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); 1359 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
1360 WriteVector(writer, "AttachedPos", sop.AttachedPos);
1348 1361
1349 if (sop.DynAttrs.CountNamespaces > 0) 1362 if (sop.DynAttrs.CountNamespaces > 0)
1350 { 1363 {
@@ -1539,6 +1552,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1539 writer.WriteElementString("ProfileEnd", shp.ProfileEnd.ToString()); 1552 writer.WriteElementString("ProfileEnd", shp.ProfileEnd.ToString());
1540 writer.WriteElementString("ProfileHollow", shp.ProfileHollow.ToString()); 1553 writer.WriteElementString("ProfileHollow", shp.ProfileHollow.ToString());
1541 writer.WriteElementString("State", shp.State.ToString()); 1554 writer.WriteElementString("State", shp.State.ToString());
1555 writer.WriteElementString("LastAttachPoint", shp.LastAttachPoint.ToString());
1542 1556
1543 WriteFlags(writer, "ProfileShape", shp.ProfileShape.ToString(), options); 1557 WriteFlags(writer, "ProfileShape", shp.ProfileShape.ToString(), options);
1544 WriteFlags(writer, "HollowShape", shp.HollowShape.ToString(), options); 1558 WriteFlags(writer, "HollowShape", shp.HollowShape.ToString(), options);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index bbe34d2..d1aeaee 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -146,7 +146,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
146 } 146 }
147 147
148 [Test] 148 [Test]
149 public void TestCloseAgent() 149 public void TestCloseClient()
150 { 150 {
151 TestHelpers.InMethod(); 151 TestHelpers.InMethod();
152// TestHelpers.EnableLogging(); 152// TestHelpers.EnableLogging();
@@ -154,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
154 TestScene scene = new SceneHelpers().SetupScene(); 154 TestScene scene = new SceneHelpers().SetupScene();
155 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 155 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
156 156
157 scene.IncomingCloseAgent(sp.UUID, false); 157 scene.CloseAgent(sp.UUID, false);
158 158
159 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); 159 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
160 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); 160 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
@@ -200,7 +200,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
200 // *** This is the second stage, where the client established a child agent/scene presence using the 200 // *** This is the second stage, where the client established a child agent/scene presence using the
201 // circuit code given to the scene in stage 1 *** 201 // circuit code given to the scene in stage 1 ***
202 TestClient client = new TestClient(acd, scene); 202 TestClient client = new TestClient(acd, scene);
203 scene.AddNewClient(client, PresenceType.User); 203 scene.AddNewAgent(client, PresenceType.User);
204 204
205 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(agentId), Is.Not.Null); 205 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(agentId), Is.Not.Null);
206 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); 206 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
@@ -279,7 +279,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
279// string reason; 279// string reason;
280// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason); 280// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason);
281// testclient = new TestClient(agent, scene); 281// testclient = new TestClient(agent, scene);
282// scene.AddNewClient(testclient); 282// scene.AddNewAgent(testclient);
283// 283//
284// ScenePresence presence = scene.GetScenePresence(agent1); 284// ScenePresence presence = scene.GetScenePresence(agent1);
285// 285//
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
index 4ae7a8e..9fa0a71 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
@@ -79,8 +79,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
79 79
80 // TODO: Need to add tests for other ICapabiltiesModule methods. 80 // TODO: Need to add tests for other ICapabiltiesModule methods.
81 81
82 scene.IncomingCloseAgent(sp.UUID, false); 82// scene.IncomingCloseAgent(sp.UUID, false);
83 //Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null); 83// //Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null);
84 scene.CloseAgent(sp.UUID, false);
85// Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null);
84 86
85 // TODO: Need to add tests for other ICapabiltiesModule methods. 87 // TODO: Need to add tests for other ICapabiltiesModule methods.
86 } 88 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
index 12a778b..b806a97 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
@@ -38,6 +38,7 @@ using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.CoreModules.Framework; 38using OpenSim.Region.CoreModules.Framework;
39using OpenSim.Region.CoreModules.Framework.EntityTransfer; 39using OpenSim.Region.CoreModules.Framework.EntityTransfer;
40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Region.CoreModules.World.Permissions;
41using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock; 43using OpenSim.Tests.Common.Mock;
43 44
@@ -159,5 +160,90 @@ namespace OpenSim.Region.Framework.Scenes.Tests
159 Assert.That(agentMovementCompleteReceived, Is.EqualTo(1)); 160 Assert.That(agentMovementCompleteReceived, Is.EqualTo(1));
160 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.False); 161 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.False);
161 } 162 }
163
164 /// <summary>
165 /// Test a cross attempt where the user can see into the neighbour but does not have permission to become
166 /// root there.
167 /// </summary>
168 [Test]
169 public void TestCrossOnSameSimulatorNoRootDestPerm()
170 {
171 TestHelpers.InMethod();
172// TestHelpers.EnableLogging();
173
174 UUID userId = TestHelpers.ParseTail(0x1);
175
176 EntityTransferModule etmA = new EntityTransferModule();
177 EntityTransferModule etmB = new EntityTransferModule();
178 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
179
180 IConfigSource config = new IniConfigSource();
181 IConfig modulesConfig = config.AddConfig("Modules");
182 modulesConfig.Set("EntityTransferModule", etmA.Name);
183 modulesConfig.Set("SimulationServices", lscm.Name);
184
185 SceneHelpers sh = new SceneHelpers();
186 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
187 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999);
188
189 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
190 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
191
192 // We need to set up the permisions module on scene B so that our later use of agent limit to deny
193 // QueryAccess won't succeed anyway because administrators are always allowed in and the default
194 // IsAdministrator if no permissions module is present is true.
195// SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), new PermissionsModule(), etmB);
196
197 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
198 TestClient tc = new TestClient(acd, sceneA);
199 List<TestClient> destinationTestClients = new List<TestClient>();
200 EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
201
202 // Make sure sceneB will not accept this avatar.
203 sceneB.RegionInfo.EstateSettings.PublicAccess = false;
204
205 ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
206 originalSp.AbsolutePosition = new Vector3(128, 32, 10);
207
208 AgentUpdateArgs moveArgs = new AgentUpdateArgs();
209 //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero);
210 moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2)));
211 moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
212 moveArgs.SessionID = acd.SessionID;
213
214 originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs);
215
216 sceneA.Update(1);
217
218// Console.WriteLine("Second pos {0}", originalSp.AbsolutePosition);
219
220 // FIXME: This is a sufficient number of updates to for the presence to reach the northern border.
221 // But really we want to do this in a more robust way.
222 for (int i = 0; i < 100; i++)
223 {
224 sceneA.Update(1);
225// Console.WriteLine("Pos {0}", originalSp.AbsolutePosition);
226 }
227
228 // sceneA agent should still be root
229 ScenePresence spAfterCrossSceneA = sceneA.GetScenePresence(originalSp.UUID);
230 Assert.That(spAfterCrossSceneA.IsChildAgent, Is.False);
231
232 ScenePresence spAfterCrossSceneB = sceneB.GetScenePresence(originalSp.UUID);
233
234 // sceneB agent should also still be root
235 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.True);
236
237 // sceneB should ignore unauthorized attempt to upgrade agent to root
238 TestClient sceneBTc = ((TestClient)spAfterCrossSceneB.ControllingClient);
239
240 int agentMovementCompleteReceived = 0;
241 sceneBTc.OnReceivedMoveAgentIntoRegion += (ri, pos, look) => agentMovementCompleteReceived++;
242
243 sceneBTc.CompleteMovement();
244
245 Assert.That(agentMovementCompleteReceived, Is.EqualTo(0));
246 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.True);
247 }
162 } 248 }
163} \ No newline at end of file 249}
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index e60a025..84e410f 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -168,7 +168,20 @@ namespace OpenSim.Region.Framework.Scenes
168 // If the prim is a sculpt then preserve this information too 168 // If the prim is a sculpt then preserve this information too
169 if (part.Shape.SculptTexture != UUID.Zero) 169 if (part.Shape.SculptTexture != UUID.Zero)
170 assetUuids[part.Shape.SculptTexture] = AssetType.Texture; 170 assetUuids[part.Shape.SculptTexture] = AssetType.Texture;
171 171
172 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
173 assetUuids[part.Shape.ProjectionTextureUUID] = AssetType.Texture;
174
175 if (part.CollisionSound != UUID.Zero)
176 assetUuids[part.CollisionSound] = AssetType.Sound;
177
178 if (part.ParticleSystem.Length > 0)
179 {
180 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
181 if (ps.Texture != UUID.Zero)
182 assetUuids[ps.Texture] = AssetType.Texture;
183 }
184
172 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 185 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
173 186
174 // Now analyze this prim's inventory items to preserve all the uuids that they reference 187 // Now analyze this prim's inventory items to preserve all the uuids that they reference