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.cs689
1 files changed, 441 insertions, 248 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 649d545..80d9f6e 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;
@@ -149,7 +177,6 @@ namespace OpenSim.Region.Framework.Scenes
149 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 177 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
150 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 178 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
151 protected string m_simulatorVersion = "OpenSimulator Server"; 179 protected string m_simulatorVersion = "OpenSimulator Server";
152 protected ModuleLoader m_moduleLoader;
153 protected AgentCircuitManager m_authenticateHandler; 180 protected AgentCircuitManager m_authenticateHandler;
154 protected SceneCommunicationService m_sceneGridService; 181 protected SceneCommunicationService m_sceneGridService;
155 protected ISnmpModule m_snmpService = null; 182 protected ISnmpModule m_snmpService = null;
@@ -285,6 +312,31 @@ namespace OpenSim.Region.Framework.Scenes
285 } 312 }
286 private volatile bool m_shuttingDown; 313 private volatile bool m_shuttingDown;
287 314
315 /// <summary>
316 /// Is the scene active?
317 /// </summary>
318 /// <remarks>
319 /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if
320 /// the scene is not active.
321 /// </remarks>
322 public bool Active
323 {
324 get { return m_active; }
325 set
326 {
327 if (value)
328 {
329 if (!m_active)
330 Start();
331 }
332 else
333 {
334 m_active = false;
335 }
336 }
337 }
338 private volatile bool m_active;
339
288// private int m_lastUpdate; 340// private int m_lastUpdate;
289 private bool m_firstHeartbeat = true; 341 private bool m_firstHeartbeat = true;
290 342
@@ -626,7 +678,7 @@ namespace OpenSim.Region.Framework.Scenes
626 public Scene(RegionInfo regInfo, AgentCircuitManager authen, 678 public Scene(RegionInfo regInfo, AgentCircuitManager authen,
627 SceneCommunicationService sceneGridService, 679 SceneCommunicationService sceneGridService,
628 ISimulationDataService simDataService, IEstateDataService estateDataService, 680 ISimulationDataService simDataService, IEstateDataService estateDataService,
629 ModuleLoader moduleLoader, bool dumpAssetsToFile, 681 bool dumpAssetsToFile,
630 IConfigSource config, string simulatorVersion) 682 IConfigSource config, string simulatorVersion)
631 : this(regInfo) 683 : this(regInfo)
632 { 684 {
@@ -637,7 +689,6 @@ namespace OpenSim.Region.Framework.Scenes
637 Random random = new Random(); 689 Random random = new Random();
638 690
639 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4); 691 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4);
640 m_moduleLoader = moduleLoader;
641 m_authenticateHandler = authen; 692 m_authenticateHandler = authen;
642 m_sceneGridService = sceneGridService; 693 m_sceneGridService = sceneGridService;
643 m_SimulationDataService = simDataService; 694 m_SimulationDataService = simDataService;
@@ -746,12 +797,24 @@ namespace OpenSim.Region.Framework.Scenes
746 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 797 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
747 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 798 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
748 799
749 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); 800 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
801 if (RegionInfo.NonphysPrimMin > 0)
802 {
803 m_minNonphys = RegionInfo.NonphysPrimMin;
804 }
805
806 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
750 if (RegionInfo.NonphysPrimMax > 0) 807 if (RegionInfo.NonphysPrimMax > 0)
751 { 808 {
752 m_maxNonphys = RegionInfo.NonphysPrimMax; 809 m_maxNonphys = RegionInfo.NonphysPrimMax;
753 } 810 }
754 811
812 m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
813 if (RegionInfo.PhysPrimMin > 0)
814 {
815 m_minPhys = RegionInfo.PhysPrimMin;
816 }
817
755 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); 818 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
756 819
757 if (RegionInfo.PhysPrimMax > 0) 820 if (RegionInfo.PhysPrimMax > 0)
@@ -759,6 +822,12 @@ namespace OpenSim.Region.Framework.Scenes
759 m_maxPhys = RegionInfo.PhysPrimMax; 822 m_maxPhys = RegionInfo.PhysPrimMax;
760 } 823 }
761 824
825 m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
826 if (RegionInfo.LinksetCapacity > 0)
827 {
828 m_linksetCapacity = RegionInfo.LinksetCapacity;
829 }
830
762 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); 831 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
763 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); 832 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
764 833
@@ -784,13 +853,6 @@ namespace OpenSim.Region.Framework.Scenes
784 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 853 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
785 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine); 854 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
786 855
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); 856 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
795 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion); 857 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
796 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); 858 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
@@ -854,6 +916,8 @@ namespace OpenSim.Region.Framework.Scenes
854 } 916 }
855 917
856 // FIXME: Ultimately this should be in a module. 918 // FIXME: Ultimately this should be in a module.
919 SendPeriodicAppearanceUpdates = true;
920
857 IConfig appearanceConfig = m_config.Configs["Appearance"]; 921 IConfig appearanceConfig = m_config.Configs["Appearance"];
858 if (appearanceConfig != null) 922 if (appearanceConfig != null)
859 { 923 {
@@ -1151,6 +1215,14 @@ namespace OpenSim.Region.Framework.Scenes
1151 1215
1152 public void SetSceneCoreDebug(Dictionary<string, string> options) 1216 public void SetSceneCoreDebug(Dictionary<string, string> options)
1153 { 1217 {
1218 if (options.ContainsKey("active"))
1219 {
1220 bool active;
1221
1222 if (bool.TryParse(options["active"], out active))
1223 Active = active;
1224 }
1225
1154 if (options.ContainsKey("scripting")) 1226 if (options.ContainsKey("scripting"))
1155 { 1227 {
1156 bool enableScripts = true; 1228 bool enableScripts = true;
@@ -1226,6 +1298,12 @@ namespace OpenSim.Region.Framework.Scenes
1226 // This is the method that shuts down the scene. 1298 // This is the method that shuts down the scene.
1227 public override void Close() 1299 public override void Close()
1228 { 1300 {
1301 if (m_shuttingDown)
1302 {
1303 m_log.WarnFormat("[SCENE]: Ignoring close request because already closing {0}", Name);
1304 return;
1305 }
1306
1229 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); 1307 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
1230 1308
1231 StatsReporter.Close(); 1309 StatsReporter.Close();
@@ -1272,6 +1350,14 @@ namespace OpenSim.Region.Framework.Scenes
1272 m_log.Debug("[SCENE]: Graph close"); 1350 m_log.Debug("[SCENE]: Graph close");
1273 m_sceneGraph.Close(); 1351 m_sceneGraph.Close();
1274 1352
1353 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1354 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1355
1356 base.Close();
1357
1358 // XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence.
1359 // Therefore. we must dispose of the PhysicsScene after this to prevent a window where script code can
1360 // attempt to reference a null or disposed physics scene.
1275 if (PhysicsScene != null) 1361 if (PhysicsScene != null)
1276 { 1362 {
1277 m_log.Debug("[SCENE]: Dispose Physics"); 1363 m_log.Debug("[SCENE]: Dispose Physics");
@@ -1281,13 +1367,6 @@ namespace OpenSim.Region.Framework.Scenes
1281 phys.Dispose(); 1367 phys.Dispose();
1282 phys = null; 1368 phys = null;
1283 } 1369 }
1284
1285 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1286 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1287
1288 // call the base class Close method.
1289 m_log.Debug("[SCENE]: Base close");
1290 base.Close();
1291 } 1370 }
1292 1371
1293 /// <summary> 1372 /// <summary>
@@ -1295,6 +1374,8 @@ namespace OpenSim.Region.Framework.Scenes
1295 /// </summary> 1374 /// </summary>
1296 public void Start() 1375 public void Start()
1297 { 1376 {
1377 m_active = true;
1378
1298// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1379// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1299 1380
1300 //m_heartbeatTimer.Enabled = true; 1381 //m_heartbeatTimer.Enabled = true;
@@ -1354,7 +1435,7 @@ namespace OpenSim.Region.Framework.Scenes
1354 #region Update Methods 1435 #region Update Methods
1355 1436
1356 /// <summary> 1437 /// <summary>
1357 /// Performs per-frame updates regularly 1438 /// Activate the various loops necessary to continually update the scene.
1358 /// </summary> 1439 /// </summary>
1359 private void Heartbeat() 1440 private void Heartbeat()
1360 { 1441 {
@@ -1411,7 +1492,7 @@ namespace OpenSim.Region.Framework.Scenes
1411 List<Vector3> coarseLocations; 1492 List<Vector3> coarseLocations;
1412 List<UUID> avatarUUIDs; 1493 List<UUID> avatarUUIDs;
1413 1494
1414 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) 1495 while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun))
1415 { 1496 {
1416 runtc = Util.EnvironmentTickCount(); 1497 runtc = Util.EnvironmentTickCount();
1417 ++MaintenanceRun; 1498 ++MaintenanceRun;
@@ -1473,7 +1554,7 @@ namespace OpenSim.Region.Framework.Scenes
1473 int sleepMS; 1554 int sleepMS;
1474 int framestart; 1555 int framestart;
1475 1556
1476 while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) 1557 while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1477 { 1558 {
1478 framestart = Util.EnvironmentTickCount(); 1559 framestart = Util.EnvironmentTickCount();
1479 ++Frame; 1560 ++Frame;
@@ -1672,15 +1753,19 @@ namespace OpenSim.Region.Framework.Scenes
1672 1753
1673 private void CheckAtTargets() 1754 private void CheckAtTargets()
1674 { 1755 {
1675 List<SceneObjectGroup> objs = new List<SceneObjectGroup>(); 1756 List<SceneObjectGroup> objs = null;
1757
1676 lock (m_groupsWithTargets) 1758 lock (m_groupsWithTargets)
1677 { 1759 {
1678 foreach (SceneObjectGroup grp in m_groupsWithTargets.Values) 1760 if (m_groupsWithTargets.Count != 0)
1679 objs.Add(grp); 1761 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1680 } 1762 }
1681 1763
1682 foreach (SceneObjectGroup entry in objs) 1764 if (objs != null)
1683 entry.checkAtTargets(); 1765 {
1766 foreach (SceneObjectGroup entry in objs)
1767 entry.checkAtTargets();
1768 }
1684 } 1769 }
1685 1770
1686 /// <summary> 1771 /// <summary>
@@ -2193,10 +2278,14 @@ namespace OpenSim.Region.Framework.Scenes
2193 public bool AddRestoredSceneObject( 2278 public bool AddRestoredSceneObject(
2194 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 2279 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
2195 { 2280 {
2196 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 2281 if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2197 if (result) 2282 {
2198 sceneObject.IsDeleted = false; 2283 sceneObject.IsDeleted = false;
2199 return result; 2284 EventManager.TriggerObjectAddedToScene(sceneObject);
2285 return true;
2286 }
2287
2288 return false;
2200 } 2289 }
2201 2290
2202 /// <summary> 2291 /// <summary>
@@ -2837,77 +2926,89 @@ namespace OpenSim.Region.Framework.Scenes
2837 2926
2838 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2927 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2839 { 2928 {
2929 ScenePresence sp;
2930 bool vialogin;
2931
2840 // Validation occurs in LLUDPServer 2932 // Validation occurs in LLUDPServer
2933 //
2934 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with
2935 // each other. In practice, this does not currently occur in the code.
2841 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2936 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2842 2937
2843 bool vialogin 2938 // We lock here on AgentCircuitData to prevent a race condition between the thread adding a new connection
2844 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2939 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2845 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2940 // whilst connecting).
2846 2941 //
2847 CheckHeartbeat(); 2942 // It would be easier to lock across all NewUserConnection(), AddNewClient() and
2848 2943 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2849 ScenePresence sp = GetScenePresence(client.AgentId); 2944 // response in some module listening to AddNewClient()) from holding up unrelated agent calls.
2850 2945 //
2851 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2946 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2852 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2947 // AddNewClient() operations (though not other ops).
2853 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2948 // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved.
2854 // connected. 2949 lock (aCircuit)
2855 if (sp == null) 2950 {
2856 { 2951 vialogin
2857 m_log.DebugFormat( 2952 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2858 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2953 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2859 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2954
2860 2955 CheckHeartbeat();
2861 m_clientManager.Add(client); 2956
2862 SubscribeToClientEvents(client); 2957 sp = GetScenePresence(client.AgentId);
2863
2864 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2865 m_eventManager.TriggerOnNewPresence(sp);
2866
2867 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2868 2958
2869 // The first agent upon login is a root agent by design. 2959 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2870 // For this agent we will have to rez the attachments. 2960 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2871 // All other AddNewClient calls find aCircuit.child to be true. 2961 // other problems, and possible the code calling AddNewClient() should ensure that no client is already
2872 if (aCircuit.child == false) 2962 // connected.
2963 if (sp == null)
2873 { 2964 {
2874 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to 2965 m_log.DebugFormat(
2875 // start the scripts again (since this is done in RezAttachments()). 2966 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2876 // XXX: This is convoluted. 2967 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2877 sp.IsChildAgent = false; 2968
2878 2969 m_clientManager.Add(client);
2879 if (AttachmentsModule != null) 2970 SubscribeToClientEvents(client);
2880 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); 2971
2972 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2973 m_eventManager.TriggerOnNewPresence(sp);
2974
2975 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2976
2977 // The first agent upon login is a root agent by design.
2978 // For this agent we will have to rez the attachments.
2979 // All other AddNewClient calls find aCircuit.child to be true.
2980 if (aCircuit.child == false)
2981 {
2982 // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to
2983 // start the scripts again (since this is done in RezAttachments()).
2984 // XXX: This is convoluted.
2985 sp.IsChildAgent = false;
2986
2987 if (AttachmentsModule != null)
2988 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2989 }
2881 } 2990 }
2882 } 2991 else
2883 else 2992 {
2884 { 2993 m_log.WarnFormat(
2885 m_log.WarnFormat( 2994 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2886 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2995 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2887 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2996 }
2888 } 2997
2998 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2999 // client is for a root or child agent.
3000 client.SceneAgent = sp;
2889 3001
2890 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 3002 // Cache the user's name
2891 // client is for a root or child agent. 3003 CacheUserName(sp, aCircuit);
2892 client.SceneAgent = sp; 3004
3005 EventManager.TriggerOnNewClient(client);
3006 if (vialogin)
3007 EventManager.TriggerOnClientLogin(client);
3008 }
2893 3009
2894 m_LastLogin = Util.EnvironmentTickCount(); 3010 m_LastLogin = Util.EnvironmentTickCount();
2895 3011
2896 // Cache the user's name
2897 CacheUserName(sp, aCircuit);
2898
2899 EventManager.TriggerOnNewClient(client);
2900 if (vialogin)
2901 {
2902 EventManager.TriggerOnClientLogin(client);
2903 // Send initial parcel data
2904/* this is done on TriggerOnNewClient by landmanegement respective event handler
2905 Vector3 pos = sp.AbsolutePosition;
2906 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2907 land.SendLandUpdateToClient(client);
2908*/
2909 }
2910
2911 return sp; 3012 return sp;
2912 } 3013 }
2913 3014
@@ -3447,110 +3548,132 @@ namespace OpenSim.Region.Framework.Scenes
3447 { 3548 {
3448// CheckHeartbeat(); 3549// CheckHeartbeat();
3449 bool isChildAgent = false; 3550 bool isChildAgent = false;
3450 ScenePresence avatar = GetScenePresence(agentID); 3551 AgentCircuitData acd;
3451 3552
3452 if (avatar == null) 3553 lock (m_removeClientLock)
3453 { 3554 {
3454 m_log.WarnFormat( 3555 acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3455 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3456
3457 return;
3458 }
3459
3460 try
3461 {
3462 isChildAgent = avatar.IsChildAgent;
3463
3464 m_log.DebugFormat(
3465 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3466 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3467 3556
3468 // Don't do this to root agents, it's not nice for the viewer 3557 if (acd == null)
3469 if (closeChildAgents && isChildAgent)
3470 { 3558 {
3471 // Tell a single agent to disconnect from the region. 3559 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID);
3472 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3560 return;
3473 if (eq != null)
3474 {
3475 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3476 }
3477 else
3478 {
3479 avatar.ControllingClient.SendShutdownConnectionNotice();
3480 }
3481 } 3561 }
3482 3562 else
3483 // Only applies to root agents.
3484 if (avatar.ParentID != 0)
3485 { 3563 {
3486 avatar.StandUp(); 3564 // We remove the acd up here to avoid later race conditions if two RemoveClient() calls occurred
3565 // simultaneously.
3566 // We also need to remove by agent ID since NPCs will have no circuit code.
3567 m_authenticateHandler.RemoveCircuit(agentID);
3487 } 3568 }
3569 }
3488 3570
3489 m_sceneGraph.removeUserCount(!isChildAgent); 3571 lock (acd)
3490 3572 {
3491 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3573 ScenePresence avatar = GetScenePresence(agentID);
3492 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3574
3493 if (closeChildAgents && CapsModule != null) 3575 if (avatar == null)
3494 CapsModule.RemoveCaps(agentID);
3495
3496 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3497 // this method is doing is HORRIBLE!!!
3498 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3499
3500 if (closeChildAgents && !isChildAgent)
3501 { 3576 {
3502 List<ulong> regions = avatar.KnownRegionHandles; 3577 m_log.WarnFormat(
3503 regions.Remove(RegionInfo.RegionHandle); 3578 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3504 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3579
3580 return;
3505 } 3581 }
3506 3582
3507 m_eventManager.TriggerClientClosed(agentID, this); 3583 try
3508 m_eventManager.TriggerOnRemovePresence(agentID);
3509
3510 if (!isChildAgent)
3511 { 3584 {
3512 if (AttachmentsModule != null) 3585 isChildAgent = avatar.IsChildAgent;
3586
3587 m_log.DebugFormat(
3588 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3589 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3590
3591 // Don't do this to root agents, it's not nice for the viewer
3592 if (closeChildAgents && isChildAgent)
3513 { 3593 {
3514 AttachmentsModule.DeRezAttachments(avatar); 3594 // Tell a single agent to disconnect from the region.
3595 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3596 if (eq != null)
3597 {
3598 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3599 }
3600 else
3601 {
3602 avatar.ControllingClient.SendShutdownConnectionNotice();
3603 }
3515 } 3604 }
3516 3605
3517 ForEachClient( 3606 // Only applies to root agents.
3518 delegate(IClientAPI client) 3607 if (avatar.ParentID != 0)
3608 {
3609 avatar.StandUp();
3610 }
3611
3612 m_sceneGraph.removeUserCount(!isChildAgent);
3613
3614 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3615 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3616 if (closeChildAgents && CapsModule != null)
3617 CapsModule.RemoveCaps(agentID);
3618
3619// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3620// // this method is doing is HORRIBLE!!!
3621 // Commented pending deletion since this method no longer appears to do anything at all
3622// avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3623
3624 if (closeChildAgents && !isChildAgent)
3625 {
3626 List<ulong> regions = avatar.KnownRegionHandles;
3627 regions.Remove(RegionInfo.RegionHandle);
3628 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3629 }
3630
3631 m_eventManager.TriggerClientClosed(agentID, this);
3632 m_eventManager.TriggerOnRemovePresence(agentID);
3633
3634 if (!isChildAgent)
3635 {
3636 if (AttachmentsModule != null)
3519 { 3637 {
3520 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3638 AttachmentsModule.DeRezAttachments(avatar);
3521 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3639 }
3522 catch (NullReferenceException) { }
3523 });
3524 }
3525
3526 // It's possible for child agents to have transactions if changes are being made cross-border.
3527 if (AgentTransactionsModule != null)
3528 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3529 3640
3530 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3641 ForEachClient(
3531 m_log.Debug("[Scene] The avatar has left the building"); 3642 delegate(IClientAPI client)
3532 } 3643 {
3533 catch (Exception e) 3644 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3534 { 3645 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3535 m_log.Error( 3646 catch (NullReferenceException) { }
3536 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); 3647 });
3537 } 3648 }
3538 finally
3539 {
3540 try
3541 {
3542 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3543 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3544 // the same cleanup exception continually.
3545 m_sceneGraph.RemoveScenePresence(agentID);
3546 m_clientManager.Remove(agentID);
3547 3649
3548 avatar.Close(); 3650 // It's possible for child agents to have transactions if changes are being made cross-border.
3651 if (AgentTransactionsModule != null)
3652 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3653 m_log.Debug("[Scene] The avatar has left the building");
3549 } 3654 }
3550 catch (Exception e) 3655 catch (Exception e)
3551 { 3656 {
3552 m_log.Error( 3657 m_log.Error(
3553 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); 3658 string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3659 }
3660 finally
3661 {
3662 try
3663 {
3664 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3665 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3666 // the same cleanup exception continually.
3667 m_sceneGraph.RemoveScenePresence(agentID);
3668 m_clientManager.Remove(agentID);
3669
3670 avatar.Close();
3671 }
3672 catch (Exception e)
3673 {
3674 m_log.Error(
3675 string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3676 }
3554 } 3677 }
3555 } 3678 }
3556 3679
@@ -3609,11 +3732,9 @@ namespace OpenSim.Region.Framework.Scenes
3609 3732
3610 /// <summary> 3733 /// <summary>
3611 /// Do the work necessary to initiate a new user connection for a particular scene. 3734 /// Do the work necessary to initiate a new user connection for a particular scene.
3612 /// At the moment, this consists of setting up the caps infrastructure
3613 /// The return bool should allow for connections to be refused, but as not all calling paths
3614 /// take proper notice of it let, we allowed banned users in still.
3615 /// </summary> 3735 /// </summary>
3616 /// <param name="agent">CircuitData of the agent who is connecting</param> 3736 /// <param name="agent">CircuitData of the agent who is connecting</param>
3737 /// <param name="teleportFlags"></param>
3617 /// <param name="reason">Outputs the reason for the false response on this string</param> 3738 /// <param name="reason">Outputs the reason for the false response on this string</param>
3618 /// <returns>True if the region accepts this agent. False if it does not. False will 3739 /// <returns>True if the region accepts this agent. False if it does not. False will
3619 /// also return a reason.</returns> 3740 /// also return a reason.</returns>
@@ -3624,10 +3745,20 @@ namespace OpenSim.Region.Framework.Scenes
3624 3745
3625 /// <summary> 3746 /// <summary>
3626 /// Do the work necessary to initiate a new user connection for a particular scene. 3747 /// Do the work necessary to initiate a new user connection for a particular scene.
3627 /// At the moment, this consists of setting up the caps infrastructure 3748 /// </summary>
3749 /// <remarks>
3750 /// The return bool should allow for connections to be refused, but as not all calling paths
3751 /// take proper notice of it yet, we still allowed banned users in.
3752 ///
3753 /// At the moment this method consists of setting up the caps infrastructure
3628 /// The return bool should allow for connections to be refused, but as not all calling paths 3754 /// The return bool should allow for connections to be refused, but as not all calling paths
3629 /// take proper notice of it let, we allowed banned users in still. 3755 /// take proper notice of it let, we allowed banned users in still.
3630 /// </summary> 3756 ///
3757 /// This method is called by the login service (in the case of login) or another simulator (in the case of region
3758 /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection
3759 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3760 /// the LLUDP stack).
3761 /// </remarks>
3631 /// <param name="agent">CircuitData of the agent who is connecting</param> 3762 /// <param name="agent">CircuitData of the agent who is connecting</param>
3632 /// <param name="reason">Outputs the reason for the false response on this string</param> 3763 /// <param name="reason">Outputs the reason for the false response on this string</param>
3633 /// <param name="requirePresenceLookup">True for normal presence. False for NPC 3764 /// <param name="requirePresenceLookup">True for normal presence. False for NPC
@@ -3726,83 +3857,86 @@ namespace OpenSim.Region.Framework.Scenes
3726 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3857 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3727 sp.Name, sp.UUID, RegionInfo.RegionName); 3858 sp.Name, sp.UUID, RegionInfo.RegionName);
3728 3859
3729 sp.ControllingClient.Close(); 3860 sp.ControllingClient.Close(true, true);
3730 sp = null; 3861 sp = null;
3731 } 3862 }
3732 3863
3733 3864 lock (agent)
3734 //On login test land permisions
3735 if (vialogin)
3736 { 3865 {
3737 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3866 //On login test land permisions
3738 if (cache != null) 3867 if (vialogin)
3739 cache.Remove(agent.firstname + " " + agent.lastname);
3740 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3741 { 3868 {
3742 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3869 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3743 return false; 3870 if (cache != null)
3871 cache.Remove(agent.firstname + " " + agent.lastname);
3872 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3873 {
3874 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3875 return false;
3876 }
3744 } 3877 }
3745 }
3746 3878
3747 if (sp == null) // We don't have an [child] agent here already 3879 if (sp == null) // We don't have an [child] agent here already
3748 {
3749 if (requirePresenceLookup)
3750 { 3880 {
3751 try 3881 if (requirePresenceLookup)
3752 { 3882 {
3753 if (!VerifyUserPresence(agent, out reason)) 3883 try
3884 {
3885 if (!VerifyUserPresence(agent, out reason))
3886 return false;
3887 } catch (Exception e)
3888 {
3889 m_log.ErrorFormat(
3890 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3754 return false; 3891 return false;
3755 } catch (Exception e) 3892 }
3893 }
3894
3895 try
3896 {
3897 // Always check estate if this is a login. Always
3898 // check if banned regions are to be blacked out.
3899 if (vialogin || (!m_seeIntoBannedRegion))
3900 {
3901 if (!AuthorizeUser(agent, out reason))
3902 return false;
3903 }
3904 }
3905 catch (Exception e)
3756 { 3906 {
3757 m_log.ErrorFormat( 3907 m_log.ErrorFormat(
3758 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3908 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3759 return false; 3909 return false;
3760 } 3910 }
3761 }
3762 3911
3763 try 3912 m_log.InfoFormat(
3764 { 3913 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3765 // Always check estate if this is a login. Always 3914 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3766 // check if banned regions are to be blacked out. 3915 agent.AgentID, agent.circuitcode);
3767 if (vialogin || (!m_seeIntoBannedRegion)) 3916
3917 if (CapsModule != null)
3768 { 3918 {
3769 if (!AuthorizeUser(agent, out reason)) 3919 CapsModule.SetAgentCapsSeeds(agent);
3770 return false; 3920 CapsModule.CreateCaps(agent.AgentID);
3771 } 3921 }
3772 } 3922 }
3773 catch (Exception e) 3923 else
3774 { 3924 {
3775 m_log.ErrorFormat( 3925 // Let the SP know how we got here. This has a lot of interesting
3776 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 3926 // uses down the line.
3777 return false; 3927 sp.TeleportFlags = (TPFlags)teleportFlags;
3778 }
3779
3780 m_log.InfoFormat(
3781 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3782 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3783 agent.AgentID, agent.circuitcode);
3784 3928
3785 if (CapsModule != null) 3929 if (sp.IsChildAgent)
3786 { 3930 {
3787 CapsModule.SetAgentCapsSeeds(agent); 3931 m_log.DebugFormat(
3788 CapsModule.CreateCaps(agent.AgentID); 3932 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3789 } 3933 agent.AgentID, RegionInfo.RegionName);
3790 } else
3791 {
3792 // Let the SP know how we got here. This has a lot of interesting
3793 // uses down the line.
3794 sp.TeleportFlags = (TPFlags)teleportFlags;
3795 3934
3796 if (sp.IsChildAgent) 3935 sp.AdjustKnownSeeds();
3797 {
3798 m_log.DebugFormat(
3799 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3800 agent.AgentID, RegionInfo.RegionName);
3801 3936
3802 sp.AdjustKnownSeeds(); 3937 if (CapsModule != null)
3803 3938 CapsModule.SetAgentCapsSeeds(agent);
3804 if (CapsModule != null) 3939 }
3805 CapsModule.SetAgentCapsSeeds(agent);
3806 } 3940 }
3807 } 3941 }
3808 3942
@@ -4233,8 +4367,9 @@ namespace OpenSim.Region.Framework.Scenes
4233 return false; 4367 return false;
4234 } 4368 }
4235 4369
4236 // We have to wait until the viewer contacts this region after receiving EAC. 4370 // We have to wait until the viewer contacts this region
4237 // That calls AddNewClient, which finally creates the ScenePresence 4371 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send
4372 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4238 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4373 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4239 4374
4240 if (childAgentUpdate != null) 4375 if (childAgentUpdate != null)
@@ -4329,15 +4464,18 @@ namespace OpenSim.Region.Framework.Scenes
4329 /// Tell a single agent to disconnect from the region. 4464 /// Tell a single agent to disconnect from the region.
4330 /// </summary> 4465 /// </summary>
4331 /// <param name="agentID"></param> 4466 /// <param name="agentID"></param>
4332 /// <param name="childOnly"></param> 4467 /// <param name="force">
4333 public bool IncomingCloseAgent(UUID agentID, bool childOnly) 4468 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4469 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4470 /// </param>
4471 public bool IncomingCloseAgent(UUID agentID, bool force)
4334 { 4472 {
4335 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4473 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4336 4474
4337 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4475 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4338 if (presence != null) 4476 if (presence != null)
4339 { 4477 {
4340 presence.ControllingClient.Close(false); 4478 presence.ControllingClient.Close(force, force);
4341 return true; 4479 return true;
4342 } 4480 }
4343 4481
@@ -4543,6 +4681,16 @@ namespace OpenSim.Region.Framework.Scenes
4543 return LandChannel.GetLandObject(x, y).LandData; 4681 return LandChannel.GetLandObject(x, y).LandData;
4544 } 4682 }
4545 4683
4684 /// <summary>
4685 /// Get LandData by position.
4686 /// </summary>
4687 /// <param name="pos"></param>
4688 /// <returns></returns>
4689 public LandData GetLandData(Vector3 pos)
4690 {
4691 return GetLandData(pos.X, pos.Y);
4692 }
4693
4546 public LandData GetLandData(uint x, uint y) 4694 public LandData GetLandData(uint x, uint y)
4547 { 4695 {
4548 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); 4696 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
@@ -4773,13 +4921,24 @@ namespace OpenSim.Region.Framework.Scenes
4773 /// Get a group via its UUID 4921 /// Get a group via its UUID
4774 /// </summary> 4922 /// </summary>
4775 /// <param name="fullID"></param> 4923 /// <param name="fullID"></param>
4776 /// <returns>null if no group with that name exists</returns> 4924 /// <returns>null if no group with that id exists</returns>
4777 public SceneObjectGroup GetSceneObjectGroup(UUID fullID) 4925 public SceneObjectGroup GetSceneObjectGroup(UUID fullID)
4778 { 4926 {
4779 return m_sceneGraph.GetSceneObjectGroup(fullID); 4927 return m_sceneGraph.GetSceneObjectGroup(fullID);
4780 } 4928 }
4781 4929
4782 /// <summary> 4930 /// <summary>
4931 /// Get a group via its local ID
4932 /// </summary>
4933 /// <remarks>This will only return a group if the local ID matches a root part</remarks>
4934 /// <param name="localID"></param>
4935 /// <returns>null if no group with that id exists</returns>
4936 public SceneObjectGroup GetSceneObjectGroup(uint localID)
4937 {
4938 return m_sceneGraph.GetSceneObjectGroup(localID);
4939 }
4940
4941 /// <summary>
4783 /// Get a group by name from the scene (will return the first 4942 /// Get a group by name from the scene (will return the first
4784 /// found, if there are more than one prim with the same name) 4943 /// found, if there are more than one prim with the same name)
4785 /// </summary> 4944 /// </summary>
@@ -4791,6 +4950,18 @@ namespace OpenSim.Region.Framework.Scenes
4791 } 4950 }
4792 4951
4793 /// <summary> 4952 /// <summary>
4953 /// Attempt to get the SOG via its UUID
4954 /// </summary>
4955 /// <param name="fullID"></param>
4956 /// <param name="sog"></param>
4957 /// <returns></returns>
4958 public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
4959 {
4960 sog = GetSceneObjectGroup(fullID);
4961 return sog != null;
4962 }
4963
4964 /// <summary>
4794 /// Get a prim by name from the scene (will return the first 4965 /// Get a prim by name from the scene (will return the first
4795 /// found, if there are more than one prim with the same name) 4966 /// found, if there are more than one prim with the same name)
4796 /// </summary> 4967 /// </summary>
@@ -4822,6 +4993,18 @@ namespace OpenSim.Region.Framework.Scenes
4822 } 4993 }
4823 4994
4824 /// <summary> 4995 /// <summary>
4996 /// Attempt to get a prim via its UUID
4997 /// </summary>
4998 /// <param name="fullID"></param>
4999 /// <param name="sop"></param>
5000 /// <returns></returns>
5001 public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
5002 {
5003 sop = GetSceneObjectPart(fullID);
5004 return sop != null;
5005 }
5006
5007 /// <summary>
4825 /// Get a scene object group that contains the prim with the given local id 5008 /// Get a scene object group that contains the prim with the given local id
4826 /// </summary> 5009 /// </summary>
4827 /// <param name="localID"></param> 5010 /// <param name="localID"></param>
@@ -4915,14 +5098,15 @@ namespace OpenSim.Region.Framework.Scenes
4915 client.SendRegionHandle(regionID, handle); 5098 client.SendRegionHandle(regionID, handle);
4916 } 5099 }
4917 5100
4918 public bool NeedSceneCacheClear(UUID agentID) 5101// Commented pending deletion since this method no longer appears to do anything at all
4919 { 5102// public bool NeedSceneCacheClear(UUID agentID)
4920 IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>(); 5103// {
4921 if (inv == null) 5104// IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
4922 return true; 5105// if (inv == null)
4923 5106// return true;
4924 return inv.NeedSceneCacheClear(agentID, this); 5107//
4925 } 5108// return inv.NeedSceneCacheClear(agentID, this);
5109// }
4926 5110
4927 public void CleanTempObjects() 5111 public void CleanTempObjects()
4928 { 5112 {
@@ -5876,6 +6060,9 @@ Environment.Exit(1);
5876 6060
5877 public string GetExtraSetting(string name) 6061 public string GetExtraSetting(string name)
5878 { 6062 {
6063 if (m_extraSettings == null)
6064 return String.Empty;
6065
5879 string val; 6066 string val;
5880 6067
5881 if (!m_extraSettings.TryGetValue(name, out val)) 6068 if (!m_extraSettings.TryGetValue(name, out val))
@@ -5886,6 +6073,9 @@ Environment.Exit(1);
5886 6073
5887 public void StoreExtraSetting(string name, string val) 6074 public void StoreExtraSetting(string name, string val)
5888 { 6075 {
6076 if (m_extraSettings == null)
6077 return;
6078
5889 string oldVal; 6079 string oldVal;
5890 6080
5891 if (m_extraSettings.TryGetValue(name, out oldVal)) 6081 if (m_extraSettings.TryGetValue(name, out oldVal))
@@ -5903,6 +6093,9 @@ Environment.Exit(1);
5903 6093
5904 public void RemoveExtraSetting(string name) 6094 public void RemoveExtraSetting(string name)
5905 { 6095 {
6096 if (m_extraSettings == null)
6097 return;
6098
5906 if (!m_extraSettings.ContainsKey(name)) 6099 if (!m_extraSettings.ContainsKey(name))
5907 return; 6100 return;
5908 6101