aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs618
1 files changed, 394 insertions, 224 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 8034bc6..45d512b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -80,6 +80,11 @@ namespace OpenSim.Region.Framework.Scenes
80 public SynchronizeSceneHandler SynchronizeScene; 80 public SynchronizeSceneHandler SynchronizeScene;
81 81
82 /// <summary> 82 /// <summary>
83 /// Used to prevent simultaneous calls to RemoveClient() for the same agent from interfering with each other.
84 /// </summary>
85 private object m_removeClientLock = new object();
86
87 /// <summary>
83 /// Statistical information for this scene. 88 /// Statistical information for this scene.
84 /// </summary> 89 /// </summary>
85 public SimStatsReporter StatsReporter { get; private set; } 90 public SimStatsReporter StatsReporter { get; private set; }
@@ -103,8 +108,31 @@ namespace OpenSim.Region.Framework.Scenes
103 /// </summary> 108 /// </summary>
104 public bool CollidablePrims { get; private set; } 109 public bool CollidablePrims { get; private set; }
105 110
111 /// <summary>
112 /// Minimum value of the size of a non-physical prim in each axis
113 /// </summary>
114 public float m_minNonphys = 0.001f;
115
116 /// <summary>
117 /// Maximum value of the size of a non-physical prim in each axis
118 /// </summary>
106 public float m_maxNonphys = 256; 119 public float m_maxNonphys = 256;
120
121 /// <summary>
122 /// Minimum value of the size of a physical prim in each axis
123 /// </summary>
124 public float m_minPhys = 0.01f;
125
126 /// <summary>
127 /// Maximum value of the size of a physical prim in each axis
128 /// </summary>
107 public float m_maxPhys = 10; 129 public float m_maxPhys = 10;
130
131 /// <summary>
132 /// Max prims an object will hold
133 /// </summary>
134 public int m_linksetCapacity = 0;
135
108 public bool m_clampPrimSize; 136 public bool m_clampPrimSize;
109 public bool m_trustBinaries; 137 public bool m_trustBinaries;
110 public bool m_allowScriptCrossings; 138 public bool m_allowScriptCrossings;
@@ -285,6 +313,31 @@ namespace OpenSim.Region.Framework.Scenes
285 } 313 }
286 private volatile bool m_shuttingDown; 314 private volatile bool m_shuttingDown;
287 315
316 /// <summary>
317 /// Is the scene active?
318 /// </summary>
319 /// <remarks>
320 /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if
321 /// the scene is not active.
322 /// </remarks>
323 public bool Active
324 {
325 get { return m_active; }
326 set
327 {
328 if (value)
329 {
330 if (!m_active)
331 Start();
332 }
333 else
334 {
335 m_active = false;
336 }
337 }
338 }
339 private volatile bool m_active;
340
288// private int m_lastUpdate; 341// private int m_lastUpdate;
289 private bool m_firstHeartbeat = true; 342 private bool m_firstHeartbeat = true;
290 343
@@ -746,12 +799,24 @@ namespace OpenSim.Region.Framework.Scenes
746 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 799 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
747 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 800 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
748 801
749 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); 802 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
803 if (RegionInfo.NonphysPrimMin > 0)
804 {
805 m_minNonphys = RegionInfo.NonphysPrimMin;
806 }
807
808 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
750 if (RegionInfo.NonphysPrimMax > 0) 809 if (RegionInfo.NonphysPrimMax > 0)
751 { 810 {
752 m_maxNonphys = RegionInfo.NonphysPrimMax; 811 m_maxNonphys = RegionInfo.NonphysPrimMax;
753 } 812 }
754 813
814 m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
815 if (RegionInfo.PhysPrimMin > 0)
816 {
817 m_minPhys = RegionInfo.PhysPrimMin;
818 }
819
755 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); 820 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
756 821
757 if (RegionInfo.PhysPrimMax > 0) 822 if (RegionInfo.PhysPrimMax > 0)
@@ -759,6 +824,12 @@ namespace OpenSim.Region.Framework.Scenes
759 m_maxPhys = RegionInfo.PhysPrimMax; 824 m_maxPhys = RegionInfo.PhysPrimMax;
760 } 825 }
761 826
827 m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
828 if (RegionInfo.LinksetCapacity > 0)
829 {
830 m_linksetCapacity = RegionInfo.LinksetCapacity;
831 }
832
762 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); 833 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
763 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); 834 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
764 835
@@ -784,13 +855,6 @@ namespace OpenSim.Region.Framework.Scenes
784 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 855 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
785 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine); 856 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
786 857
787 IConfig packetConfig = m_config.Configs["PacketPool"];
788 if (packetConfig != null)
789 {
790 PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
791 PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
792 }
793
794 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 858 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
795 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion); 859 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
796 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); 860 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
@@ -854,6 +918,8 @@ namespace OpenSim.Region.Framework.Scenes
854 } 918 }
855 919
856 // FIXME: Ultimately this should be in a module. 920 // FIXME: Ultimately this should be in a module.
921 SendPeriodicAppearanceUpdates = true;
922
857 IConfig appearanceConfig = m_config.Configs["Appearance"]; 923 IConfig appearanceConfig = m_config.Configs["Appearance"];
858 if (appearanceConfig != null) 924 if (appearanceConfig != null)
859 { 925 {
@@ -1151,6 +1217,14 @@ namespace OpenSim.Region.Framework.Scenes
1151 1217
1152 public void SetSceneCoreDebug(Dictionary<string, string> options) 1218 public void SetSceneCoreDebug(Dictionary<string, string> options)
1153 { 1219 {
1220 if (options.ContainsKey("active"))
1221 {
1222 bool active;
1223
1224 if (bool.TryParse(options["active"], out active))
1225 Active = active;
1226 }
1227
1154 if (options.ContainsKey("scripting")) 1228 if (options.ContainsKey("scripting"))
1155 { 1229 {
1156 bool enableScripts = true; 1230 bool enableScripts = true;
@@ -1290,6 +1364,8 @@ namespace OpenSim.Region.Framework.Scenes
1290 /// </summary> 1364 /// </summary>
1291 public void Start() 1365 public void Start()
1292 { 1366 {
1367 m_active = true;
1368
1293// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1369// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1294 1370
1295 //m_heartbeatTimer.Enabled = true; 1371 //m_heartbeatTimer.Enabled = true;
@@ -1346,7 +1422,7 @@ namespace OpenSim.Region.Framework.Scenes
1346 #region Update Methods 1422 #region Update Methods
1347 1423
1348 /// <summary> 1424 /// <summary>
1349 /// Performs per-frame updates regularly 1425 /// Activate the various loops necessary to continually update the scene.
1350 /// </summary> 1426 /// </summary>
1351 private void Heartbeat() 1427 private void Heartbeat()
1352 { 1428 {
@@ -1403,7 +1479,7 @@ namespace OpenSim.Region.Framework.Scenes
1403 List<Vector3> coarseLocations; 1479 List<Vector3> coarseLocations;
1404 List<UUID> avatarUUIDs; 1480 List<UUID> avatarUUIDs;
1405 1481
1406 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) 1482 while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun))
1407 { 1483 {
1408 runtc = Util.EnvironmentTickCount(); 1484 runtc = Util.EnvironmentTickCount();
1409 ++MaintenanceRun; 1485 ++MaintenanceRun;
@@ -1465,7 +1541,7 @@ namespace OpenSim.Region.Framework.Scenes
1465 int sleepMS; 1541 int sleepMS;
1466 int framestart; 1542 int framestart;
1467 1543
1468 while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) 1544 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1469 { 1545 {
1470 framestart = Util.EnvironmentTickCount(); 1546 framestart = Util.EnvironmentTickCount();
1471 ++Frame; 1547 ++Frame;
@@ -2182,10 +2258,14 @@ namespace OpenSim.Region.Framework.Scenes
2182 public bool AddRestoredSceneObject( 2258 public bool AddRestoredSceneObject(
2183 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 2259 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
2184 { 2260 {
2185 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 2261 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2186 if (result) 2262 {
2187 sceneObject.IsDeleted = false; 2263 sceneObject.IsDeleted = false;
2188 return result; 2264 EventManager.TriggerObjectAddedToScene(sceneObject);
2265 return true;
2266 }
2267
2268 return false;
2189 } 2269 }
2190 2270
2191 /// <summary> 2271 /// <summary>
@@ -2826,77 +2906,89 @@ namespace OpenSim.Region.Framework.Scenes
2826 2906
2827 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2907 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2828 { 2908 {
2909 ScenePresence sp;
2910 bool vialogin;
2911
2829 // Validation occurs in LLUDPServer 2912 // Validation occurs in LLUDPServer
2913 //
2914 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with
2915 // each other. In practice, this does not currently occur in the code.
2830 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2916 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2831 2917
2832 bool vialogin 2918 // We lock here on AgentCircuitData to prevent a race condition between the thread adding a new connection
2833 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2919 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2834 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2920 // whilst connecting).
2835 2921 //
2836 CheckHeartbeat(); 2922 // It would be easier to lock across all NewUserConnection(), AddNewClient() and
2837 2923 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2838 ScenePresence sp = GetScenePresence(client.AgentId); 2924 // response in some module listening to AddNewClient()) from holding up unrelated agent calls.
2839 2925 //
2840 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2926 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2841 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2927 // AddNewClient() operations (though not other ops).
2842 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2928 // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved.
2843 // connected. 2929 lock (aCircuit)
2844 if (sp == null) 2930 {
2845 { 2931 vialogin
2846 m_log.DebugFormat( 2932 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2847 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2933 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2848 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2934
2849 2935 CheckHeartbeat();
2850 m_clientManager.Add(client); 2936
2851 SubscribeToClientEvents(client); 2937 sp = GetScenePresence(client.AgentId);
2852
2853 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2854 m_eventManager.TriggerOnNewPresence(sp);
2855
2856 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2857 2938
2858 // The first agent upon login is a root agent by design. 2939 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2859 // For this agent we will have to rez the attachments. 2940 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2860 // All other AddNewClient calls find aCircuit.child to be true. 2941 // other problems, and possible the code calling AddNewClient() should ensure that no client is already
2861 if (aCircuit.child == false) 2942 // connected.
2943 if (sp == null)
2862 { 2944 {
2863 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to 2945 m_log.DebugFormat(
2864 // start the scripts again (since this is done in RezAttachments()). 2946 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2865 // XXX: This is convoluted. 2947 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2866 sp.IsChildAgent = false; 2948
2867 2949 m_clientManager.Add(client);
2868 if (AttachmentsModule != null) 2950 SubscribeToClientEvents(client);
2869 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); 2951
2952 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2953 m_eventManager.TriggerOnNewPresence(sp);
2954
2955 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2956
2957 // The first agent upon login is a root agent by design.
2958 // For this agent we will have to rez the attachments.
2959 // All other AddNewClient calls find aCircuit.child to be true.
2960 if (aCircuit.child == false)
2961 {
2962 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to
2963 // start the scripts again (since this is done in RezAttachments()).
2964 // XXX: This is convoluted.
2965 sp.IsChildAgent = false;
2966
2967 if (AttachmentsModule != null)
2968 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2969 }
2870 } 2970 }
2871 } 2971 else
2872 else 2972 {
2873 { 2973 m_log.WarnFormat(
2874 m_log.WarnFormat( 2974 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2875 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2975 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2876 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2976 }
2877 } 2977
2978 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2979 // client is for a root or child agent.
2980 client.SceneAgent = sp;
2878 2981
2879 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 2982 // Cache the user's name
2880 // client is for a root or child agent. 2983 CacheUserName(sp, aCircuit);
2881 client.SceneAgent = sp; 2984
2985 EventManager.TriggerOnNewClient(client);
2986 if (vialogin)
2987 EventManager.TriggerOnClientLogin(client);
2988 }
2882 2989
2883 m_LastLogin = Util.EnvironmentTickCount(); 2990 m_LastLogin = Util.EnvironmentTickCount();
2884 2991
2885 // Cache the user's name
2886 CacheUserName(sp, aCircuit);
2887
2888 EventManager.TriggerOnNewClient(client);
2889 if (vialogin)
2890 {
2891 EventManager.TriggerOnClientLogin(client);
2892 // Send initial parcel data
2893/* this is done on TriggerOnNewClient by landmanegement respective event handler
2894 Vector3 pos = sp.AbsolutePosition;
2895 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2896 land.SendLandUpdateToClient(client);
2897*/
2898 }
2899
2900 return sp; 2992 return sp;
2901 } 2993 }
2902 2994
@@ -3436,110 +3528,130 @@ namespace OpenSim.Region.Framework.Scenes
3436 { 3528 {
3437// CheckHeartbeat(); 3529// CheckHeartbeat();
3438 bool isChildAgent = false; 3530 bool isChildAgent = false;
3439 ScenePresence avatar = GetScenePresence(agentID); 3531 AgentCircuitData acd;
3440
3441 if (avatar == null)
3442 {
3443 m_log.WarnFormat(
3444 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3445
3446 return;
3447 }
3448 3532
3449 try 3533 lock (m_removeClientLock)
3450 { 3534 {
3451 isChildAgent = avatar.IsChildAgent; 3535 acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3452
3453 m_log.DebugFormat(
3454 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3455 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3456 3536
3457 // Don't do this to root agents, it's not nice for the viewer 3537 if (acd == null)
3458 if (closeChildAgents && isChildAgent)
3459 { 3538 {
3460 // Tell a single agent to disconnect from the region. 3539 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
3461 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3540 return;
3462 if (eq != null)
3463 {
3464 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3465 }
3466 else
3467 {
3468 avatar.ControllingClient.SendShutdownConnectionNotice();
3469 }
3470 } 3541 }
3471 3542 else
3472 // Only applies to root agents.
3473 if (avatar.ParentID != 0)
3474 { 3543 {
3475 avatar.StandUp(); 3544 // We remove the acd up here to avoid later raec conditions if two RemoveClient() calls occurred
3545 // simultaneously.
3546 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3476 } 3547 }
3548 }
3477 3549
3478 m_sceneGraph.removeUserCount(!isChildAgent); 3550 lock (acd)
3479 3551 {
3480 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3552 ScenePresence avatar = GetScenePresence(agentID);
3481 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3553
3482 if (closeChildAgents && CapsModule != null) 3554 if (avatar == null)
3483 CapsModule.RemoveCaps(agentID);
3484
3485 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3486 // this method is doing is HORRIBLE!!!
3487 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3488
3489 if (closeChildAgents && !isChildAgent)
3490 { 3555 {
3491 List<ulong> regions = avatar.KnownRegionHandles; 3556 m_log.WarnFormat(
3492 regions.Remove(RegionInfo.RegionHandle); 3557 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3493 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3558
3559 return;
3494 } 3560 }
3495 3561
3496 m_eventManager.TriggerClientClosed(agentID, this); 3562 try
3497 m_eventManager.TriggerOnRemovePresence(agentID);
3498
3499 if (!isChildAgent)
3500 { 3563 {
3501 if (AttachmentsModule != null) 3564 isChildAgent = avatar.IsChildAgent;
3565
3566 m_log.DebugFormat(
3567 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3568 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3569
3570 // Don't do this to root agents, it's not nice for the viewer
3571 if (closeChildAgents && isChildAgent)
3502 { 3572 {
3503 AttachmentsModule.DeRezAttachments(avatar); 3573 // Tell a single agent to disconnect from the region.
3574 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3575 if (eq != null)
3576 {
3577 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3578 }
3579 else
3580 {
3581 avatar.ControllingClient.SendShutdownConnectionNotice();
3582 }
3504 } 3583 }
3505 3584
3506 ForEachClient( 3585 // Only applies to root agents.
3507 delegate(IClientAPI client) 3586 if (avatar.ParentID != 0)
3587 {
3588 avatar.StandUp();
3589 }
3590
3591 m_sceneGraph.removeUserCount(!isChildAgent);
3592
3593 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3594 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3595 if (closeChildAgents && CapsModule != null)
3596 CapsModule.RemoveCaps(agentID);
3597
3598 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3599 // this method is doing is HORRIBLE!!!
3600 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3601
3602 if (closeChildAgents && !isChildAgent)
3603 {
3604 List<ulong> regions = avatar.KnownRegionHandles;
3605 regions.Remove(RegionInfo.RegionHandle);
3606 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3607 }
3608
3609 m_eventManager.TriggerClientClosed(agentID, this);
3610 m_eventManager.TriggerOnRemovePresence(agentID);
3611
3612 if (!isChildAgent)
3613 {
3614 if (AttachmentsModule != null)
3508 { 3615 {
3509 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3616 AttachmentsModule.DeRezAttachments(avatar);
3510 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3617 }
3511 catch (NullReferenceException) { }
3512 });
3513 }
3514
3515 // It's possible for child agents to have transactions if changes are being made cross-border.
3516 if (AgentTransactionsModule != null)
3517 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3518 3618
3519 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3619 ForEachClient(
3520 m_log.Debug("[Scene] The avatar has left the building"); 3620 delegate(IClientAPI client)
3521 } 3621 {
3522 catch (Exception e) 3622 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3523 { 3623 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3524 m_log.Error( 3624 catch (NullReferenceException) { }
3525 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); 3625 });
3526 } 3626 }
3527 finally
3528 {
3529 try
3530 {
3531 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3532 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3533 // the same cleanup exception continually.
3534 m_sceneGraph.RemoveScenePresence(agentID);
3535 m_clientManager.Remove(agentID);
3536 3627
3537 avatar.Close(); 3628 // It's possible for child agents to have transactions if changes are being made cross-border.
3629 if (AgentTransactionsModule != null)
3630 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3631 m_log.Debug("[Scene] The avatar has left the building");
3538 } 3632 }
3539 catch (Exception e) 3633 catch (Exception e)
3540 { 3634 {
3541 m_log.Error( 3635 m_log.Error(
3542 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); 3636 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3637 }
3638 finally
3639 {
3640 try
3641 {
3642 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3643 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3644 // the same cleanup exception continually.
3645 m_sceneGraph.RemoveScenePresence(agentID);
3646 m_clientManager.Remove(agentID);
3647
3648 avatar.Close();
3649 }
3650 catch (Exception e)
3651 {
3652 m_log.Error(
3653 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3654 }
3543 } 3655 }
3544 } 3656 }
3545 3657
@@ -3598,11 +3710,9 @@ namespace OpenSim.Region.Framework.Scenes
3598 3710
3599 /// <summary> 3711 /// <summary>
3600 /// Do the work necessary to initiate a new user connection for a particular scene. 3712 /// Do the work necessary to initiate a new user connection for a particular scene.
3601 /// At the moment, this consists of setting up the caps infrastructure
3602 /// The return bool should allow for connections to be refused, but as not all calling paths
3603 /// take proper notice of it let, we allowed banned users in still.
3604 /// </summary> 3713 /// </summary>
3605 /// <param name="agent">CircuitData of the agent who is connecting</param> 3714 /// <param name="agent">CircuitData of the agent who is connecting</param>
3715 /// <param name="teleportFlags"></param>
3606 /// <param name="reason">Outputs the reason for the false response on this string</param> 3716 /// <param name="reason">Outputs the reason for the false response on this string</param>
3607 /// <returns>True if the region accepts this agent. False if it does not. False will 3717 /// <returns>True if the region accepts this agent. False if it does not. False will
3608 /// also return a reason.</returns> 3718 /// also return a reason.</returns>
@@ -3613,10 +3723,20 @@ namespace OpenSim.Region.Framework.Scenes
3613 3723
3614 /// <summary> 3724 /// <summary>
3615 /// Do the work necessary to initiate a new user connection for a particular scene. 3725 /// Do the work necessary to initiate a new user connection for a particular scene.
3616 /// At the moment, this consists of setting up the caps infrastructure 3726 /// </summary>
3727 /// <remarks>
3728 /// The return bool should allow for connections to be refused, but as not all calling paths
3729 /// take proper notice of it yet, we still allowed banned users in.
3730 ///
3731 /// At the moment this method consists of setting up the caps infrastructure
3617 /// The return bool should allow for connections to be refused, but as not all calling paths 3732 /// The return bool should allow for connections to be refused, but as not all calling paths
3618 /// take proper notice of it let, we allowed banned users in still. 3733 /// take proper notice of it let, we allowed banned users in still.
3619 /// </summary> 3734 ///
3735 /// This method is called by the login service (in the case of login) or another simulator (in the case of region
3736 /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection
3737 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3738 /// the LLUDP stack).
3739 /// </remarks>
3620 /// <param name="agent">CircuitData of the agent who is connecting</param> 3740 /// <param name="agent">CircuitData of the agent who is connecting</param>
3621 /// <param name="reason">Outputs the reason for the false response on this string</param> 3741 /// <param name="reason">Outputs the reason for the false response on this string</param>
3622 /// <param name="requirePresenceLookup">True for normal presence. False for NPC 3742 /// <param name="requirePresenceLookup">True for normal presence. False for NPC
@@ -3715,83 +3835,86 @@ namespace OpenSim.Region.Framework.Scenes
3715 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3835 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3716 sp.Name, sp.UUID, RegionInfo.RegionName); 3836 sp.Name, sp.UUID, RegionInfo.RegionName);
3717 3837
3718 sp.ControllingClient.Close(); 3838 sp.ControllingClient.Close(true, true);
3719 sp = null; 3839 sp = null;
3720 } 3840 }
3721 3841
3722 3842 lock (agent)
3723 //On login test land permisions
3724 if (vialogin)
3725 { 3843 {
3726 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3844 //On login test land permisions
3727 if (cache != null) 3845 if (vialogin)
3728 cache.Remove(agent.firstname + " " + agent.lastname);
3729 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3730 { 3846 {
3731 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3847 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3732 return false; 3848 if (cache != null)
3849 cache.Remove(agent.firstname + " " + agent.lastname);
3850 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3851 {
3852 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3853 return false;
3854 }
3733 } 3855 }
3734 }
3735 3856
3736 if (sp == null) // We don't have an [child] agent here already 3857 if (sp == null) // We don't have an [child] agent here already
3737 {
3738 if (requirePresenceLookup)
3739 { 3858 {
3740 try 3859 if (requirePresenceLookup)
3741 { 3860 {
3742 if (!VerifyUserPresence(agent, out reason)) 3861 try
3862 {
3863 if (!VerifyUserPresence(agent, out reason))
3864 return false;
3865 } catch (Exception e)
3866 {
3867 m_log.ErrorFormat(
3868 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3743 return false; 3869 return false;
3744 } catch (Exception e) 3870 }
3871 }
3872
3873 try
3874 {
3875 // Always check estate if this is a login. Always
3876 // check if banned regions are to be blacked out.
3877 if (vialogin || (!m_seeIntoBannedRegion))
3878 {
3879 if (!AuthorizeUser(agent, out reason))
3880 return false;
3881 }
3882 }
3883 catch (Exception e)
3745 { 3884 {
3746 m_log.ErrorFormat( 3885 m_log.ErrorFormat(
3747 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3886 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3748 return false; 3887 return false;
3749 } 3888 }
3750 }
3751 3889
3752 try 3890 m_log.InfoFormat(
3753 { 3891 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3754 // Always check estate if this is a login. Always 3892 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3755 // check if banned regions are to be blacked out. 3893 agent.AgentID, agent.circuitcode);
3756 if (vialogin || (!m_seeIntoBannedRegion)) 3894
3895 if (CapsModule != null)
3757 { 3896 {
3758 if (!AuthorizeUser(agent, out reason)) 3897 CapsModule.SetAgentCapsSeeds(agent);
3759 return false; 3898 CapsModule.CreateCaps(agent.AgentID);
3760 } 3899 }
3761 } 3900 }
3762 catch (Exception e) 3901 else
3763 { 3902 {
3764 m_log.ErrorFormat( 3903 // Let the SP know how we got here. This has a lot of interesting
3765 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 3904 // uses down the line.
3766 return false; 3905 sp.TeleportFlags = (TPFlags)teleportFlags;
3767 }
3768
3769 m_log.InfoFormat(
3770 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3771 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3772 agent.AgentID, agent.circuitcode);
3773 3906
3774 if (CapsModule != null) 3907 if (sp.IsChildAgent)
3775 { 3908 {
3776 CapsModule.SetAgentCapsSeeds(agent); 3909 m_log.DebugFormat(
3777 CapsModule.CreateCaps(agent.AgentID); 3910 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3778 } 3911 agent.AgentID, RegionInfo.RegionName);
3779 } else
3780 {
3781 // Let the SP know how we got here. This has a lot of interesting
3782 // uses down the line.
3783 sp.TeleportFlags = (TPFlags)teleportFlags;
3784 3912
3785 if (sp.IsChildAgent) 3913 sp.AdjustKnownSeeds();
3786 {
3787 m_log.DebugFormat(
3788 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3789 agent.AgentID, RegionInfo.RegionName);
3790 3914
3791 sp.AdjustKnownSeeds(); 3915 if (CapsModule != null)
3792 3916 CapsModule.SetAgentCapsSeeds(agent);
3793 if (CapsModule != null) 3917 }
3794 CapsModule.SetAgentCapsSeeds(agent);
3795 } 3918 }
3796 } 3919 }
3797 3920
@@ -4222,8 +4345,9 @@ namespace OpenSim.Region.Framework.Scenes
4222 return false; 4345 return false;
4223 } 4346 }
4224 4347
4225 // We have to wait until the viewer contacts this region after receiving EAC. 4348 // We have to wait until the viewer contacts this region
4226 // That calls AddNewClient, which finally creates the ScenePresence 4349 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send
4350 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4227 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4351 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4228 4352
4229 if (childAgentUpdate != null) 4353 if (childAgentUpdate != null)
@@ -4318,15 +4442,18 @@ namespace OpenSim.Region.Framework.Scenes
4318 /// Tell a single agent to disconnect from the region. 4442 /// Tell a single agent to disconnect from the region.
4319 /// </summary> 4443 /// </summary>
4320 /// <param name="agentID"></param> 4444 /// <param name="agentID"></param>
4321 /// <param name="childOnly"></param> 4445 /// <param name="force">
4322 public bool IncomingCloseAgent(UUID agentID, bool childOnly) 4446 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4447 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4448 /// </param>
4449 public bool IncomingCloseAgent(UUID agentID, bool force)
4323 { 4450 {
4324 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4451 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4325 4452
4326 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4453 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4327 if (presence != null) 4454 if (presence != null)
4328 { 4455 {
4329 presence.ControllingClient.Close(false); 4456 presence.ControllingClient.Close(force, force);
4330 return true; 4457 return true;
4331 } 4458 }
4332 4459
@@ -4532,6 +4659,16 @@ namespace OpenSim.Region.Framework.Scenes
4532 return LandChannel.GetLandObject(x, y).LandData; 4659 return LandChannel.GetLandObject(x, y).LandData;
4533 } 4660 }
4534 4661
4662 /// <summary>
4663 /// Get LandData by position.
4664 /// </summary>
4665 /// <param name="pos"></param>
4666 /// <returns></returns>
4667 public LandData GetLandData(Vector3 pos)
4668 {
4669 return GetLandData(pos.X, pos.Y);
4670 }
4671
4535 public LandData GetLandData(uint x, uint y) 4672 public LandData GetLandData(uint x, uint y)
4536 { 4673 {
4537 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); 4674 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
@@ -4780,6 +4917,18 @@ namespace OpenSim.Region.Framework.Scenes
4780 } 4917 }
4781 4918
4782 /// <summary> 4919 /// <summary>
4920 /// Attempt to get the SOG via its UUID
4921 /// </summary>
4922 /// <param name="fullID"></param>
4923 /// <param name="sog"></param>
4924 /// <returns></returns>
4925 public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
4926 {
4927 sog = GetSceneObjectGroup(fullID);
4928 return sog != null;
4929 }
4930
4931 /// <summary>
4783 /// Get a prim by name from the scene (will return the first 4932 /// Get a prim by name from the scene (will return the first
4784 /// found, if there are more than one prim with the same name) 4933 /// found, if there are more than one prim with the same name)
4785 /// </summary> 4934 /// </summary>
@@ -4811,6 +4960,18 @@ namespace OpenSim.Region.Framework.Scenes
4811 } 4960 }
4812 4961
4813 /// <summary> 4962 /// <summary>
4963 /// Attempt to get a prim via its UUID
4964 /// </summary>
4965 /// <param name="fullID"></param>
4966 /// <param name="sop"></param>
4967 /// <returns></returns>
4968 public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
4969 {
4970 sop = GetSceneObjectPart(fullID);
4971 return sop != null;
4972 }
4973
4974 /// <summary>
4814 /// Get a scene object group that contains the prim with the given local id 4975 /// Get a scene object group that contains the prim with the given local id
4815 /// </summary> 4976 /// </summary>
4816 /// <param name="localID"></param> 4977 /// <param name="localID"></param>
@@ -5865,6 +6026,9 @@ Environment.Exit(1);
5865 6026
5866 public string GetExtraSetting(string name) 6027 public string GetExtraSetting(string name)
5867 { 6028 {
6029 if (m_extraSettings == null)
6030 return String.Empty;
6031
5868 string val; 6032 string val;
5869 6033
5870 if (!m_extraSettings.TryGetValue(name, out val)) 6034 if (!m_extraSettings.TryGetValue(name, out val))
@@ -5875,6 +6039,9 @@ Environment.Exit(1);
5875 6039
5876 public void StoreExtraSetting(string name, string val) 6040 public void StoreExtraSetting(string name, string val)
5877 { 6041 {
6042 if (m_extraSettings == null)
6043 return;
6044
5878 string oldVal; 6045 string oldVal;
5879 6046
5880 if (m_extraSettings.TryGetValue(name, out oldVal)) 6047 if (m_extraSettings.TryGetValue(name, out oldVal))
@@ -5892,6 +6059,9 @@ Environment.Exit(1);
5892 6059
5893 public void RemoveExtraSetting(string name) 6060 public void RemoveExtraSetting(string name)
5894 { 6061 {
6062 if (m_extraSettings == null)
6063 return;
6064
5895 if (!m_extraSettings.ContainsKey(name)) 6065 if (!m_extraSettings.ContainsKey(name))
5896 return; 6066 return;
5897 6067