aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs2
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs11
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs79
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs183
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs114
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs43
-rw-r--r--bin/OpenSimDefaults.ini7
9 files changed, 358 insertions, 85 deletions
diff --git a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
index 79d6fc5..3ac74fc 100644
--- a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
+++ b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Groups
53 private ForeignImporter m_ForeignImporter; 53 private ForeignImporter m_ForeignImporter;
54 54
55 private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>(); 55 private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>();
56 private const int GROUPS_CACHE_TIMEOUT = 5 * 60; // 5 minutes 56 private const int GROUPS_CACHE_TIMEOUT = 1 * 60; // 1 minutes
57 57
58 // This all important cache cahces objects of different types: 58 // This all important cache cahces objects of different types:
59 // group-<GroupID> or group-<Name> => ExtendedGroupRecord 59 // group-<GroupID> or group-<Name> => ExtendedGroupRecord
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index b399a58..4962629 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -292,7 +292,7 @@ namespace OpenSim.Framework
292 public Vector3 AtAxis; 292 public Vector3 AtAxis;
293 public Vector3 LeftAxis; 293 public Vector3 LeftAxis;
294 public Vector3 UpAxis; 294 public Vector3 UpAxis;
295 public bool ChangedGrid; 295 public bool SenderWantsToWaitForRoot;
296 296
297 public float Far; 297 public float Far;
298 public float Aspect; 298 public float Aspect;
@@ -363,8 +363,9 @@ namespace OpenSim.Framework
363 args["left_axis"] = OSD.FromString(LeftAxis.ToString()); 363 args["left_axis"] = OSD.FromString(LeftAxis.ToString());
364 args["up_axis"] = OSD.FromString(UpAxis.ToString()); 364 args["up_axis"] = OSD.FromString(UpAxis.ToString());
365 365
366 366 //backwards compatibility
367 args["changed_grid"] = OSD.FromBoolean(ChangedGrid); 367 args["changed_grid"] = OSD.FromBoolean(SenderWantsToWaitForRoot);
368 args["wait_for_root"] = OSD.FromBoolean(SenderWantsToWaitForRoot);
368 args["far"] = OSD.FromReal(Far); 369 args["far"] = OSD.FromReal(Far);
369 args["aspect"] = OSD.FromReal(Aspect); 370 args["aspect"] = OSD.FromReal(Aspect);
370 371
@@ -537,8 +538,8 @@ namespace OpenSim.Framework
537 if (args["up_axis"] != null) 538 if (args["up_axis"] != null)
538 Vector3.TryParse(args["up_axis"].AsString(), out AtAxis); 539 Vector3.TryParse(args["up_axis"].AsString(), out AtAxis);
539 540
540 if (args["changed_grid"] != null) 541 if (args.ContainsKey("wait_for_root") && args["wait_for_root"] != null)
541 ChangedGrid = args["changed_grid"].AsBoolean(); 542 SenderWantsToWaitForRoot = args["wait_for_root"].AsBoolean();
542 543
543 if (args["far"] != null) 544 if (args["far"] != null)
544 Far = (float)(args["far"].AsReal()); 545 Far = (float)(args["far"].AsReal());
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 7a4c6f4..544b54b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1302,6 +1302,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1302 queue.Enqueue(buffer); 1302 queue.Enqueue(buffer);
1303 return; 1303 return;
1304 } 1304 }
1305 else if (packet.Type == PacketType.CompleteAgentMovement)
1306 {
1307 // Send ack straight away to let the viewer know that we got it.
1308 SendAckImmediate(endPoint, packet.Header.Sequence);
1309
1310 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1311 // buffer.
1312 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1313
1314 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1315
1316 return;
1317 }
1305 } 1318 }
1306 1319
1307 // Determine which agent this packet came from 1320 // Determine which agent this packet came from
@@ -1676,6 +1689,72 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1676 } 1689 }
1677 } 1690 }
1678 1691
1692 private void HandleCompleteMovementIntoRegion(object o)
1693 {
1694 IPEndPoint endPoint = null;
1695 IClientAPI client = null;
1696
1697 try
1698 {
1699 object[] array = (object[])o;
1700 endPoint = (IPEndPoint)array[0];
1701 CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
1702
1703 // Determine which agent this packet came from
1704 int count = 20;
1705 bool ready = false;
1706 while (!ready && count-- > 0)
1707 {
1708 if (m_scene.TryGetClient(endPoint, out client) && client.IsActive && client.SceneAgent != null)
1709 {
1710 LLClientView llClientView = (LLClientView)client;
1711 LLUDPClient udpClient = llClientView.UDPClient;
1712 if (udpClient != null && udpClient.IsConnected)
1713 ready = true;
1714 else
1715 {
1716 m_log.Debug("[LLUDPSERVER]: Received a CompleteMovementIntoRegion in " + m_scene.RegionInfo.RegionName + " (not ready yet)");
1717 Thread.Sleep(200);
1718 }
1719 }
1720 else
1721 {
1722 m_log.Debug("[LLUDPSERVER]: Received a CompleteMovementIntoRegion in " + m_scene.RegionInfo.RegionName + " (not ready yet)");
1723 Thread.Sleep(200);
1724 }
1725 }
1726
1727 if (client == null)
1728 return;
1729
1730 IncomingPacket incomingPacket1;
1731
1732 // Inbox insertion
1733 if (UsePools)
1734 {
1735 incomingPacket1 = m_incomingPacketPool.GetObject();
1736 incomingPacket1.Client = (LLClientView)client;
1737 incomingPacket1.Packet = packet;
1738 }
1739 else
1740 {
1741 incomingPacket1 = new IncomingPacket((LLClientView)client, packet);
1742 }
1743
1744 packetInbox.Enqueue(incomingPacket1);
1745 }
1746 catch (Exception e)
1747 {
1748 m_log.ErrorFormat(
1749 "[LLUDPSERVER]: CompleteMovementIntoRegion handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
1750 endPoint != null ? endPoint.ToString() : "n/a",
1751 client != null ? client.Name : "unknown",
1752 client != null ? client.AgentId.ToString() : "unknown",
1753 e.Message,
1754 e.StackTrace);
1755 }
1756 }
1757
1679 /// <summary> 1758 /// <summary>
1680 /// Send an ack immediately to the given endpoint. 1759 /// Send an ack immediately to the given endpoint.
1681 /// </summary> 1760 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index a3c539d..29b4296 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -689,6 +689,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
689 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 689 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
690 } 690 }
691 691
692 if (version.Equals("SIMULATION/0.2"))
693 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
694 else
695 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
696
697 }
698
699 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
700 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason)
701 {
702 ulong destinationHandle = finalDestination.RegionHandle;
703 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
704
705 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Using TP V1");
692 // Let's create an agent there if one doesn't exist yet. 706 // Let's create an agent there if one doesn't exist yet.
693 // NOTE: logout will always be false for a non-HG teleport. 707 // NOTE: logout will always be false for a non-HG teleport.
694 bool logout = false; 708 bool logout = false;
@@ -710,7 +724,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
710 m_interRegionTeleportCancels.Value++; 724 m_interRegionTeleportCancels.Value++;
711 725
712 m_log.DebugFormat( 726 m_log.DebugFormat(
713 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", 727 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
714 sp.Name, finalDestination.RegionName, sp.Scene.Name); 728 sp.Name, finalDestination.RegionName, sp.Scene.Name);
715 729
716 return; 730 return;
@@ -732,11 +746,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
732 // OK, it got this agent. Let's close some child agents 746 // OK, it got this agent. Let's close some child agents
733 sp.CloseChildAgents(newRegionX, newRegionY); 747 sp.CloseChildAgents(newRegionX, newRegionY);
734 748
735 IClientIPEndpoint ipepClient; 749 IClientIPEndpoint ipepClient;
750 string capsPath = String.Empty;
736 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 751 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
737 { 752 {
738 m_log.DebugFormat( 753 m_log.DebugFormat(
739 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", 754 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
740 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); 755 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
741 756
742 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); 757 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
@@ -783,10 +798,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
783 // Let's send a full update of the agent. This is a synchronous call. 798 // Let's send a full update of the agent. This is a synchronous call.
784 AgentData agent = new AgentData(); 799 AgentData agent = new AgentData();
785 sp.CopyTo(agent); 800 sp.CopyTo(agent);
786 agent.Position = position; 801 agent.Position = agentCircuit.startpos;
787 SetCallbackURL(agent, sp.Scene.RegionInfo); 802 SetCallbackURL(agent, sp.Scene.RegionInfo);
788 803
789 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
790 804
791 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to 805 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
792 // establish th econnection to the destination which makes it return true. 806 // establish th econnection to the destination which makes it return true.
@@ -821,7 +835,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
821 m_log.WarnFormat( 835 m_log.WarnFormat(
822 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", 836 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
823 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 837 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
824 838
825 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); 839 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
826 return; 840 return;
827 } 841 }
@@ -831,7 +845,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
831 m_interRegionTeleportCancels.Value++; 845 m_interRegionTeleportCancels.Value++;
832 846
833 m_log.DebugFormat( 847 m_log.DebugFormat(
834 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", 848 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
835 sp.Name, finalDestination.RegionName, sp.Scene.Name); 849 sp.Name, finalDestination.RegionName, sp.Scene.Name);
836 850
837 CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination); 851 CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination);
@@ -848,6 +862,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
848 // closes our existing agent which is still signalled as root. 862 // closes our existing agent which is still signalled as root.
849 sp.IsChildAgent = true; 863 sp.IsChildAgent = true;
850 864
865 // OK, send TPFinish to the client, so that it starts the process of contacting the destination region
851 if (m_eqModule != null) 866 if (m_eqModule != null)
852 { 867 {
853 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); 868 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID);
@@ -877,7 +892,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
877 m_log.WarnFormat( 892 m_log.WarnFormat(
878 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 893 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
879 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 894 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
880 895
881 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion."); 896 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion.");
882 897
883 return; 898 return;
@@ -906,13 +921,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
906 921
907 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 922 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
908 { 923 {
909 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before 924 // RED ALERT!!!!
910 // they regard the new region as the current region after receiving the AgentMovementComplete 925 // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
911 // response. If close is sent before then, it will cause the viewer to quit instead. 926 // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
912 // 927 // BEFORE THEY SETTLE IN THE NEW REGION.
913 // This sleep can be increased if necessary. However, whilst it's active, 928 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
914 // an agent cannot teleport back to this region if it has teleported away. 929 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
915 Thread.Sleep(3000); 930 Thread.Sleep(5000);
916 931
917 sp.Scene.IncomingCloseAgent(sp.UUID, false); 932 sp.Scene.IncomingCloseAgent(sp.UUID, false);
918 } 933 }
@@ -923,6 +938,134 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
923 } 938 }
924 } 939 }
925 940
941 private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
942 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason)
943 {
944 ulong destinationHandle = finalDestination.RegionHandle;
945 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
946
947 // Let's create an agent there if one doesn't exist yet.
948 // NOTE: logout will always be false for a non-HG teleport.
949 bool logout = false;
950 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
951 {
952 m_interRegionTeleportFailures.Value++;
953
954 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
955
956 m_log.DebugFormat(
957 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
958 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
959
960 return;
961 }
962
963 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
964 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
965
966 IClientIPEndpoint ipepClient;
967 string capsPath = String.Empty;
968 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
969 {
970 m_log.DebugFormat(
971 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
972 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
973
974 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
975 #region IP Translation for NAT
976 // Uses ipepClient above
977 if (sp.ClientView.TryGet(out ipepClient))
978 {
979 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
980 }
981 #endregion
982 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
983 }
984 else
985 {
986 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
987 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
988 }
989
990 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
991 // where that neighbour simulator could otherwise request a child agent create on the source which then
992 // closes our existing agent which is still signalled as root.
993 //sp.IsChildAgent = true;
994
995 // New protocol: send TP Finish directly, without prior ES or EAC. That's what happens in the Linden grid
996 if (m_eqModule != null)
997 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID);
998 else
999 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4,
1000 teleportFlags, capsPath);
1001
1002 m_log.DebugFormat(
1003 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
1004 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
1005
1006 // Let's send a full update of the agent.
1007 AgentData agent = new AgentData();
1008 sp.CopyTo(agent);
1009 agent.Position = agentCircuit.startpos;
1010 agent.SenderWantsToWaitForRoot = true;
1011 //SetCallbackURL(agent, sp.Scene.RegionInfo);
1012
1013 // Send the Update. If this returns true, we know the client has contacted the destination
1014 // via CompleteMovementIntoRegion, so we can let go.
1015 // If it returns false, something went wrong, and we need to abort.
1016 if (!UpdateAgent(reg, finalDestination, agent, sp))
1017 {
1018 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
1019 {
1020 m_interRegionTeleportAborts.Value++;
1021
1022 m_log.DebugFormat(
1023 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
1024 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1025
1026 return;
1027 }
1028
1029 m_log.WarnFormat(
1030 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
1031 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
1032
1033 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
1034 return;
1035 }
1036
1037 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
1038
1039 // May need to logout or other cleanup
1040 AgentHasMovedAway(sp, logout);
1041
1042 // Well, this is it. The agent is over there.
1043 KillEntity(sp.Scene, sp.LocalId);
1044
1045 // Now let's make it officially a child agent
1046 sp.MakeChildAgent();
1047
1048 // OK, it got this agent. Let's close some child agents
1049 sp.CloseChildAgents(newRegionX, newRegionY);
1050
1051 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
1052
1053 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
1054 {
1055 // RED ALERT!!!!
1056 // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
1057 // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
1058 // BEFORE THEY SETTLE IN THE NEW REGION.
1059 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
1060 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
1061 Thread.Sleep(5000);
1062 sp.Scene.IncomingCloseAgent(sp.UUID, false);
1063 }
1064 else
1065 // now we have a child agent in this region.
1066 sp.Reset();
1067 }
1068
926 /// <summary> 1069 /// <summary>
927 /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation. 1070 /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation.
928 /// </summary> 1071 /// </summary>
@@ -936,11 +1079,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
936 { 1079 {
937 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 1080 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
938 1081
939 sp.IsChildAgent = false; 1082 if (sp.IsChildAgent) // We had set it to child before attempted TP (V1)
940 ReInstantiateScripts(sp); 1083 {
941 1084 sp.IsChildAgent = false;
942 EnableChildAgents(sp); 1085 ReInstantiateScripts(sp);
943 1086
1087 EnableChildAgents(sp);
1088 }
944 // Finally, kill the agent we just created at the destination. 1089 // Finally, kill the agent we just created at the destination.
945 // XXX: Possibly this should be done asynchronously. 1090 // XXX: Possibly this should be done asynchronously.
946 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token); 1091 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
index 172bea1..516ad40 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
79 79
80 public void OnConnectionClose(IClientAPI client) 80 public void OnConnectionClose(IClientAPI client)
81 { 81 {
82 if (!client.SceneAgent.IsChildAgent) 82 if (client != null && client.SceneAgent != null && !client.SceneAgent.IsChildAgent)
83 { 83 {
84// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 84// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
85 m_PresenceService.LogoutAgent(client.SessionId); 85 m_PresenceService.LogoutAgent(client.SessionId);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 8207fb9..39657a3 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
48 /// <summary> 48 /// <summary>
49 /// Version of this service 49 /// Version of this service
50 /// </summary> 50 /// </summary>
51 private const string m_Version = "SIMULATION/0.1"; 51 private const string m_Version = "SIMULATION/0.2";
52 52
53 /// <summary> 53 /// <summary>
54 /// Map region ID to scene. 54 /// Map region ID to scene.
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index c132c5d..96e45ed 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -230,6 +230,8 @@ namespace OpenSim.Region.Framework.Scenes
230 public bool m_seeIntoBannedRegion = false; 230 public bool m_seeIntoBannedRegion = false;
231 public int MaxUndoCount = 5; 231 public int MaxUndoCount = 5;
232 232
233 public bool SeeIntoRegion { get; set; }
234
233 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 235 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
234 public bool LoginLock = false; 236 public bool LoginLock = false;
235 237
@@ -861,9 +863,11 @@ namespace OpenSim.Region.Framework.Scenes
861 //Animation states 863 //Animation states
862 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 864 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
863 865
866
867 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
868
864 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 869 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
865 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 870 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
866
867 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); 871 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
868 if (RegionInfo.NonphysPrimMin > 0) 872 if (RegionInfo.NonphysPrimMin > 0)
869 { 873 {
@@ -3910,15 +3914,10 @@ namespace OpenSim.Region.Framework.Scenes
3910 3914
3911 try 3915 try
3912 { 3916 {
3913 // Always check estate if this is a login. Always 3917 if (!AuthorizeUser(agent, SeeIntoRegion, out reason))
3914 // check if banned regions are to be blacked out.
3915 if (vialogin || (!m_seeIntoBannedRegion))
3916 { 3918 {
3917 if (!AuthorizeUser(agent, out reason)) 3919 m_authenticateHandler.RemoveCircuit(agent.circuitcode);
3918 { 3920 return false;
3919 m_authenticateHandler.RemoveCircuit(agent.circuitcode);
3920 return false;
3921 }
3922 } 3921 }
3923 } 3922 }
3924 catch (Exception e) 3923 catch (Exception e)
@@ -4158,7 +4157,7 @@ namespace OpenSim.Region.Framework.Scenes
4158 /// <param name="reason">outputs the reason to this string</param> 4157 /// <param name="reason">outputs the reason to this string</param>
4159 /// <returns>True if the region accepts this agent. False if it does not. False will 4158 /// <returns>True if the region accepts this agent. False if it does not. False will
4160 /// also return a reason.</returns> 4159 /// also return a reason.</returns>
4161 protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason) 4160 protected virtual bool AuthorizeUser(AgentCircuitData agent, bool bypassAccessControl, out string reason)
4162 { 4161 {
4163 reason = String.Empty; 4162 reason = String.Empty;
4164 4163
@@ -4193,51 +4192,58 @@ namespace OpenSim.Region.Framework.Scenes
4193 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!"); 4192 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
4194 } 4193 }
4195 4194
4196 List<UUID> agentGroups = new List<UUID>(); 4195 // We only test the things below when we want to cut off
4197 4196 // child agents from being present in the scene for which their root
4198 if (m_groupsModule != null) 4197 // agent isn't allowed. Otherwise, we allow child agents. The test for
4198 // the root is done elsewhere (QueryAccess)
4199 if (!bypassAccessControl)
4199 { 4200 {
4200 GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID); 4201 List<UUID> agentGroups = new List<UUID>();
4201 4202
4202 if (GroupMembership != null) 4203 if (m_groupsModule != null)
4203 { 4204 {
4204 for (int i = 0; i < GroupMembership.Length; i++) 4205 GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID);
4205 agentGroups.Add(GroupMembership[i].GroupID); 4206
4206 } 4207 if (GroupMembership != null)
4207 else 4208 {
4208 { 4209 for (int i = 0; i < GroupMembership.Length; i++)
4209 m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!"); 4210 agentGroups.Add(GroupMembership[i].GroupID);
4211 }
4212 else
4213 {
4214 m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!");
4215 }
4210 } 4216 }
4211 }
4212 4217
4213 bool groupAccess = false; 4218 bool groupAccess = false;
4214 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups; 4219 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups;
4215 4220
4216 if (estateGroups != null) 4221 if (estateGroups != null)
4217 {
4218 foreach (UUID group in estateGroups)
4219 { 4222 {
4220 if (agentGroups.Contains(group)) 4223 foreach (UUID group in estateGroups)
4221 { 4224 {
4222 groupAccess = true; 4225 if (agentGroups.Contains(group))
4223 break; 4226 {
4227 groupAccess = true;
4228 break;
4229 }
4224 } 4230 }
4225 } 4231 }
4226 } 4232 else
4227 else 4233 {
4228 { 4234 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
4229 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); 4235 }
4230 }
4231 4236
4232 if (!RegionInfo.EstateSettings.PublicAccess && 4237 if (!RegionInfo.EstateSettings.PublicAccess &&
4233 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && 4238 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) &&
4234 !groupAccess) 4239 !groupAccess)
4235 { 4240 {
4236 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", 4241 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
4237 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 4242 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4238 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", 4243 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
4239 RegionInfo.RegionName); 4244 RegionInfo.RegionName);
4240 return false; 4245 return false;
4246 }
4241 } 4247 }
4242 4248
4243 // TODO: estate/region settings are not properly hooked up 4249 // TODO: estate/region settings are not properly hooked up
@@ -4402,6 +4408,20 @@ namespace OpenSim.Region.Framework.Scenes
4402 } 4408 }
4403 4409
4404 childAgentUpdate.ChildAgentDataUpdate(cAgentData); 4410 childAgentUpdate.ChildAgentDataUpdate(cAgentData);
4411
4412 int ntimes = 20;
4413 if (cAgentData.SenderWantsToWaitForRoot)
4414 {
4415 while (childAgentUpdate.IsChildAgent && ntimes-- > 0)
4416 Thread.Sleep(1000);
4417
4418 m_log.DebugFormat(
4419 "[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits",
4420 childAgentUpdate.Name, childAgentUpdate.UUID, childAgentUpdate.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 20 - ntimes);
4421
4422 if (childAgentUpdate.IsChildAgent)
4423 return false;
4424 }
4405 return true; 4425 return true;
4406 } 4426 }
4407 return false; 4427 return false;
@@ -4459,10 +4479,6 @@ namespace OpenSim.Region.Framework.Scenes
4459 m_log.WarnFormat( 4479 m_log.WarnFormat(
4460 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", 4480 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4461 agentID, RegionInfo.RegionName); 4481 agentID, RegionInfo.RegionName);
4462// else
4463// m_log.DebugFormat(
4464// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
4465// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes);
4466 4482
4467 return sp; 4483 return sp;
4468 } 4484 }
@@ -5873,7 +5889,7 @@ Environment.Exit(1);
5873 5889
5874 try 5890 try
5875 { 5891 {
5876 if (!AuthorizeUser(aCircuit, out reason)) 5892 if (!AuthorizeUser(aCircuit, false, out reason))
5877 { 5893 {
5878 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); 5894 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5879 return false; 5895 return false;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1225c2e..c78fe62 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -29,7 +29,9 @@ using System;
29using System.Xml; 29using System.Xml;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using System.Threading;
32using System.Timers; 33using System.Timers;
34using Timer = System.Timers.Timer;
33using OpenMetaverse; 35using OpenMetaverse;
34using log4net; 36using log4net;
35using Nini.Config; 37using Nini.Config;
@@ -1154,9 +1156,8 @@ namespace OpenSim.Region.Framework.Scenes
1154 1156
1155 MovementFlag = 0; 1157 MovementFlag = 0;
1156 1158
1157 // DIVA NOTE: I moved TriggerOnMakeRootAgent out of here and into the end of 1159 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1158 // CompleteMovement. We don't want modules doing heavy computation before CompleteMovement 1160
1159 // is over.
1160 } 1161 }
1161 1162
1162 public int GetStateSource() 1163 public int GetStateSource()
@@ -1502,6 +1503,26 @@ namespace OpenSim.Region.Framework.Scenes
1502 1503
1503 } 1504 }
1504 1505
1506 private bool WaitForUpdateAgent(IClientAPI client)
1507 {
1508 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero
1509 int count = 20;
1510 while (m_originRegionID.Equals(UUID.Zero) && count-- > 0)
1511 {
1512 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.RegionInfo.RegionName);
1513 Thread.Sleep(200);
1514 }
1515
1516 if (m_originRegionID.Equals(UUID.Zero))
1517 {
1518 // Movement into region will fail
1519 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived", client.Name);
1520 return false;
1521 }
1522
1523 return true;
1524 }
1525
1505 /// <summary> 1526 /// <summary>
1506 /// Complete Avatar's movement into the region. 1527 /// Complete Avatar's movement into the region.
1507 /// </summary> 1528 /// </summary>
@@ -1519,6 +1540,13 @@ namespace OpenSim.Region.Framework.Scenes
1519 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", 1540 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
1520 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); 1541 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
1521 1542
1543 // Make sure it's not a login agent. We don't want to wait for updates during login
1544 if ((m_teleportFlags & TeleportFlags.ViaLogin) == 0)
1545 // Let's wait until UpdateAgent (called by departing region) is done
1546 if (!WaitForUpdateAgent(client))
1547 // The sending region never sent the UpdateAgent data, we have to refuse
1548 return;
1549
1522 Vector3 look = Velocity; 1550 Vector3 look = Velocity;
1523 1551
1524 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1552 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
@@ -1540,10 +1568,11 @@ namespace OpenSim.Region.Framework.Scenes
1540 1568
1541 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1569 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1542 MakeRootAgent(AbsolutePosition, flying); 1570 MakeRootAgent(AbsolutePosition, flying);
1571
1572 // Tell the client that we're totally ready
1543 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1573 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1574
1544 // Remember in HandleUseCircuitCode, we delayed this to here 1575 // Remember in HandleUseCircuitCode, we delayed this to here
1545 // This will also send the initial data to clients when TP to a neighboring region.
1546 // Not ideal, but until we know we're TP-ing from a neighboring region, there's not much we can do
1547 if (m_teleportFlags > 0) 1576 if (m_teleportFlags > 0)
1548 SendInitialDataToMe(); 1577 SendInitialDataToMe();
1549 1578
@@ -1600,10 +1629,6 @@ namespace OpenSim.Region.Framework.Scenes
1600// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1629// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1601// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 1630// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
1602 1631
1603 // DIVA NOTE: moved this here from MakeRoot. We don't want modules making heavy
1604 // computations before CompleteMovement is over
1605 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1606
1607 } 1632 }
1608 1633
1609 /// <summary> 1634 /// <summary>
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 8055886..57bc79e 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -86,6 +86,13 @@
86 ;; from the selected region_info_source. 86 ;; from the selected region_info_source.
87 allow_regionless = false 87 allow_regionless = false
88 88
89 ;; Allow child agents to see into the region even if their root counterpart isn't allowed in here
90 see_into_region = true
91
92 ; Maximum number of position, rotation and scale changes for each prim that the simulator will store for later undos
93 ; Increasing this number will increase memory usage.
94 MaxPrimUndos = 20
95
89 ; Maximum size of non physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonPhysicalPrimMax!). 96 ; Maximum size of non physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonPhysicalPrimMax!).
90 NonPhysicalPrimMax = 256 97 NonPhysicalPrimMax = 256
91 98