diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 699 |
1 files changed, 443 insertions, 256 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 649d545..c99e37e 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 | { |
@@ -1103,15 +1167,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1103 | } | 1167 | } |
1104 | } | 1168 | } |
1105 | 1169 | ||
1106 | m_log.Error("[REGION]: Closing"); | 1170 | m_log.InfoFormat("[REGION]: Restarting region {0}", Name); |
1107 | Close(); | ||
1108 | 1171 | ||
1109 | if (PhysicsScene != null) | 1172 | Close(); |
1110 | { | ||
1111 | PhysicsScene.Dispose(); | ||
1112 | } | ||
1113 | |||
1114 | m_log.Error("[REGION]: Firing Region Restart Message"); | ||
1115 | 1173 | ||
1116 | base.Restart(); | 1174 | base.Restart(); |
1117 | } | 1175 | } |
@@ -1151,6 +1209,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1151 | 1209 | ||
1152 | public void SetSceneCoreDebug(Dictionary<string, string> options) | 1210 | public void SetSceneCoreDebug(Dictionary<string, string> options) |
1153 | { | 1211 | { |
1212 | if (options.ContainsKey("active")) | ||
1213 | { | ||
1214 | bool active; | ||
1215 | |||
1216 | if (bool.TryParse(options["active"], out active)) | ||
1217 | Active = active; | ||
1218 | } | ||
1219 | |||
1154 | if (options.ContainsKey("scripting")) | 1220 | if (options.ContainsKey("scripting")) |
1155 | { | 1221 | { |
1156 | bool enableScripts = true; | 1222 | bool enableScripts = true; |
@@ -1226,6 +1292,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1226 | // This is the method that shuts down the scene. | 1292 | // This is the method that shuts down the scene. |
1227 | public override void Close() | 1293 | public override void Close() |
1228 | { | 1294 | { |
1295 | if (m_shuttingDown) | ||
1296 | { | ||
1297 | m_log.WarnFormat("[SCENE]: Ignoring close request because already closing {0}", Name); | ||
1298 | return; | ||
1299 | } | ||
1300 | |||
1229 | m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); | 1301 | m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); |
1230 | 1302 | ||
1231 | StatsReporter.Close(); | 1303 | StatsReporter.Close(); |
@@ -1272,6 +1344,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1272 | m_log.Debug("[SCENE]: Graph close"); | 1344 | m_log.Debug("[SCENE]: Graph close"); |
1273 | m_sceneGraph.Close(); | 1345 | m_sceneGraph.Close(); |
1274 | 1346 | ||
1347 | if (!GridService.DeregisterRegion(RegionInfo.RegionID)) | ||
1348 | m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name); | ||
1349 | |||
1350 | base.Close(); | ||
1351 | |||
1352 | // XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence. | ||
1353 | // Therefore. we must dispose of the PhysicsScene after this to prevent a window where script code can | ||
1354 | // attempt to reference a null or disposed physics scene. | ||
1275 | if (PhysicsScene != null) | 1355 | if (PhysicsScene != null) |
1276 | { | 1356 | { |
1277 | m_log.Debug("[SCENE]: Dispose Physics"); | 1357 | m_log.Debug("[SCENE]: Dispose Physics"); |
@@ -1281,13 +1361,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1281 | phys.Dispose(); | 1361 | phys.Dispose(); |
1282 | phys = null; | 1362 | phys = null; |
1283 | } | 1363 | } |
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 | } | 1364 | } |
1292 | 1365 | ||
1293 | /// <summary> | 1366 | /// <summary> |
@@ -1295,6 +1368,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1295 | /// </summary> | 1368 | /// </summary> |
1296 | public void Start() | 1369 | public void Start() |
1297 | { | 1370 | { |
1371 | m_active = true; | ||
1372 | |||
1298 | // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); | 1373 | // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); |
1299 | 1374 | ||
1300 | //m_heartbeatTimer.Enabled = true; | 1375 | //m_heartbeatTimer.Enabled = true; |
@@ -1354,7 +1429,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1354 | #region Update Methods | 1429 | #region Update Methods |
1355 | 1430 | ||
1356 | /// <summary> | 1431 | /// <summary> |
1357 | /// Performs per-frame updates regularly | 1432 | /// Activate the various loops necessary to continually update the scene. |
1358 | /// </summary> | 1433 | /// </summary> |
1359 | private void Heartbeat() | 1434 | private void Heartbeat() |
1360 | { | 1435 | { |
@@ -1411,7 +1486,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1411 | List<Vector3> coarseLocations; | 1486 | List<Vector3> coarseLocations; |
1412 | List<UUID> avatarUUIDs; | 1487 | List<UUID> avatarUUIDs; |
1413 | 1488 | ||
1414 | while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) | 1489 | while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun)) |
1415 | { | 1490 | { |
1416 | runtc = Util.EnvironmentTickCount(); | 1491 | runtc = Util.EnvironmentTickCount(); |
1417 | ++MaintenanceRun; | 1492 | ++MaintenanceRun; |
@@ -1473,7 +1548,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1473 | int sleepMS; | 1548 | int sleepMS; |
1474 | int framestart; | 1549 | int framestart; |
1475 | 1550 | ||
1476 | while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) | 1551 | while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) |
1477 | { | 1552 | { |
1478 | framestart = Util.EnvironmentTickCount(); | 1553 | framestart = Util.EnvironmentTickCount(); |
1479 | ++Frame; | 1554 | ++Frame; |
@@ -1672,15 +1747,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1672 | 1747 | ||
1673 | private void CheckAtTargets() | 1748 | private void CheckAtTargets() |
1674 | { | 1749 | { |
1675 | List<SceneObjectGroup> objs = new List<SceneObjectGroup>(); | 1750 | List<SceneObjectGroup> objs = null; |
1751 | |||
1676 | lock (m_groupsWithTargets) | 1752 | lock (m_groupsWithTargets) |
1677 | { | 1753 | { |
1678 | foreach (SceneObjectGroup grp in m_groupsWithTargets.Values) | 1754 | if (m_groupsWithTargets.Count != 0) |
1679 | objs.Add(grp); | 1755 | objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values); |
1680 | } | 1756 | } |
1681 | 1757 | ||
1682 | foreach (SceneObjectGroup entry in objs) | 1758 | if (objs != null) |
1683 | entry.checkAtTargets(); | 1759 | { |
1760 | foreach (SceneObjectGroup entry in objs) | ||
1761 | entry.checkAtTargets(); | ||
1762 | } | ||
1684 | } | 1763 | } |
1685 | 1764 | ||
1686 | /// <summary> | 1765 | /// <summary> |
@@ -2193,10 +2272,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2193 | public bool AddRestoredSceneObject( | 2272 | public bool AddRestoredSceneObject( |
2194 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) | 2273 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) |
2195 | { | 2274 | { |
2196 | bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); | 2275 | if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) |
2197 | if (result) | 2276 | { |
2198 | sceneObject.IsDeleted = false; | 2277 | sceneObject.IsDeleted = false; |
2199 | return result; | 2278 | EventManager.TriggerObjectAddedToScene(sceneObject); |
2279 | return true; | ||
2280 | } | ||
2281 | |||
2282 | return false; | ||
2200 | } | 2283 | } |
2201 | 2284 | ||
2202 | /// <summary> | 2285 | /// <summary> |
@@ -2837,77 +2920,89 @@ namespace OpenSim.Region.Framework.Scenes | |||
2837 | 2920 | ||
2838 | public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) | 2921 | public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) |
2839 | { | 2922 | { |
2923 | ScenePresence sp; | ||
2924 | bool vialogin; | ||
2925 | |||
2840 | // Validation occurs in LLUDPServer | 2926 | // Validation occurs in LLUDPServer |
2927 | // | ||
2928 | // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with | ||
2929 | // each other. In practice, this does not currently occur in the code. | ||
2841 | AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); | 2930 | AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); |
2842 | 2931 | ||
2843 | bool vialogin | 2932 | // 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 | 2933 | // 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; | 2934 | // whilst connecting). |
2846 | 2935 | // | |
2847 | CheckHeartbeat(); | 2936 | // It would be easier to lock across all NewUserConnection(), AddNewClient() and |
2848 | 2937 | // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service | |
2849 | ScenePresence sp = GetScenePresence(client.AgentId); | 2938 | // response in some module listening to AddNewClient()) from holding up unrelated agent calls. |
2850 | 2939 | // | |
2851 | // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this | 2940 | // 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 | 2941 | // AddNewClient() operations (though not other ops). |
2853 | // other problems, and possible the code calling AddNewClient() should ensure that no client is already | 2942 | // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved. |
2854 | // connected. | 2943 | lock (aCircuit) |
2855 | if (sp == null) | 2944 | { |
2856 | { | 2945 | vialogin |
2857 | m_log.DebugFormat( | 2946 | = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 |
2858 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", | 2947 | || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; |
2859 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); | 2948 | |
2860 | 2949 | CheckHeartbeat(); | |
2861 | m_clientManager.Add(client); | 2950 | |
2862 | SubscribeToClientEvents(client); | 2951 | 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 | 2952 | ||
2869 | // The first agent upon login is a root agent by design. | 2953 | // 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. | 2954 | // 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. | 2955 | // other problems, and possible the code calling AddNewClient() should ensure that no client is already |
2872 | if (aCircuit.child == false) | 2956 | // connected. |
2957 | if (sp == null) | ||
2873 | { | 2958 | { |
2874 | // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to | 2959 | m_log.DebugFormat( |
2875 | // start the scripts again (since this is done in RezAttachments()). | 2960 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", |
2876 | // XXX: This is convoluted. | 2961 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); |
2877 | sp.IsChildAgent = false; | 2962 | |
2878 | 2963 | m_clientManager.Add(client); | |
2879 | if (AttachmentsModule != null) | 2964 | SubscribeToClientEvents(client); |
2880 | Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); | 2965 | |
2966 | sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); | ||
2967 | m_eventManager.TriggerOnNewPresence(sp); | ||
2968 | |||
2969 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; | ||
2970 | |||
2971 | // The first agent upon login is a root agent by design. | ||
2972 | // For this agent we will have to rez the attachments. | ||
2973 | // All other AddNewClient calls find aCircuit.child to be true. | ||
2974 | if (aCircuit.child == false) | ||
2975 | { | ||
2976 | // We have to set SP to be a root agent here so that SP.MakeRootAgent() will later not try to | ||
2977 | // start the scripts again (since this is done in RezAttachments()). | ||
2978 | // XXX: This is convoluted. | ||
2979 | sp.IsChildAgent = false; | ||
2980 | |||
2981 | if (AttachmentsModule != null) | ||
2982 | Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); }); | ||
2983 | } | ||
2881 | } | 2984 | } |
2882 | } | 2985 | else |
2883 | else | 2986 | { |
2884 | { | 2987 | m_log.WarnFormat( |
2885 | m_log.WarnFormat( | 2988 | "[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", | 2989 | sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); |
2887 | sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); | 2990 | } |
2888 | } | 2991 | |
2992 | // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the | ||
2993 | // client is for a root or child agent. | ||
2994 | client.SceneAgent = sp; | ||
2889 | 2995 | ||
2890 | // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the | 2996 | // Cache the user's name |
2891 | // client is for a root or child agent. | 2997 | CacheUserName(sp, aCircuit); |
2892 | client.SceneAgent = sp; | 2998 | |
2999 | EventManager.TriggerOnNewClient(client); | ||
3000 | if (vialogin) | ||
3001 | EventManager.TriggerOnClientLogin(client); | ||
3002 | } | ||
2893 | 3003 | ||
2894 | m_LastLogin = Util.EnvironmentTickCount(); | 3004 | m_LastLogin = Util.EnvironmentTickCount(); |
2895 | 3005 | ||
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; | 3006 | return sp; |
2912 | } | 3007 | } |
2913 | 3008 | ||
@@ -3447,110 +3542,132 @@ namespace OpenSim.Region.Framework.Scenes | |||
3447 | { | 3542 | { |
3448 | // CheckHeartbeat(); | 3543 | // CheckHeartbeat(); |
3449 | bool isChildAgent = false; | 3544 | bool isChildAgent = false; |
3450 | ScenePresence avatar = GetScenePresence(agentID); | 3545 | AgentCircuitData acd; |
3451 | |||
3452 | if (avatar == null) | ||
3453 | { | ||
3454 | m_log.WarnFormat( | ||
3455 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); | ||
3456 | 3546 | ||
3457 | return; | 3547 | lock (m_removeClientLock) |
3458 | } | ||
3459 | |||
3460 | try | ||
3461 | { | 3548 | { |
3462 | isChildAgent = avatar.IsChildAgent; | 3549 | acd = m_authenticateHandler.GetAgentCircuitData(agentID); |
3463 | 3550 | ||
3464 | m_log.DebugFormat( | 3551 | if (acd == null) |
3465 | "[SCENE]: Removing {0} agent {1} {2} from {3}", | ||
3466 | (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); | ||
3467 | |||
3468 | // Don't do this to root agents, it's not nice for the viewer | ||
3469 | if (closeChildAgents && isChildAgent) | ||
3470 | { | 3552 | { |
3471 | // Tell a single agent to disconnect from the region. | 3553 | m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID); |
3472 | IEventQueue eq = RequestModuleInterface<IEventQueue>(); | 3554 | return; |
3473 | if (eq != null) | ||
3474 | { | ||
3475 | eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID); | ||
3476 | } | ||
3477 | else | ||
3478 | { | ||
3479 | avatar.ControllingClient.SendShutdownConnectionNotice(); | ||
3480 | } | ||
3481 | } | 3555 | } |
3482 | 3556 | else | |
3483 | // Only applies to root agents. | ||
3484 | if (avatar.ParentID != 0) | ||
3485 | { | 3557 | { |
3486 | avatar.StandUp(); | 3558 | // We remove the acd up here to avoid later race conditions if two RemoveClient() calls occurred |
3559 | // simultaneously. | ||
3560 | // We also need to remove by agent ID since NPCs will have no circuit code. | ||
3561 | m_authenticateHandler.RemoveCircuit(agentID); | ||
3487 | } | 3562 | } |
3563 | } | ||
3488 | 3564 | ||
3489 | m_sceneGraph.removeUserCount(!isChildAgent); | 3565 | lock (acd) |
3490 | 3566 | { | |
3491 | // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop | 3567 | ScenePresence avatar = GetScenePresence(agentID); |
3492 | // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI | 3568 | |
3493 | if (closeChildAgents && CapsModule != null) | 3569 | 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 | { | 3570 | { |
3502 | List<ulong> regions = avatar.KnownRegionHandles; | 3571 | m_log.WarnFormat( |
3503 | regions.Remove(RegionInfo.RegionHandle); | 3572 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); |
3504 | m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); | 3573 | |
3574 | return; | ||
3505 | } | 3575 | } |
3506 | 3576 | ||
3507 | m_eventManager.TriggerClientClosed(agentID, this); | 3577 | try |
3508 | m_eventManager.TriggerOnRemovePresence(agentID); | ||
3509 | |||
3510 | if (!isChildAgent) | ||
3511 | { | 3578 | { |
3512 | if (AttachmentsModule != null) | 3579 | isChildAgent = avatar.IsChildAgent; |
3580 | |||
3581 | m_log.DebugFormat( | ||
3582 | "[SCENE]: Removing {0} agent {1} {2} from {3}", | ||
3583 | (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); | ||
3584 | |||
3585 | // Don't do this to root agents, it's not nice for the viewer | ||
3586 | if (closeChildAgents && isChildAgent) | ||
3513 | { | 3587 | { |
3514 | AttachmentsModule.DeRezAttachments(avatar); | 3588 | // Tell a single agent to disconnect from the region. |
3589 | IEventQueue eq = RequestModuleInterface<IEventQueue>(); | ||
3590 | if (eq != null) | ||
3591 | { | ||
3592 | eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID); | ||
3593 | } | ||
3594 | else | ||
3595 | { | ||
3596 | avatar.ControllingClient.SendShutdownConnectionNotice(); | ||
3597 | } | ||
3515 | } | 3598 | } |
3516 | 3599 | ||
3517 | ForEachClient( | 3600 | // Only applies to root agents. |
3518 | delegate(IClientAPI client) | 3601 | if (avatar.ParentID != 0) |
3602 | { | ||
3603 | avatar.StandUp(); | ||
3604 | } | ||
3605 | |||
3606 | m_sceneGraph.removeUserCount(!isChildAgent); | ||
3607 | |||
3608 | // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop | ||
3609 | // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI | ||
3610 | if (closeChildAgents && CapsModule != null) | ||
3611 | CapsModule.RemoveCaps(agentID); | ||
3612 | |||
3613 | // // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever | ||
3614 | // // this method is doing is HORRIBLE!!! | ||
3615 | // Commented pending deletion since this method no longer appears to do anything at all | ||
3616 | // avatar.Scene.NeedSceneCacheClear(avatar.UUID); | ||
3617 | |||
3618 | if (closeChildAgents && !isChildAgent) | ||
3619 | { | ||
3620 | List<ulong> regions = avatar.KnownRegionHandles; | ||
3621 | regions.Remove(RegionInfo.RegionHandle); | ||
3622 | m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); | ||
3623 | } | ||
3624 | |||
3625 | m_eventManager.TriggerClientClosed(agentID, this); | ||
3626 | m_eventManager.TriggerOnRemovePresence(agentID); | ||
3627 | |||
3628 | if (!isChildAgent) | ||
3629 | { | ||
3630 | if (AttachmentsModule != null) | ||
3519 | { | 3631 | { |
3520 | //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway | 3632 | AttachmentsModule.DeRezAttachments(avatar); |
3521 | try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } | 3633 | } |
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 | 3634 | ||
3530 | m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); | 3635 | ForEachClient( |
3531 | m_log.Debug("[Scene] The avatar has left the building"); | 3636 | delegate(IClientAPI client) |
3532 | } | 3637 | { |
3533 | catch (Exception e) | 3638 | //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway |
3534 | { | 3639 | try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } |
3535 | m_log.Error( | 3640 | catch (NullReferenceException) { } |
3536 | string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); | 3641 | }); |
3537 | } | 3642 | } |
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 | 3643 | ||
3548 | avatar.Close(); | 3644 | // It's possible for child agents to have transactions if changes are being made cross-border. |
3645 | if (AgentTransactionsModule != null) | ||
3646 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); | ||
3647 | m_log.Debug("[Scene] The avatar has left the building"); | ||
3549 | } | 3648 | } |
3550 | catch (Exception e) | 3649 | catch (Exception e) |
3551 | { | 3650 | { |
3552 | m_log.Error( | 3651 | m_log.Error( |
3553 | string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); | 3652 | string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); |
3653 | } | ||
3654 | finally | ||
3655 | { | ||
3656 | try | ||
3657 | { | ||
3658 | // Always clean these structures up so that any failure above doesn't cause them to remain in the | ||
3659 | // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering | ||
3660 | // the same cleanup exception continually. | ||
3661 | m_sceneGraph.RemoveScenePresence(agentID); | ||
3662 | m_clientManager.Remove(agentID); | ||
3663 | |||
3664 | avatar.Close(); | ||
3665 | } | ||
3666 | catch (Exception e) | ||
3667 | { | ||
3668 | m_log.Error( | ||
3669 | string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); | ||
3670 | } | ||
3554 | } | 3671 | } |
3555 | } | 3672 | } |
3556 | 3673 | ||
@@ -3609,11 +3726,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3609 | 3726 | ||
3610 | /// <summary> | 3727 | /// <summary> |
3611 | /// Do the work necessary to initiate a new user connection for a particular scene. | 3728 | /// 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> | 3729 | /// </summary> |
3616 | /// <param name="agent">CircuitData of the agent who is connecting</param> | 3730 | /// <param name="agent">CircuitData of the agent who is connecting</param> |
3731 | /// <param name="teleportFlags"></param> | ||
3617 | /// <param name="reason">Outputs the reason for the false response on this string</param> | 3732 | /// <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 | 3733 | /// <returns>True if the region accepts this agent. False if it does not. False will |
3619 | /// also return a reason.</returns> | 3734 | /// also return a reason.</returns> |
@@ -3624,10 +3739,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3624 | 3739 | ||
3625 | /// <summary> | 3740 | /// <summary> |
3626 | /// Do the work necessary to initiate a new user connection for a particular scene. | 3741 | /// 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 | 3742 | /// </summary> |
3743 | /// <remarks> | ||
3744 | /// The return bool should allow for connections to be refused, but as not all calling paths | ||
3745 | /// take proper notice of it yet, we still allowed banned users in. | ||
3746 | /// | ||
3747 | /// 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 | 3748 | /// 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. | 3749 | /// take proper notice of it let, we allowed banned users in still. |
3630 | /// </summary> | 3750 | /// |
3751 | /// This method is called by the login service (in the case of login) or another simulator (in the case of region | ||
3752 | /// cross or teleport) to initiate the connection. It is not triggered by the viewer itself - the connection | ||
3753 | /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of | ||
3754 | /// the LLUDP stack). | ||
3755 | /// </remarks> | ||
3631 | /// <param name="agent">CircuitData of the agent who is connecting</param> | 3756 | /// <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> | 3757 | /// <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 | 3758 | /// <param name="requirePresenceLookup">True for normal presence. False for NPC |
@@ -3726,83 +3851,86 @@ namespace OpenSim.Region.Framework.Scenes | |||
3726 | "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", | 3851 | "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", |
3727 | sp.Name, sp.UUID, RegionInfo.RegionName); | 3852 | sp.Name, sp.UUID, RegionInfo.RegionName); |
3728 | 3853 | ||
3729 | sp.ControllingClient.Close(); | 3854 | sp.ControllingClient.Close(true, true); |
3730 | sp = null; | 3855 | sp = null; |
3731 | } | 3856 | } |
3732 | 3857 | ||
3733 | 3858 | lock (agent) | |
3734 | //On login test land permisions | ||
3735 | if (vialogin) | ||
3736 | { | 3859 | { |
3737 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); | 3860 | //On login test land permisions |
3738 | if (cache != null) | 3861 | 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 | { | 3862 | { |
3742 | m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); | 3863 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); |
3743 | return false; | 3864 | if (cache != null) |
3865 | cache.Remove(agent.firstname + " " + agent.lastname); | ||
3866 | if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y)) | ||
3867 | { | ||
3868 | m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); | ||
3869 | return false; | ||
3870 | } | ||
3744 | } | 3871 | } |
3745 | } | ||
3746 | 3872 | ||
3747 | if (sp == null) // We don't have an [child] agent here already | 3873 | if (sp == null) // We don't have an [child] agent here already |
3748 | { | ||
3749 | if (requirePresenceLookup) | ||
3750 | { | 3874 | { |
3751 | try | 3875 | if (requirePresenceLookup) |
3752 | { | 3876 | { |
3753 | if (!VerifyUserPresence(agent, out reason)) | 3877 | try |
3878 | { | ||
3879 | if (!VerifyUserPresence(agent, out reason)) | ||
3880 | return false; | ||
3881 | } catch (Exception e) | ||
3882 | { | ||
3883 | m_log.ErrorFormat( | ||
3884 | "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); | ||
3754 | return false; | 3885 | return false; |
3755 | } catch (Exception e) | 3886 | } |
3887 | } | ||
3888 | |||
3889 | try | ||
3890 | { | ||
3891 | // Always check estate if this is a login. Always | ||
3892 | // check if banned regions are to be blacked out. | ||
3893 | if (vialogin || (!m_seeIntoBannedRegion)) | ||
3894 | { | ||
3895 | if (!AuthorizeUser(agent, out reason)) | ||
3896 | return false; | ||
3897 | } | ||
3898 | } | ||
3899 | catch (Exception e) | ||
3756 | { | 3900 | { |
3757 | m_log.ErrorFormat( | 3901 | m_log.ErrorFormat( |
3758 | "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); | 3902 | "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); |
3759 | return false; | 3903 | return false; |
3760 | } | 3904 | } |
3761 | } | ||
3762 | 3905 | ||
3763 | try | 3906 | m_log.InfoFormat( |
3764 | { | 3907 | "[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 | 3908 | RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, |
3766 | // check if banned regions are to be blacked out. | 3909 | agent.AgentID, agent.circuitcode); |
3767 | if (vialogin || (!m_seeIntoBannedRegion)) | 3910 | |
3911 | if (CapsModule != null) | ||
3768 | { | 3912 | { |
3769 | if (!AuthorizeUser(agent, out reason)) | 3913 | CapsModule.SetAgentCapsSeeds(agent); |
3770 | return false; | 3914 | CapsModule.CreateCaps(agent.AgentID); |
3771 | } | 3915 | } |
3772 | } | 3916 | } |
3773 | catch (Exception e) | 3917 | else |
3774 | { | 3918 | { |
3775 | m_log.ErrorFormat( | 3919 | // 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); | 3920 | // uses down the line. |
3777 | return false; | 3921 | 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 | 3922 | ||
3785 | if (CapsModule != null) | 3923 | if (sp.IsChildAgent) |
3786 | { | 3924 | { |
3787 | CapsModule.SetAgentCapsSeeds(agent); | 3925 | m_log.DebugFormat( |
3788 | CapsModule.CreateCaps(agent.AgentID); | 3926 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", |
3789 | } | 3927 | 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 | 3928 | ||
3796 | if (sp.IsChildAgent) | 3929 | sp.AdjustKnownSeeds(); |
3797 | { | ||
3798 | m_log.DebugFormat( | ||
3799 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", | ||
3800 | agent.AgentID, RegionInfo.RegionName); | ||
3801 | 3930 | ||
3802 | sp.AdjustKnownSeeds(); | 3931 | if (CapsModule != null) |
3803 | 3932 | CapsModule.SetAgentCapsSeeds(agent); | |
3804 | if (CapsModule != null) | 3933 | } |
3805 | CapsModule.SetAgentCapsSeeds(agent); | ||
3806 | } | 3934 | } |
3807 | } | 3935 | } |
3808 | 3936 | ||
@@ -4233,8 +4361,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
4233 | return false; | 4361 | return false; |
4234 | } | 4362 | } |
4235 | 4363 | ||
4236 | // We have to wait until the viewer contacts this region after receiving EAC. | 4364 | // We have to wait until the viewer contacts this region |
4237 | // That calls AddNewClient, which finally creates the ScenePresence | 4365 | // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send |
4366 | // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence. | ||
4238 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); | 4367 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); |
4239 | 4368 | ||
4240 | if (childAgentUpdate != null) | 4369 | if (childAgentUpdate != null) |
@@ -4329,15 +4458,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
4329 | /// Tell a single agent to disconnect from the region. | 4458 | /// Tell a single agent to disconnect from the region. |
4330 | /// </summary> | 4459 | /// </summary> |
4331 | /// <param name="agentID"></param> | 4460 | /// <param name="agentID"></param> |
4332 | /// <param name="childOnly"></param> | 4461 | /// <param name="force"> |
4333 | public bool IncomingCloseAgent(UUID agentID, bool childOnly) | 4462 | /// Force the agent to close even if it might be in the middle of some other operation. You do not want to |
4463 | /// force unless you are absolutely sure that the agent is dead and a normal close is not working. | ||
4464 | /// </param> | ||
4465 | public bool IncomingCloseAgent(UUID agentID, bool force) | ||
4334 | { | 4466 | { |
4335 | //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); | 4467 | //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); |
4336 | 4468 | ||
4337 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); | 4469 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); |
4338 | if (presence != null) | 4470 | if (presence != null) |
4339 | { | 4471 | { |
4340 | presence.ControllingClient.Close(false); | 4472 | presence.ControllingClient.Close(force, force); |
4341 | return true; | 4473 | return true; |
4342 | } | 4474 | } |
4343 | 4475 | ||
@@ -4543,6 +4675,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
4543 | return LandChannel.GetLandObject(x, y).LandData; | 4675 | return LandChannel.GetLandObject(x, y).LandData; |
4544 | } | 4676 | } |
4545 | 4677 | ||
4678 | /// <summary> | ||
4679 | /// Get LandData by position. | ||
4680 | /// </summary> | ||
4681 | /// <param name="pos"></param> | ||
4682 | /// <returns></returns> | ||
4683 | public LandData GetLandData(Vector3 pos) | ||
4684 | { | ||
4685 | return GetLandData(pos.X, pos.Y); | ||
4686 | } | ||
4687 | |||
4546 | public LandData GetLandData(uint x, uint y) | 4688 | public LandData GetLandData(uint x, uint y) |
4547 | { | 4689 | { |
4548 | m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); | 4690 | m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); |
@@ -4773,13 +4915,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
4773 | /// Get a group via its UUID | 4915 | /// Get a group via its UUID |
4774 | /// </summary> | 4916 | /// </summary> |
4775 | /// <param name="fullID"></param> | 4917 | /// <param name="fullID"></param> |
4776 | /// <returns>null if no group with that name exists</returns> | 4918 | /// <returns>null if no group with that id exists</returns> |
4777 | public SceneObjectGroup GetSceneObjectGroup(UUID fullID) | 4919 | public SceneObjectGroup GetSceneObjectGroup(UUID fullID) |
4778 | { | 4920 | { |
4779 | return m_sceneGraph.GetSceneObjectGroup(fullID); | 4921 | return m_sceneGraph.GetSceneObjectGroup(fullID); |
4780 | } | 4922 | } |
4781 | 4923 | ||
4782 | /// <summary> | 4924 | /// <summary> |
4925 | /// Get a group via its local ID | ||
4926 | /// </summary> | ||
4927 | /// <remarks>This will only return a group if the local ID matches a root part</remarks> | ||
4928 | /// <param name="localID"></param> | ||
4929 | /// <returns>null if no group with that id exists</returns> | ||
4930 | public SceneObjectGroup GetSceneObjectGroup(uint localID) | ||
4931 | { | ||
4932 | return m_sceneGraph.GetSceneObjectGroup(localID); | ||
4933 | } | ||
4934 | |||
4935 | /// <summary> | ||
4783 | /// Get a group by name from the scene (will return the first | 4936 | /// 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) | 4937 | /// found, if there are more than one prim with the same name) |
4785 | /// </summary> | 4938 | /// </summary> |
@@ -4791,6 +4944,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
4791 | } | 4944 | } |
4792 | 4945 | ||
4793 | /// <summary> | 4946 | /// <summary> |
4947 | /// Attempt to get the SOG via its UUID | ||
4948 | /// </summary> | ||
4949 | /// <param name="fullID"></param> | ||
4950 | /// <param name="sog"></param> | ||
4951 | /// <returns></returns> | ||
4952 | public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog) | ||
4953 | { | ||
4954 | sog = GetSceneObjectGroup(fullID); | ||
4955 | return sog != null; | ||
4956 | } | ||
4957 | |||
4958 | /// <summary> | ||
4794 | /// Get a prim by name from the scene (will return the first | 4959 | /// 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) | 4960 | /// found, if there are more than one prim with the same name) |
4796 | /// </summary> | 4961 | /// </summary> |
@@ -4822,6 +4987,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
4822 | } | 4987 | } |
4823 | 4988 | ||
4824 | /// <summary> | 4989 | /// <summary> |
4990 | /// Attempt to get a prim via its UUID | ||
4991 | /// </summary> | ||
4992 | /// <param name="fullID"></param> | ||
4993 | /// <param name="sop"></param> | ||
4994 | /// <returns></returns> | ||
4995 | public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop) | ||
4996 | { | ||
4997 | sop = GetSceneObjectPart(fullID); | ||
4998 | return sop != null; | ||
4999 | } | ||
5000 | |||
5001 | /// <summary> | ||
4825 | /// Get a scene object group that contains the prim with the given local id | 5002 | /// Get a scene object group that contains the prim with the given local id |
4826 | /// </summary> | 5003 | /// </summary> |
4827 | /// <param name="localID"></param> | 5004 | /// <param name="localID"></param> |
@@ -4915,14 +5092,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
4915 | client.SendRegionHandle(regionID, handle); | 5092 | client.SendRegionHandle(regionID, handle); |
4916 | } | 5093 | } |
4917 | 5094 | ||
4918 | public bool NeedSceneCacheClear(UUID agentID) | 5095 | // Commented pending deletion since this method no longer appears to do anything at all |
4919 | { | 5096 | // public bool NeedSceneCacheClear(UUID agentID) |
4920 | IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>(); | 5097 | // { |
4921 | if (inv == null) | 5098 | // IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>(); |
4922 | return true; | 5099 | // if (inv == null) |
4923 | 5100 | // return true; | |
4924 | return inv.NeedSceneCacheClear(agentID, this); | 5101 | // |
4925 | } | 5102 | // return inv.NeedSceneCacheClear(agentID, this); |
5103 | // } | ||
4926 | 5104 | ||
4927 | public void CleanTempObjects() | 5105 | public void CleanTempObjects() |
4928 | { | 5106 | { |
@@ -5876,6 +6054,9 @@ Environment.Exit(1); | |||
5876 | 6054 | ||
5877 | public string GetExtraSetting(string name) | 6055 | public string GetExtraSetting(string name) |
5878 | { | 6056 | { |
6057 | if (m_extraSettings == null) | ||
6058 | return String.Empty; | ||
6059 | |||
5879 | string val; | 6060 | string val; |
5880 | 6061 | ||
5881 | if (!m_extraSettings.TryGetValue(name, out val)) | 6062 | if (!m_extraSettings.TryGetValue(name, out val)) |
@@ -5886,6 +6067,9 @@ Environment.Exit(1); | |||
5886 | 6067 | ||
5887 | public void StoreExtraSetting(string name, string val) | 6068 | public void StoreExtraSetting(string name, string val) |
5888 | { | 6069 | { |
6070 | if (m_extraSettings == null) | ||
6071 | return; | ||
6072 | |||
5889 | string oldVal; | 6073 | string oldVal; |
5890 | 6074 | ||
5891 | if (m_extraSettings.TryGetValue(name, out oldVal)) | 6075 | if (m_extraSettings.TryGetValue(name, out oldVal)) |
@@ -5903,6 +6087,9 @@ Environment.Exit(1); | |||
5903 | 6087 | ||
5904 | public void RemoveExtraSetting(string name) | 6088 | public void RemoveExtraSetting(string name) |
5905 | { | 6089 | { |
6090 | if (m_extraSettings == null) | ||
6091 | return; | ||
6092 | |||
5906 | if (!m_extraSettings.ContainsKey(name)) | 6093 | if (!m_extraSettings.ContainsKey(name)) |
5907 | return; | 6094 | return; |
5908 | 6095 | ||