diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs old mode 100644 new mode 100755 index f6f458d3ec..e4df7ee7f0 --- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using OpenMetaverse; @@ -71,6 +72,11 @@ namespace OpenSim.Framework.Monitoring private volatile float pendingUploads; private volatile float activeScripts; private volatile float scriptLinesPerSecond; + private volatile float m_frameDilation; + private volatile float m_usersLoggingIn; + private volatile float m_totalGeoPrims; + private volatile float m_totalMeshes; + private volatile float m_inUseThreads; // /// // /// These statistics are being collected by push rather than pull. Pull would be simpler, but I had the @@ -249,6 +255,10 @@ namespace OpenSim.Framework.Monitoring { // FIXME: SimStats shouldn't allow an arbitrary stat packing order (which is inherited from the original // SimStatsPacket that was being used). + + // For an unknown reason the original designers decided not to + // include the spare MS statistic inside of this class, this is + // located inside the StatsBlock at location 21, thus it is skipped timeDilation = stats.StatsBlock[0].StatValue; simFps = stats.StatsBlock[1].StatValue; physicsFps = stats.StatsBlock[2].StatValue; @@ -270,6 +280,11 @@ namespace OpenSim.Framework.Monitoring pendingUploads = stats.StatsBlock[18].StatValue; activeScripts = stats.StatsBlock[19].StatValue; scriptLinesPerSecond = stats.StatsBlock[20].StatValue; + m_frameDilation = stats.StatsBlock[22].StatValue; + m_usersLoggingIn = stats.StatsBlock[23].StatValue; + m_totalGeoPrims = stats.StatsBlock[24].StatValue; + m_totalMeshes = stats.StatsBlock[25].StatValue; + m_inUseThreads = stats.StatsBlock[26].StatValue; } /// @@ -407,6 +422,27 @@ Asset service request failures: {3}" + Environment.NewLine, /// public override OSDMap OReport(string uptime, string version) { + // Get the amount of physical memory, allocated with the instance of this program, in kilobytes; + // the working set is the set of memory pages currently visible to this program in physical RAM + // memory and includes both shared (e.g. system libraries) and private data + double memUsage = Process.GetCurrentProcess().WorkingSet64 / 1024.0; + + // Get the number of threads from the system that are currently + // running + int numberThreadsRunning = 0; + foreach (ProcessThread currentThread in + Process.GetCurrentProcess().Threads) + { + // A known issue with the current process .Threads property is + // that it can return null threads, thus don't count those as + // running threads and prevent the program function from failing + if (currentThread != null && + currentThread.ThreadState == ThreadState.Running) + { + numberThreadsRunning++; + } + } + OSDMap args = new OSDMap(30); // args["AssetsInCache"] = OSD.FromString (String.Format ("{0:0.##}", AssetsInCache)); // args["TimeAfterCacheMiss"] = OSD.FromString (String.Format ("{0:0.##}", @@ -443,6 +479,22 @@ Asset service request failures: {3}" + Environment.NewLine, args["Memory"] = OSD.FromString (base.XReport (uptime, version)); args["Uptime"] = OSD.FromString (uptime); args["Version"] = OSD.FromString (version); + + args["FrameDilatn"] = OSD.FromString(String.Format("{0:0.##}", m_frameDilation)); + args["Logging in Users"] = OSD.FromString(String.Format("{0:0.##}", + m_usersLoggingIn)); + args["GeoPrims"] = OSD.FromString(String.Format("{0:0.##}", + m_totalGeoPrims)); + args["Mesh Objects"] = OSD.FromString(String.Format("{0:0.##}", + m_totalMeshes)); + args["XEngine Thread Count"] = OSD.FromString(String.Format("{0:0.##}", + m_inUseThreads)); + args["Util Thread Count"] = OSD.FromString(String.Format("{0:0.##}", + Util.GetSmartThreadPoolInfo().InUseThreads)); + args["System Thread Count"] = OSD.FromString(String.Format( + "{0:0.##}", numberThreadsRunning)); + args["ProcMem"] = OSD.FromString(String.Format("{0:#,###,###.##}", + memUsage)); return args; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 438dce963c..31900ec5c6 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1,29 +1,29 @@ /* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSimulator Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ using System; using System.Collections.Generic; @@ -48,7 +48,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Physics.Manager; -using Timer=System.Timers.Timer; +using Timer = System.Timers.Timer; using TPFlags = OpenSim.Framework.Constants.TeleportFlags; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using PermissionMask = OpenSim.Framework.PermissionMask; @@ -64,6 +64,8 @@ namespace OpenSim.Region.Framework.Scenes public const int m_defaultNumberFramesStored = 10; + public const int m_defaultNumberFramesStored = 10; + public delegate void SynchronizeSceneHandler(Scene scene); #region Fields @@ -105,9 +107,9 @@ namespace OpenSim.Region.Framework.Scenes /// /// If false then physical objects are disabled, though collisions will continue as normal. /// - public bool PhysicsEnabled - { - get + public bool PhysicsEnabled + { + get { return m_physicsEnabled; } @@ -121,8 +123,8 @@ namespace OpenSim.Region.Framework.Scenes IPhysicsParameters physScene = PhysicsScene as IPhysicsParameters; if (physScene != null) - physScene.SetPhysicsParameter( - "Active", m_physicsEnabled.ToString(), PhysParameterEntry.APPLY_TO_NONE); + physScene.SetPhysicsParameter( + "Active", m_physicsEnabled.ToString(), PhysParameterEntry.APPLY_TO_NONE); } } } @@ -132,10 +134,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// If false then scripts are not enabled on the smiulator /// - public bool ScriptsEnabled - { + public bool ScriptsEnabled + { get { return m_scripts_enabled; } - set + set { if (m_scripts_enabled != value) { @@ -147,13 +149,13 @@ namespace OpenSim.Region.Framework.Scenes foreach (EntityBase ent in entities) { if (ent is SceneObjectGroup) - ((SceneObjectGroup)ent).RemoveScriptInstances(false); + ((SceneObjectGroup)ent).RemoveScriptInstances(false); } } else { m_log.Info("Starting all Scripts in Scene"); - + EntityBase[] entities = Entities.GetEntities(); foreach (EntityBase ent in entities) { @@ -238,8 +240,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// Temporarily setting to trigger appearance resends at 60 second intervals. /// - public bool SendPeriodicAppearanceUpdates { get; set; } - + public bool SendPeriodicAppearanceUpdates { get; set; } + /// /// How much a root agent has to change position before updates are sent to viewers. /// @@ -266,10 +268,11 @@ namespace OpenSim.Region.Framework.Scenes public int ChildTerseUpdatePeriod { get; set; } protected float m_defaultDrawDistance = 255.0f; - public float DefaultDrawDistance + public float DefaultDrawDistance { // get { return m_defaultDrawDistance; } - get { + get + { if (RegionInfo != null) { float largestDimension = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); @@ -282,7 +285,7 @@ namespace OpenSim.Region.Framework.Scenes private List m_AllowedViewers = new List(); private List m_BannedViewers = new List(); - + // TODO: need to figure out how allow client agents but deny // root agents when ACL denies access to root agent public bool m_strictAccessControl = true; @@ -369,15 +372,15 @@ namespace OpenSim.Region.Framework.Scenes /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations /// occur too quickly (viewer 1) or with even more slide (viewer 2). /// - public int MinFrameTicks - { - get { return m_minFrameTicks; } - private set - { + public int MinFrameTicks + { + get { return m_minFrameTicks; } + private set + { m_minFrameTicks = value; MinFrameSeconds = (float)m_minFrameTicks / 1000; } - } + } private int m_minFrameTicks; /// @@ -405,7 +408,7 @@ namespace OpenSim.Region.Framework.Scenes private int m_update_events = 1; private int m_update_backup = 200; private int m_update_terrain = 50; -// private int m_update_land = 1; + // private int m_update_land = 1; private int m_update_coarse_locations = 50; private int m_update_temp_cleaning = 180; @@ -436,7 +439,7 @@ namespace OpenSim.Region.Framework.Scenes /// asynchronously from the update loop. /// private bool m_cleaningTemps = false; - + /// /// Used to control main scene thread looping time when not updating via timer. /// @@ -491,7 +494,7 @@ namespace OpenSim.Region.Framework.Scenes if (value) { if (!m_active) - Start(false); + Start(false); } else { @@ -528,6 +531,13 @@ namespace OpenSim.Region.Framework.Scenes get { return m_sceneGraph.PhysicsScene.TimeDilation; } } + public void setThreadCount(int inUseThreads) + { + // Just pass the thread count information on its way as the Scene + // does not require the value for anything at this time + StatsReporter.SetThreadCount(inUseThreads); + } + public SceneCommunicationService SceneGridService { get { return m_sceneGridService; } @@ -586,7 +596,7 @@ namespace OpenSim.Region.Framework.Scenes return m_AssetService; } } - + public IAuthorizationService AuthorizationService { get @@ -647,7 +657,7 @@ namespace OpenSim.Region.Framework.Scenes get { if (m_LibraryService == null) - m_LibraryService = RequestModuleInterface(); + m_LibraryService = RequestModuleInterface(); return m_LibraryService; } @@ -658,7 +668,7 @@ namespace OpenSim.Region.Framework.Scenes get { if (m_simulationService == null) - m_simulationService = RequestModuleInterface(); + m_simulationService = RequestModuleInterface(); return m_simulationService; } @@ -669,7 +679,7 @@ namespace OpenSim.Region.Framework.Scenes get { if (m_AuthenticationService == null) - m_AuthenticationService = RequestModuleInterface(); + m_AuthenticationService = RequestModuleInterface(); return m_AuthenticationService; } } @@ -679,7 +689,7 @@ namespace OpenSim.Region.Framework.Scenes get { if (m_PresenceService == null) - m_PresenceService = RequestModuleInterface(); + m_PresenceService = RequestModuleInterface(); return m_PresenceService; } } @@ -689,7 +699,7 @@ namespace OpenSim.Region.Framework.Scenes get { if (m_UserAccountService == null) - m_UserAccountService = RequestModuleInterface(); + m_UserAccountService = RequestModuleInterface(); return m_UserAccountService; } } @@ -699,7 +709,7 @@ namespace OpenSim.Region.Framework.Scenes get { if (m_AvatarService == null) - m_AvatarService = RequestModuleInterface(); + m_AvatarService = RequestModuleInterface(); return m_AvatarService; } } @@ -709,7 +719,7 @@ namespace OpenSim.Region.Framework.Scenes get { if (m_GridUserService == null) - m_GridUserService = RequestModuleInterface(); + m_GridUserService = RequestModuleInterface(); return m_GridUserService; } } @@ -723,7 +733,7 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_AvatarFactory; } } - + public ICapabilitiesModule CapsModule { get { return m_capsModule; } @@ -789,18 +799,20 @@ namespace OpenSim.Region.Framework.Scenes get { return m_sceneGraph.Entities; } } - + // used in sequence see: SpawnPoint() private int m_SpawnPoint; // can be closest/random/sequence public string SpawnPointRouting { - get; private set; + get; + private set; } // allow landmarks to pass public bool TelehubAllowLandmarks { - get; private set; + get; + private set; } #endregion Properties @@ -808,10 +820,10 @@ namespace OpenSim.Region.Framework.Scenes #region Constructors public Scene(RegionInfo regInfo, AgentCircuitManager authen, PhysicsScene physicsScene, - SceneCommunicationService sceneGridService, - ISimulationDataService simDataService, IEstateDataService estateDataService, - IConfigSource config, string simulatorVersion) - : this(regInfo, physicsScene) + SceneCommunicationService sceneGridService, + ISimulationDataService simDataService, IEstateDataService estateDataService, + IConfigSource config, string simulatorVersion) + : this(regInfo, physicsScene) { m_config = config; MinFrameTicks = 89; @@ -868,20 +880,20 @@ namespace OpenSim.Region.Framework.Scenes } if (updatedTerrainTextures) - rs.Save(); + rs.Save(); RegionInfo.RegionSettings = rs; if (estateDataService != null) - RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false); + RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false); #endregion Region Settings //Bind Storage Manager functions to some land manager functions for this scene EventManager.OnLandObjectAdded += - new EventManager.LandObjectAdded(simDataService.StoreLandObject); + new EventManager.LandObjectAdded(simDataService.StoreLandObject); EventManager.OnLandObjectRemoved += - new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); + new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); RegisterDefaultSceneEvents(); @@ -906,8 +918,8 @@ namespace OpenSim.Region.Framework.Scenes m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup); if (!UseBackup) - m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); - + m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName); + //Animation states m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); @@ -961,10 +973,10 @@ namespace OpenSim.Region.Framework.Scenes m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); m_dontPersistBefore = - startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE); + startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE); m_dontPersistBefore *= 10000000; m_persistAfter = - startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE); + startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE); m_persistAfter *= 10000000; m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); @@ -976,8 +988,8 @@ namespace OpenSim.Region.Framework.Scenes string[] possibleMapConfigSections = new string[] { "Map", "Startup" }; - m_generateMaptiles - = Util.GetConfigVarFromSections(config, "GenerateMaptiles", possibleMapConfigSections, true); + m_generateMaptiles + = Util.GetConfigVarFromSections(config, "GenerateMaptiles", possibleMapConfigSections, true); if (m_generateMaptiles) { @@ -993,9 +1005,9 @@ namespace OpenSim.Region.Framework.Scenes } else { - string tile - = Util.GetConfigVarFromSections( - config, "MaptileStaticUUID", possibleMapConfigSections, UUID.Zero.ToString()); + string tile + = Util.GetConfigVarFromSections( + config, "MaptileStaticUUID", possibleMapConfigSections, UUID.Zero.ToString()); UUID tileID; @@ -1012,9 +1024,9 @@ namespace OpenSim.Region.Framework.Scenes string[] possibleAccessControlConfigSections = new string[] { "AccessControl", "Startup" }; - string grant - = Util.GetConfigVarFromSections( - config, "AllowedClients", possibleAccessControlConfigSections, ""); + string grant + = Util.GetConfigVarFromSections( + config, "AllowedClients", possibleAccessControlConfigSections, ""); if (grant.Length > 0) { @@ -1024,9 +1036,9 @@ namespace OpenSim.Region.Framework.Scenes } } - grant - = Util.GetConfigVarFromSections( - config, "BannedClients", possibleAccessControlConfigSections, ""); + grant + = Util.GetConfigVarFromSections( + config, "BannedClients", possibleAccessControlConfigSections, ""); if (grant.Length > 0) { @@ -1037,27 +1049,27 @@ namespace OpenSim.Region.Framework.Scenes } if (startupConfig.Contains("MinFrameTime")) - MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000); + MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000); - m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); - m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); - m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement); - m_update_events = startupConfig.GetInt( "UpdateEventsEveryNFrames", m_update_events); - m_update_objects = startupConfig.GetInt( "UpdateObjectsEveryNFrames", m_update_objects); - m_update_physics = startupConfig.GetInt( "UpdatePhysicsEveryNFrames", m_update_physics); - m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences); - m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); - m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNSeconds", m_update_temp_cleaning); + m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup); + m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); + m_update_entitymovement = startupConfig.GetInt("UpdateEntityMovementEveryNFrames", m_update_entitymovement); + m_update_events = startupConfig.GetInt("UpdateEventsEveryNFrames", m_update_events); + m_update_objects = startupConfig.GetInt("UpdateObjectsEveryNFrames", m_update_objects); + m_update_physics = startupConfig.GetInt("UpdatePhysicsEveryNFrames", m_update_physics); + m_update_presences = startupConfig.GetInt("UpdateAgentsEveryNFrames", m_update_presences); + m_update_terrain = startupConfig.GetInt("UpdateTerrainEveryNFrames", m_update_terrain); + m_update_temp_cleaning = startupConfig.GetInt("UpdateTempCleaningEveryNSeconds", m_update_temp_cleaning); } // FIXME: Ultimately this should be in a module. SendPeriodicAppearanceUpdates = false; - + IConfig appearanceConfig = m_config.Configs["Appearance"]; if (appearanceConfig != null) { SendPeriodicAppearanceUpdates - = appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates); + = appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates); } #endregion Region Config @@ -1085,32 +1097,40 @@ namespace OpenSim.Region.Framework.Scenes UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time; } - IsReprioritizationEnabled - = interestConfig.GetBoolean("ReprioritizationEnabled", IsReprioritizationEnabled); - ReprioritizationInterval - = interestConfig.GetDouble("ReprioritizationInterval", ReprioritizationInterval); - RootReprioritizationDistance - = interestConfig.GetDouble("RootReprioritizationDistance", RootReprioritizationDistance); - ChildReprioritizationDistance - = interestConfig.GetDouble("ChildReprioritizationDistance", ChildReprioritizationDistance); + IsReprioritizationEnabled + = interestConfig.GetBoolean("ReprioritizationEnabled", IsReprioritizationEnabled); + ReprioritizationInterval + = interestConfig.GetDouble("ReprioritizationInterval", ReprioritizationInterval); + RootReprioritizationDistance + = interestConfig.GetDouble("RootReprioritizationDistance", RootReprioritizationDistance); + ChildReprioritizationDistance + = interestConfig.GetDouble("ChildReprioritizationDistance", ChildReprioritizationDistance); RootTerseUpdatePeriod = interestConfig.GetInt("RootTerseUpdatePeriod", RootTerseUpdatePeriod); ChildTerseUpdatePeriod = interestConfig.GetInt("ChildTerseUpdatePeriod", ChildTerseUpdatePeriod); - RootPositionUpdateTolerance - = interestConfig.GetFloat("RootPositionUpdateTolerance", RootPositionUpdateTolerance); + RootPositionUpdateTolerance + = interestConfig.GetFloat("RootPositionUpdateTolerance", RootPositionUpdateTolerance); RootRotationUpdateTolerance - = interestConfig.GetFloat("RootRotationUpdateTolerance", RootRotationUpdateTolerance); + = interestConfig.GetFloat("RootRotationUpdateTolerance", RootRotationUpdateTolerance); RootVelocityUpdateTolerance - = interestConfig.GetFloat("RootVelocityUpdateTolerance", RootVelocityUpdateTolerance); + = interestConfig.GetFloat("RootVelocityUpdateTolerance", RootVelocityUpdateTolerance); } m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", UpdatePrioritizationScheme); #endregion Interest Management + // The timer used by the Stopwatch class depends on the system hardware and operating system; inform + // if the timer is based on a high-resolution performance counter or based on the system timer; + // the performance counter will provide a more precise time than the system timer + if (Stopwatch.IsHighResolution) + m_log.InfoFormat("[SCENE]: Using high-resolution performance counter for statistics."); + else + m_log.InfoFormat("[SCENE]: Using system timer for statistics."); + // Acquire the statistics section of the OpenSim.ini file located - // in the bin directory + // in the bin directory IConfig statisticsConfig = m_config.Configs["Statistics"]; // Confirm that the statistics section existed in the configuration @@ -1118,9 +1138,9 @@ namespace OpenSim.Region.Framework.Scenes if (statisticsConfig != null) { // Create the StatsReporter using the number of frames to store - // for the frame time statistics, or 10 frames if the config + // for the frame time statistics, or 10 frames if the config // file doesn't contain a value - StatsReporter = new SimStatsReporter(this, + StatsReporter = new SimStatsReporter(this, statisticsConfig.GetInt("NumberOfFrames", m_defaultNumberFramesStored)); } @@ -1130,14 +1150,15 @@ namespace OpenSim.Region.Framework.Scenes // 10 frames stored for the frame time statistics StatsReporter = new SimStatsReporter(this); } - + StatsReporter.OnSendStatsResult += SendSimStatsPackets; StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; } - public Scene(RegionInfo regInfo, PhysicsScene physicsScene) : base(regInfo) - { + public Scene(RegionInfo regInfo, PhysicsScene physicsScene) + : base(regInfo) + { m_sceneGraph = new SceneGraph(this); m_sceneGraph.PhysicsScene = physicsScene; @@ -1147,11 +1168,11 @@ namespace OpenSim.Region.Framework.Scenes // // Out of memory // Operating system has killed the plugin - m_sceneGraph.UnRecoverableError - += () => - { - m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name); - RestartNow(); + m_sceneGraph.UnRecoverableError + += () => + { + m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name); + RestartNow(); }; PhysicalPrims = true; @@ -1196,7 +1217,7 @@ namespace OpenSim.Region.Framework.Scenes IDialogModule dm = RequestModuleInterface(); if (dm != null) - m_eventManager.OnPermissionError += dm.SendAlertToUser; + m_eventManager.OnPermissionError += dm.SendAlertToUser; m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement; } @@ -1226,7 +1247,7 @@ namespace OpenSim.Region.Framework.Scenes //int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY); //if (resultX <= 1 && resultY <= 1) float dist = (float)Math.Max(DefaultDrawDistance, - (float)Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY)); + (float)Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY)); uint newRegionX, newRegionY, thisRegionX, thisRegionY; Util.RegionHandleToRegionLoc(otherRegion.RegionHandle, out newRegionX, out newRegionY); Util.RegionHandleToRegionLoc(RegionInfo.RegionHandle, out thisRegionX, out thisRegionY); @@ -1250,7 +1271,7 @@ namespace OpenSim.Region.Framework.Scenes old.Add(otherRegion.RegionHandle); agent.DropOldNeighbours(old); if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) - EntityTransferModule.EnableChildAgent(agent, otherRegion); + EntityTransferModule.EnableChildAgent(agent, otherRegion); }); } catch (NullReferenceException) @@ -1263,8 +1284,8 @@ namespace OpenSim.Region.Framework.Scenes else { m_log.InfoFormat( - "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})", - otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY); + "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})", + otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY); } } } @@ -1342,7 +1363,7 @@ namespace OpenSim.Region.Framework.Scenes ForEachRootScenePresence(delegate(ScenePresence agent) { if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) - EntityTransferModule.EnableChildAgent(agent, r); + EntityTransferModule.EnableChildAgent(agent, r); }); } catch (NullReferenceException) @@ -1380,14 +1401,14 @@ namespace OpenSim.Region.Framework.Scenes // Kick all ROOT agents with the message, 'The simulator is going down' ForEachScenePresence(delegate(ScenePresence avatar) - { - avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle); + { + avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle); - if (!avatar.IsChildAgent) - avatar.ControllingClient.Kick("The simulator is going down."); + if (!avatar.IsChildAgent) + avatar.ControllingClient.Kick("The simulator is going down."); - avatar.ControllingClient.SendShutdownConnectionNotice(); - }); + avatar.ControllingClient.SendShutdownConnectionNotice(); + }); // Stop updating the scene objects and agents. m_shuttingDown = true; @@ -1406,7 +1427,7 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGraph.Close(); if (!GridService.DeregisterRegion(RegionInfo.RegionID)) - m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name); + m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name); base.Close(); @@ -1437,12 +1458,12 @@ namespace OpenSim.Region.Framework.Scenes public void Start(bool startScripts) { if (IsRunning) - return; + return; m_isRunning = true; m_active = true; -// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); + // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); if (m_heartbeatThread != null) { m_heartbeatThread.Abort(); @@ -1450,8 +1471,8 @@ namespace OpenSim.Region.Framework.Scenes } m_heartbeatThread - = WorkManager.StartThread( - Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); + = WorkManager.StartThread( + Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); StartScripts(); } @@ -1492,7 +1513,7 @@ namespace OpenSim.Region.Framework.Scenes Update(1); WorkManager.StartThread( - Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); + Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; m_lastFrameTick = Util.EnvironmentTickCount(); @@ -1516,15 +1537,15 @@ namespace OpenSim.Region.Framework.Scenes private volatile bool m_isTimerUpdateRunning; private void Update(object sender, ElapsedEventArgs e) - { + { if (m_isTimerUpdateRunning) - return; + return; m_isTimerUpdateRunning = true; // If the last frame did not complete on time, then immediately start the next update on the same thread // and ignore further timed updates until we have a frame that had spare time. - while (!Update(1) && Active) {} + while (!Update(1) && Active) { } if (!Active || m_shuttingDown) { @@ -1550,7 +1571,7 @@ namespace OpenSim.Region.Framework.Scenes int previousMaintenanceTick; if (runs >= 0) - endRun = MaintenanceRun + runs; + endRun = MaintenanceRun + runs; List coarseLocations; List avatarUUIDs; @@ -1560,7 +1581,7 @@ namespace OpenSim.Region.Framework.Scenes runtc = Util.EnvironmentTickCount(); ++MaintenanceRun; -// m_log.DebugFormat("[SCENE]: Maintenance run {0} in {1}", MaintenanceRun, Name); + // m_log.DebugFormat("[SCENE]: Maintenance run {0} in {1}", MaintenanceRun, Name); // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) if (MaintenanceRun % (m_update_coarse_locations / 10) == 0) @@ -1575,7 +1596,7 @@ namespace OpenSim.Region.Framework.Scenes if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0) { -// m_log.DebugFormat("[SCENE]: Sending periodic appearance updates"); + // m_log.DebugFormat("[SCENE]: Sending periodic appearance updates"); if (AvatarFactory != null) { @@ -1586,14 +1607,14 @@ namespace OpenSim.Region.Framework.Scenes // Delete temp-on-rez stuff if (MaintenanceRun % m_update_temp_cleaning == 0 && !m_cleaningTemps) { -// m_log.DebugFormat("[SCENE]: Running temp-on-rez cleaning in {0}", Name); + // m_log.DebugFormat("[SCENE]: Running temp-on-rez cleaning in {0}", Name); tmpMS = Util.EnvironmentTickCount(); m_cleaningTemps = true; WorkManager.RunInThread( - delegate { CleanTempObjects(); m_cleaningTemps = false; }, - null, - string.Format("CleanTempObjects ({0})", Name)); + delegate { CleanTempObjects(); m_cleaningTemps = false; }, + null, + string.Format("CleanTempObjects ({0})", Name)); tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); } @@ -1604,19 +1625,19 @@ namespace OpenSim.Region.Framework.Scenes m_lastMaintenanceTick = Util.EnvironmentTickCount(); runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); runtc = MinMaintenanceTicks - runtc; - + if (runtc > 0) - m_maintenanceWaitEvent.WaitOne(runtc); - + m_maintenanceWaitEvent.WaitOne(runtc); + // Optionally warn if a frame takes double the amount of time that it should. if (DebugUpdates - && Util.EnvironmentTickCountSubtract( - m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2) - m_log.WarnFormat( - "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", - Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), - MinMaintenanceTicks, - RegionInfo.RegionName); + && Util.EnvironmentTickCountSubtract( + m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2) + m_log.WarnFormat( + "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", + Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), + MinMaintenanceTicks, + RegionInfo.RegionName); } } @@ -1625,14 +1646,14 @@ namespace OpenSim.Region.Framework.Scenes long? endFrame = null; if (frames >= 0) - endFrame = Frame + frames; + endFrame = Frame + frames; float physicsFPS = 0f; int previousFrameTick, tmpMS; // These variables will be used to save the precise frame time using the // Stopwatch class of Microsoft SDK; the times are recorded at the start - // and end of a particular section of code, and then used to calculate + // and end of a parcticular section of code, and then used to calculate // the frame times, which are the sums of the sections for each given name double preciseTotalFrameTime = 0.0; double preciseSimFrameTime = 0.0; @@ -1644,12 +1665,12 @@ namespace OpenSim.Region.Framework.Scenes // Begin the stopwatch to keep track of the time that the frame // started running to determine how long the frame took to complete totalFrameStopwatch.Start(); - + while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame)) { ++Frame; -// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); + // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); agentMS = eventMS = backupMS = terrainMS = landMS = spareMS = 0; @@ -1670,48 +1691,56 @@ namespace OpenSim.Region.Framework.Scenes // at this point in time, the precise values all begin // with the keyword precise tmpMS = Util.EnvironmentTickCount(); - simFrameStopwatch.Start(); UpdateTerrain(); - + // Get the simulation frame time that the avatar force - // input took + // input took simFrameStopwatch.Stop(); - preciseSimFrameTime = - simFrameStopwatch.Elapsed.TotalMilliseconds; + preciseSimFrameTime = + simFrameStopwatch.Elapsed.TotalMilliseconds; terrainMS = Util.EnvironmentTickCountSubtract(tmpMS); } + // At several points inside the code there was a need to + // create a more precise measurement of time elapsed. This + // led to the addition of variables that have a similar + // function and thus remain tightly connected to their + // original counterparts. However, the original code is + // not receiving comments from our group because we don't + // feel right modifying the code to that degree at this + // point in time, the precise values all begin with the + // keyword precise + tmpMS = Util.EnvironmentTickCount(); - + // Begin the stopwatch to track the time to prepare physics physicsFrameStopwatch.Start(); if (PhysicsEnabled && Frame % m_update_physics == 0) - m_sceneGraph.UpdatePreparePhysics(); - + m_sceneGraph.UpdatePreparePhysics(); + // Get the time it took to prepare the physics, this // would report the most precise time that physics was // running on the machine and should the physics not be // enabled will report the time it took to check if physics // was enabled physicsFrameStopwatch.Stop(); - precisePhysicsFrameTime = - physicsFrameStopwatch.Elapsed.TotalMilliseconds; + precisePhysicsFrameTime = physicsFrameStopwatch.Elapsed.TotalMilliseconds; physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS); - + // Apply any pending avatar force input to the avatar's velocity tmpMS = Util.EnvironmentTickCount(); simFrameStopwatch.Restart(); if (Frame % m_update_entitymovement == 0) - m_sceneGraph.UpdateScenePresenceMovement(); - + m_sceneGraph.UpdateScenePresenceMovement(); + // Get the simulation frame time that the avatar force input - // took + // took simFrameStopwatch.Stop(); - preciseSimFrameTime += - simFrameStopwatch.Elapsed.TotalMilliseconds; + preciseSimFrameTime += + simFrameStopwatch.Elapsed.TotalMilliseconds; agentMS = Util.EnvironmentTickCountSubtract(tmpMS); - + // Perform the main physics update. This will do the actual work of moving objects and avatars according to their // velocity tmpMS = Util.EnvironmentTickCount(); @@ -1719,63 +1748,61 @@ namespace OpenSim.Region.Framework.Scenes if (Frame % m_update_physics == 0) { if (PhysicsEnabled) - physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds); - + physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds); + if (SynchronizeScene != null) - SynchronizeScene(this); + SynchronizeScene(this); } - - // Add the main physics update time to the prepare physics - // time + + // Add the main physics update time to the prepare physics time physicsFrameStopwatch.Stop(); - precisePhysicsFrameTime += - physicsFrameStopwatch.Elapsed.TotalMilliseconds; + precisePhysicsFrameTime += physicsFrameStopwatch.Elapsed.TotalMilliseconds; physicsMS = Util.EnvironmentTickCountSubtract(tmpMS); - // Start the stopwatch for the remainder of the simulation + // Start the stopwatch for the remainder of the simulation simFrameStopwatch.Restart(); tmpMS = Util.EnvironmentTickCount(); - + // Check if any objects have reached their targets CheckAtTargets(); - + // Update SceneObjectGroups that have scheduled themselves for updates // Objects queue their updates onto all scene presences if (Frame % m_update_objects == 0) - m_sceneGraph.UpdateObjectGroups(); + m_sceneGraph.UpdateObjectGroups(); // Run through all ScenePresences looking for updates // Presence updates and queued object updates for each presence are sent to clients if (Frame % m_update_presences == 0) - m_sceneGraph.UpdatePresences(); - - agentMS += Util.EnvironmentTickCountSubtract(tmpMS); - + m_sceneGraph.UpdatePresences(); + + agentMS += Util.EnvironmentTickCountSubtract(tmpMS); + if (Frame % m_update_events == 0) { tmpMS = Util.EnvironmentTickCount(); UpdateEvents(); eventMS = Util.EnvironmentTickCountSubtract(tmpMS); } - + if (PeriodicBackup && Frame % m_update_backup == 0) { tmpMS = Util.EnvironmentTickCount(); UpdateStorageBackup(); backupMS = Util.EnvironmentTickCountSubtract(tmpMS); } - + //if (Frame % m_update_land == 0) //{ // int ldMS = Util.EnvironmentTickCount(); // UpdateLand(); // landMS = Util.EnvironmentTickCountSubtract(ldMS); //} - + if (!LoginsEnabled && Frame == 20) { - // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); - + // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); + // In 99.9% of cases it is a bad idea to manually force garbage collection. However, // this is a rare case where we know we have just went through a long cycle of heap // allocations, and there is no more work to be done until someone logs in @@ -1790,7 +1817,7 @@ namespace OpenSim.Region.Framework.Scenes } m_sceneGridService.InformNeighborsThatRegionisUp( - RequestModuleInterface(), RegionInfo); + RequestModuleInterface(), RegionInfo); // Region ready should always be set Ready = true; @@ -1801,7 +1828,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_sceneGraph.GetActiveScriptsCount() == 0) { // In this case, we leave it to the IRegionReadyModule to enable logins - + // LoginLock can currently only be set by a region module implementation. // If somehow this hasn't been done then the quickest way to bugfix is to see the // NullReferenceException @@ -1814,18 +1841,18 @@ namespace OpenSim.Region.Framework.Scenes catch (Exception e) { m_log.ErrorFormat( - "[SCENE]: Failed on region {0} with exception {1}{2}", - RegionInfo.RegionName, e.Message, e.StackTrace); + "[SCENE]: Failed on region {0} with exception {1}{2}", + RegionInfo.RegionName, e.Message, e.StackTrace); } - + EventManager.TriggerRegionHeartbeatEnd(this); otherMS = eventMS + backupMS + terrainMS + landMS; // Get the elapsed time for the simulation frame simFrameStopwatch.Stop(); - preciseSimFrameTime += - simFrameStopwatch.Elapsed.TotalMilliseconds; - + preciseSimFrameTime += + simFrameStopwatch.Elapsed.TotalMilliseconds; + if (!UpdateOnTimer) { Watchdog.UpdateThread(); @@ -1833,9 +1860,9 @@ namespace OpenSim.Region.Framework.Scenes spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick); if (spareMS > 0) - m_updateWaitEvent.WaitOne(spareMS); + m_updateWaitEvent.WaitOne(spareMS); else - spareMS = 0; + spareMS = 0; } else { @@ -1844,15 +1871,15 @@ namespace OpenSim.Region.Framework.Scenes // Get the total frame time totalFrameStopwatch.Stop(); - preciseTotalFrameTime = - totalFrameStopwatch.Elapsed.TotalMilliseconds; + preciseTotalFrameTime = + totalFrameStopwatch.Elapsed.TotalMilliseconds; // Restart the stopwatch for the total time of the next frame totalFrameStopwatch.Restart(); - + previousFrameTick = m_lastFrameTick; frameMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick); - m_lastFrameTick = Util.EnvironmentTickCount(); + m_lastFrameTick = Util.EnvironmentTickCount(); // if (Frame%m_update_avatars == 0) // UpdateInWorldTime(); @@ -1869,37 +1896,40 @@ namespace OpenSim.Region.Framework.Scenes // Send the correct time values to the stats reporter for the // frame times - StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime, - preciseSimFrameTime, precisePhysicsFrameTime, 0.0); + StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime, + preciseSimFrameTime, precisePhysicsFrameTime, 0.0); // Send the correct number of frames that the physics library // has processed to the stats reporter StatsReporter.addPhysicsFrame(1); - + // Optionally warn if a frame takes double the amount of time that it should. if (DebugUpdates - && Util.EnvironmentTickCountSubtract( - m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2) - m_log.WarnFormat( - "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", - Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), - MinFrameTicks, - RegionInfo.RegionName); + && Util.EnvironmentTickCountSubtract( + m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2) + m_log.WarnFormat( + "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", + Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), + MinFrameTicks, + RegionInfo.RegionName); } + // Finished updating scene frame, so stop the total frame's Stopwatch + totalFrameStopwatch.Stop(); + return spareMS >= 0; - } + } public void AddGroupTarget(SceneObjectGroup grp) { lock (m_groupsWithTargets) - m_groupsWithTargets[grp.UUID] = grp; + m_groupsWithTargets[grp.UUID] = grp; } public void RemoveGroupTarget(SceneObjectGroup grp) { lock (m_groupsWithTargets) - m_groupsWithTargets.Remove(grp.UUID); + m_groupsWithTargets.Remove(grp.UUID); } private void CheckAtTargets() @@ -1909,13 +1939,13 @@ namespace OpenSim.Region.Framework.Scenes lock (m_groupsWithTargets) { if (m_groupsWithTargets.Count != 0) - objs = new List(m_groupsWithTargets.Values); + objs = new List(m_groupsWithTargets.Values); } if (objs != null) { foreach (SceneObjectGroup entry in objs) - entry.checkAtTargets(); + entry.checkAtTargets(); } } @@ -1958,7 +1988,7 @@ namespace OpenSim.Region.Framework.Scenes { m_eventManager.TriggerOnFrame(); } - + /// /// Backup the scene. /// @@ -1998,13 +2028,13 @@ namespace OpenSim.Region.Framework.Scenes // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3. msg.binaryBucket = Util.StringToBytes256("\0"); if (ret.Value.count > 1) - msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); + msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); else - msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); + msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); IMessageTransferModule tr = RequestModuleInterface(); if (tr != null) - tr.SendInstantMessage(msg, delegate(bool success) {}); + tr.SendInstantMessage(msg, delegate(bool success) { }); } m_returns.Clear(); } @@ -2095,7 +2125,7 @@ namespace OpenSim.Region.Framework.Scenes IConfig terrainConfig = m_config.Configs["Terrain"]; String m_InitialTerrain = "pinhead-island"; if (terrainConfig != null) - m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); + m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain); Heightmap = new TerrainChannel(m_InitialTerrain, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ); @@ -2110,11 +2140,11 @@ namespace OpenSim.Region.Framework.Scenes catch (IOException e) { m_log.WarnFormat( - "[TERRAIN]: Scene.cs: LoadWorldMap() - Regenerating as failed with exception {0}{1}", - e.Message, e.StackTrace); - + "[TERRAIN]: Scene.cs: LoadWorldMap() - Regenerating as failed with exception {0}{1}", + e.Message, e.StackTrace); + // Non standard region size. If there's an old terrain in the database, it might read past the buffer - #pragma warning disable 0162 +#pragma warning disable 0162 if ((int)Constants.RegionSize != 256) { Heightmap = new TerrainChannel(); @@ -2125,7 +2155,7 @@ namespace OpenSim.Region.Framework.Scenes catch (Exception e) { m_log.WarnFormat( - "[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception {0}{1}", e.Message, e.StackTrace); + "[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception {0}{1}", e.Message, e.StackTrace); } } @@ -2142,18 +2172,18 @@ namespace OpenSim.Region.Framework.Scenes //// stored in the GridService, because that's what the world map module uses //// to send the map image UUIDs (of other regions) to the viewer... if (m_generateMaptiles) - RegenerateMaptile(); + RegenerateMaptile(); GridRegion region = new GridRegion(RegionInfo); string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); -// m_log.DebugFormat("[SCENE]: RegisterRegionWithGrid. name={0},id={1},loc=<{2},{3}>,size=<{4},{5}>", -// m_regionName, -// RegionInfo.RegionID, -// RegionInfo.RegionLocX, RegionInfo.RegionLocY, -// RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); + // m_log.DebugFormat("[SCENE]: RegisterRegionWithGrid. name={0},id={1},loc=<{2},{3}>,size=<{4},{5}>", + // m_regionName, + // RegionInfo.RegionID, + // RegionInfo.RegionLocX, RegionInfo.RegionLocY, + // RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); if (error != String.Empty) - throw new Exception(error); + throw new Exception(error); } #endregion @@ -2212,7 +2242,7 @@ namespace OpenSim.Region.Framework.Scenes rootPart.TrimPermissions(); // Don't do this here - it will get done later on when sculpt data is loaded. -// group.CheckSculptAndLoad(); + // group.CheckSculptAndLoad(); } LoadingPrims = false; @@ -2222,15 +2252,15 @@ namespace OpenSim.Region.Framework.Scenes public bool SupportsRayCastFiltered() { if (PhysicsScene == null) - return false; + return false; return PhysicsScene.SupportsRaycastWorldFiltered(); } public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter) { if (PhysicsScene == null) - return null; - return PhysicsScene.RaycastWorld(position, direction, length, Count,filter); + return null; + return PhysicsScene.RaycastWorld(position, direction, length, Count, filter); } /// @@ -2298,7 +2328,7 @@ namespace OpenSim.Region.Framework.Scenes //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method // Un-offset the prim (it gets offset later by the consumer method) //pos.Z -= 0.25F; - + } return pos; @@ -2315,7 +2345,7 @@ namespace OpenSim.Region.Framework.Scenes if (ei.HitTF) { pos = ei.ipoint; - } + } else { // fall back to our stupid functionality @@ -2351,8 +2381,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// public virtual void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape, - byte bypassRaycast, Vector3 RayStart, UUID RayTargetID, - byte RayEndIsIntersection) + byte bypassRaycast, Vector3 RayStart, UUID RayTargetID, + byte RayEndIsIntersection) { Vector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false); @@ -2367,18 +2397,18 @@ namespace OpenSim.Region.Framework.Scenes { IClientAPI client = null; if (TryGetClient(ownerID, out client)) - client.SendAlertMessage("You cannot create objects here."); + client.SendAlertMessage("You cannot create objects here."); } } public virtual SceneObjectGroup AddNewPrim( - UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) + UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) { //m_log.DebugFormat( // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName); SceneObjectGroup sceneObject = null; - + // If an entity creator has been registered for this prim type then use that if (m_entityCreators.ContainsKey((PCode)shape.PCode)) { @@ -2393,13 +2423,13 @@ namespace OpenSim.Region.Framework.Scenes } if (UserManagementModule != null) - sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID); + sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID); sceneObject.ScheduleGroupForFullUpdate(); return sceneObject; } - + /// /// Add an object into the scene that has come from storage /// @@ -2421,7 +2451,7 @@ namespace OpenSim.Region.Framework.Scenes /// true if the object was added, false if an object with the same uuid was already in the scene /// public bool AddRestoredSceneObject( - SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) + SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) { if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates)) { @@ -2432,7 +2462,7 @@ namespace OpenSim.Region.Framework.Scenes return false; } - + /// /// Add an object into the scene that has come from storage /// @@ -2450,7 +2480,7 @@ namespace OpenSim.Region.Framework.Scenes /// true if the object was added, false if an object with the same uuid was already in the scene /// public bool AddRestoredSceneObject( - SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) + SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) { return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); } @@ -2468,7 +2498,7 @@ namespace OpenSim.Region.Framework.Scenes { return AddNewSceneObject(sceneObject, attachToBackup, true); } - + /// /// Add a newly created object to the scene /// @@ -2483,16 +2513,16 @@ namespace OpenSim.Region.Framework.Scenes /// /// true if the object was added. false if not public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) - { + { if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates)) { EventManager.TriggerObjectAddedToScene(sceneObject); - return true; + return true; } - + return false; } - + /// /// Add a newly created object to the scene. /// @@ -2506,10 +2536,10 @@ namespace OpenSim.Region.Framework.Scenes /// Velocity of the object. This parameter only has an effect if the object is physical /// public bool AddNewSceneObject( - SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel) + SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel) { if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel)) - { + { EventManager.TriggerObjectAddedToScene(sceneObject); return true; } @@ -2531,7 +2561,7 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup sog = (SceneObjectGroup)e; if (!sog.IsAttachment) - DeleteSceneObject((SceneObjectGroup)e, false); + DeleteSceneObject((SceneObjectGroup)e, false); } } } @@ -2557,13 +2587,13 @@ namespace OpenSim.Region.Framework.Scenes /// Suppress broadcasting changes to other clients. /// If true, then scripts are removed. If false, then they are only stopped. public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts) - { -// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); + { + // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); if (removeScripts) - group.RemoveScriptInstances(true); + group.RemoveScriptInstances(true); else - group.StopScriptInstances(); + group.StopScriptInstances(); SceneObjectPart[] partList = group.Parts; @@ -2593,7 +2623,7 @@ namespace OpenSim.Region.Framework.Scenes group.DeleteGroupFromScene(silent); -// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); + // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); } /// @@ -2613,12 +2643,12 @@ namespace OpenSim.Region.Framework.Scenes // database update, because RemoveObject() works by searching on the SceneGroupID. // This is an expensive thing to do so only do it if absolutely necessary. if (so.GroupContainsForeignPrims) - ForceSceneObjectBackup(so); + ForceSceneObjectBackup(so); so.DetachFromBackup(); SimulationDataService.RemoveObject(so.UUID, RegionInfo.RegionID); } - + // We need to keep track of this state in case this group is still queued for further backup. so.IsDeleted = true; @@ -2638,9 +2668,9 @@ namespace OpenSim.Region.Framework.Scenes public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent) { if (grp == null) - return; + return; if (grp.IsDeleted) - return; + return; if (grp.RootPart.DIE_AT_EDGE) { @@ -2674,7 +2704,7 @@ namespace OpenSim.Region.Framework.Scenes } if (EntityTransferModule != null) - EntityTransferModule.Cross(grp, attemptedPosition, silent); + EntityTransferModule.Cross(grp, attemptedPosition, silent); } // Simple test to see if a position is in the current region. @@ -2687,14 +2717,14 @@ namespace OpenSim.Region.Framework.Scenes int xx = (int)Math.Floor(pos.X); int yy = (int)Math.Floor(pos.Y); if (xx < 0 || yy < 0) - return false; + return false; IRegionCombinerModule regionCombinerModule = RequestModuleInterface(); if (regionCombinerModule == null) { // Regular region. Just check for region size - if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) - ret = true; + if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY) + ret = true; } else { @@ -2728,7 +2758,7 @@ namespace OpenSim.Region.Framework.Scenes } if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition)) - return false; + return false; // Do this as late as possible so that listeners have full access to the incoming object EventManager.TriggerOnIncomingSceneObject(newObject); @@ -2749,13 +2779,13 @@ namespace OpenSim.Region.Framework.Scenes // SceneObjectPart[] parts = sceneObject.Parts; for (int i = 0; i < parts.Length; i++) - parts[i].LocalId = 0; + parts[i].LocalId = 0; if (sceneObject.IsAttachmentCheckFull()) // Attachment { sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); sceneObject.RootPart.AddFlag(PrimFlags.Phantom); - + // Don't sent a full update here because this will cause full updates to be sent twice for // attachments on region crossings, resulting in viewer glitches. AddRestoredSceneObject(sceneObject, false, false, false); @@ -2770,10 +2800,10 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup grp = sceneObject; -// m_log.DebugFormat( -// "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); -// m_log.DebugFormat( -// "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); + // m_log.DebugFormat( + // "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); + // m_log.DebugFormat( + // "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); RootPrim.RemFlag(PrimFlags.TemporaryOnRez); @@ -2781,7 +2811,7 @@ namespace OpenSim.Region.Framework.Scenes // information that this is due to a teleport/border cross rather than an ordinary attachment. // We currently do this in Scene.MakeRootAgent() instead. if (AttachmentsModule != null) - AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); + AttachmentsModule.AttachObject(sp, grp, 0, false, false, true); } else { @@ -2807,6 +2837,9 @@ namespace OpenSim.Region.Framework.Scenes bool vialogin; bool reallyNew = true; + // Update the number of users attempting to login + StatsReporter.UpdateUsersLoggingIn(true); + // Validation occurs in LLUDPServer // // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with @@ -2827,11 +2860,11 @@ namespace OpenSim.Region.Framework.Scenes lock (aCircuit) { vialogin - = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 - || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; - - // CheckHeartbeat(); - + = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 + || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; + + // CheckHeartbeat(); + sp = GetScenePresence(client.AgentId); // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this @@ -2841,9 +2874,9 @@ namespace OpenSim.Region.Framework.Scenes if (sp == null) { m_log.DebugFormat( - "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", - client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); - + "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", + client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); + sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the @@ -2860,7 +2893,7 @@ namespace OpenSim.Region.Framework.Scenes m_clientManager.Add(client); SubscribeToClientEvents(client); m_eventManager.TriggerOnNewPresence(sp); - + sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; } else @@ -2873,24 +2906,28 @@ namespace OpenSim.Region.Framework.Scenes client.SceneAgent = sp; m_log.WarnFormat( - "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", - sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); + "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", + sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); reallyNew = false; - } + } // This is currently also being done earlier in NewUserConnection for real users to see if this // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other // places. However, we still need to do it here for NPCs. CacheUserName(sp, aCircuit); - + if (reallyNew) - EventManager.TriggerOnNewClient(client); - + EventManager.TriggerOnNewClient(client); + if (vialogin) - EventManager.TriggerOnClientLogin(client); + EventManager.TriggerOnClientLogin(client); } + // User has logged into the scene so update the list of users logging + // in + StatsReporter.UpdateUsersLoggingIn(false); + m_LastLogin = Util.EnvironmentTickCount(); return sp; @@ -2903,9 +2940,9 @@ namespace OpenSim.Region.Framework.Scenes { AgentCircuitData circuit = AuthenticateHandler.GetAgentCircuitData(agentID); if (circuit != null && circuit.ServiceURLs != null && circuit.ServiceURLs.ContainsKey("HomeURI")) - return circuit.ServiceURLs["HomeURI"].ToString(); + return circuit.ServiceURLs["HomeURI"].ToString(); else - return null; + return null; } /// @@ -2928,7 +2965,7 @@ namespace OpenSim.Region.Framework.Scenes string homeURL = string.Empty; if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) - homeURL = aCircuit.ServiceURLs["HomeURI"].ToString(); + homeURL = aCircuit.ServiceURLs["HomeURI"].ToString(); if (aCircuit.lastname.StartsWith("@")) { @@ -2948,7 +2985,7 @@ namespace OpenSim.Region.Framework.Scenes private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin) { vialogin = false; - + // Do the verification here if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) { @@ -2964,7 +3001,7 @@ namespace OpenSim.Region.Framework.Scenes return false; } else - m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); + m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); } } @@ -2972,7 +3009,7 @@ namespace OpenSim.Region.Framework.Scenes else if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0) { m_log.DebugFormat("[SCENE]: Incoming client {0} {1} in region {2} via regular login. Client IP verification not performed.", - aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); + aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); vialogin = true; } @@ -3016,7 +3053,7 @@ namespace OpenSim.Region.Framework.Scenes } } else - return true; + return true; } return false; @@ -3043,7 +3080,7 @@ namespace OpenSim.Region.Framework.Scenes { client.OnRegionHandShakeReply += SendLayerData; } - + public virtual void SubscribeToClientPrimEvents(IClientAPI client) { client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition; @@ -3053,7 +3090,7 @@ namespace OpenSim.Region.Framework.Scenes client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation; client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition; - + client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale; client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale; client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam; @@ -3066,7 +3103,7 @@ namespace OpenSim.Region.Framework.Scenes client.OnSpinStart += m_sceneGraph.SpinStart; client.OnSpinUpdate += m_sceneGraph.SpinObject; client.OnDeRezObject += DeRezObjects; - + client.OnObjectName += m_sceneGraph.PrimName; client.OnObjectClickAction += m_sceneGraph.PrimClickAction; client.OnObjectMaterial += m_sceneGraph.PrimMaterial; @@ -3078,7 +3115,7 @@ namespace OpenSim.Region.Framework.Scenes client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily; client.OnObjectPermissions += HandleObjectPermissionsUpdate; client.OnGrabObject += ProcessObjectGrab; - client.OnGrabUpdate += ProcessObjectGrabUpdate; + client.OnGrabUpdate += ProcessObjectGrabUpdate; client.OnDeGrabObject += ProcessObjectDeGrab; client.OnUndo += m_sceneGraph.HandleUndo; client.OnRedo += m_sceneGraph.HandleRedo; @@ -3139,7 +3176,7 @@ namespace OpenSim.Region.Framework.Scenes //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; } - + public virtual void SubscribeToClientNetworkEvents(IClientAPI client) { client.OnNetworkStatsUpdate += StatsReporter.AddPacketsStats; @@ -3300,7 +3337,7 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup copy = SceneGraph.DuplicateObject(originalPrim, offset, flags, AgentID, GroupID, Quaternion.Identity); if (copy != null) - EventManager.TriggerObjectAddedToScene(copy); + EventManager.TriggerObjectAddedToScene(copy); } /// @@ -3319,8 +3356,8 @@ namespace OpenSim.Region.Framework.Scenes /// Position the object at the center of the face that it's colliding with /// Rotate the object the same as the localID object public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID, - UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart, - bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates) + UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart, + bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates) { Vector3 pos; const bool frontFacesOnly = true; @@ -3381,7 +3418,7 @@ namespace OpenSim.Region.Framework.Scenes } if (copy != null) - EventManager.TriggerObjectAddedToScene(copy); + EventManager.TriggerObjectAddedToScene(copy); } } } @@ -3432,25 +3469,25 @@ namespace OpenSim.Region.Framework.Scenes if (acd == null) { m_log.ErrorFormat( - "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name); + "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name); return; } // TODO: Can we now remove this lock? lock (acd) - { + { bool isChildAgent = false; ScenePresence avatar = GetScenePresence(agentID); - + // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not // However, will keep for now just in case. if (avatar == null) { m_log.ErrorFormat( - "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); + "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); m_authenticateHandler.RemoveCircuit(agentID); return; @@ -3461,9 +3498,9 @@ namespace OpenSim.Region.Framework.Scenes isChildAgent = avatar.IsChildAgent; m_log.DebugFormat( - "[SCENE]: Removing {0} agent {1} {2} from {3}", - isChildAgent ? "child" : "root", avatar.Name, agentID, Name); - + "[SCENE]: Removing {0} agent {1} {2} from {3}", + isChildAgent ? "child" : "root", avatar.Name, agentID, Name); + // Don't do this to root agents, it's not nice for the viewer if (closeChildAgents && isChildAgent) { @@ -3471,20 +3508,20 @@ namespace OpenSim.Region.Framework.Scenes // Let's do this via UDP avatar.ControllingClient.SendShutdownConnectionNotice(); } - + // Only applies to root agents. if (avatar.ParentID != 0) { avatar.StandUp(); } - + m_sceneGraph.removeUserCount(!isChildAgent); - + // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI if (closeChildAgents && CapsModule != null) - CapsModule.RemoveCaps(agentID); - + CapsModule.RemoveCaps(agentID); + if (closeChildAgents && !isChildAgent) { List regions = avatar.KnownRegionHandles; @@ -3493,10 +3530,10 @@ namespace OpenSim.Region.Framework.Scenes // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours. m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions); } - + m_eventManager.TriggerClientClosed(agentID, this); m_eventManager.TriggerOnRemovePresence(agentID); - + if (!isChildAgent) { if (AttachmentsModule != null) @@ -3505,22 +3542,22 @@ namespace OpenSim.Region.Framework.Scenes } ForEachClient( - delegate(IClientAPI client) - { - //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway - try { client.SendKillObject(new List { avatar.LocalId }); } - catch (NullReferenceException) { } - }); + delegate(IClientAPI client) + { + //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway + try { client.SendKillObject(new List { avatar.LocalId }); } + catch (NullReferenceException) { } + }); } - + // It's possible for child agents to have transactions if changes are being made cross-border. if (AgentTransactionsModule != null) - AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); + AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); } catch (Exception e) { m_log.Error( - string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); + string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e); } finally { @@ -3532,13 +3569,13 @@ namespace OpenSim.Region.Framework.Scenes m_authenticateHandler.RemoveCircuit(agentID); m_sceneGraph.RemoveScenePresence(agentID); m_clientManager.Remove(agentID); - + avatar.Close(); } catch (Exception e) { m_log.Error( - string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); + string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e); } } } @@ -3584,7 +3621,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid { if (part.ParentGroup.RootPart != part) // Child part - continue; + continue; } } deleteIDs.Add(localID); @@ -3637,7 +3674,7 @@ namespace OpenSim.Region.Framework.Scenes public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup) { bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || - (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); + (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0); bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0); @@ -3653,18 +3690,18 @@ namespace OpenSim.Region.Framework.Scenes // Don't disable this log message - it's too helpful string curViewer = Util.GetViewerName(acd); m_log.DebugFormat( - "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9}. {10}", - RegionInfo.RegionName, - (acd.child ? "child" : "root"), - acd.firstname, - acd.lastname, - acd.AgentID, - acd.circuitcode, - acd.IPAddress, - curViewer, - ((TPFlags)teleportFlags).ToString(), - acd.startpos, - (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI) + "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9}. {10}", + RegionInfo.RegionName, + (acd.child ? "child" : "root"), + acd.firstname, + acd.lastname, + acd.AgentID, + acd.circuitcode, + acd.IPAddress, + curViewer, + ((TPFlags)teleportFlags).ToString(), + acd.startpos, + (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI) ); if (!LoginsEnabled) @@ -3710,8 +3747,8 @@ namespace OpenSim.Region.Framework.Scenes if (ViewerDenied) { m_log.DebugFormat( - "[SCENE]: Access denied for {0} {1} using {2}", - acd.firstname, acd.lastname, curViewer); + "[SCENE]: Access denied for {0} {1} using {2}", + acd.firstname, acd.lastname, curViewer); reason = "Access denied, your viewer is banned by the region owner"; return false; } @@ -3725,13 +3762,13 @@ namespace OpenSim.Region.Framework.Scenes // We need to ensure that we are not already removing the scene presence before we ask it not to be // closed. - if (sp != null && sp.IsChildAgent - && (sp.LifecycleState == ScenePresenceState.Running - || sp.LifecycleState == ScenePresenceState.PreRemove)) + if (sp != null && sp.IsChildAgent + && (sp.LifecycleState == ScenePresenceState.Running + || sp.LifecycleState == ScenePresenceState.PreRemove)) { m_log.DebugFormat( - "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}", - sp.Name, sp.LifecycleState, Name); + "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}", + sp.Name, sp.LifecycleState, Name); // In the case where, for example, an A B C D region layout, an avatar may // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C @@ -3743,15 +3780,15 @@ namespace OpenSim.Region.Framework.Scenes // vulnerable to an issue when a viewer quits a region without sending a proper logout but then // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport // flag when no teleport had taken place (and hence no close was going to come). -// if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) -// { -// m_log.DebugFormat( -// "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", -// sp.Name, Name); -// -// sp.DoNotCloseAfterTeleport = true; -// } -// else if (EntityTransferModule.IsInTransit(sp.UUID)) + // if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) + // { + // m_log.DebugFormat( + // "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", + // sp.Name, Name); + // + // sp.DoNotCloseAfterTeleport = true; + // } + // else if (EntityTransferModule.IsInTransit(sp.UUID)) sp.LifecycleState = ScenePresenceState.Running; @@ -3760,8 +3797,8 @@ namespace OpenSim.Region.Framework.Scenes sp.DoNotCloseAfterTeleport = true; m_log.DebugFormat( - "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.", - sp.Name, Name); + "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.", + sp.Name, Name); } } } @@ -3775,21 +3812,21 @@ namespace OpenSim.Region.Framework.Scenes int pollsLeft = polls; while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0) - Thread.Sleep(pollInterval); + Thread.Sleep(pollInterval); if (sp.LifecycleState == ScenePresenceState.Removing) { m_log.WarnFormat( - "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.", - sp.Name, Name, polls * pollInterval / 1000); + "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.", + sp.Name, Name, polls * pollInterval / 1000); return false; } else if (polls != pollsLeft) { m_log.DebugFormat( - "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.", - sp.Name, Name, polls * pollInterval / 1000); + "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.", + sp.Name, Name, polls * pollInterval / 1000); } } @@ -3805,11 +3842,11 @@ namespace OpenSim.Region.Framework.Scenes // Or the same user is trying to be root twice here, won't work. // Kill it. m_log.WarnFormat( - "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", - sp.Name, sp.UUID, RegionInfo.RegionName); + "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", + sp.Name, sp.UUID, RegionInfo.RegionName); if (sp.ControllingClient != null) - CloseAgent(sp.UUID, true); + CloseAgent(sp.UUID, true); sp = null; } @@ -3824,7 +3861,7 @@ namespace OpenSim.Region.Framework.Scenes m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); - + // On login test land permisions if (vialogin) { @@ -3834,7 +3871,7 @@ namespace OpenSim.Region.Framework.Scenes return false; } } - + if (sp == null) // We don't have an [child] agent here already { if (requirePresenceLookup) @@ -3850,13 +3887,13 @@ namespace OpenSim.Region.Framework.Scenes catch (Exception e) { m_log.ErrorFormat( - "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); + "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); m_authenticateHandler.RemoveCircuit(acd.circuitcode); return false; } } - + try { if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason)) @@ -3868,17 +3905,17 @@ namespace OpenSim.Region.Framework.Scenes catch (Exception e) { m_log.ErrorFormat( - "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); + "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); m_authenticateHandler.RemoveCircuit(acd.circuitcode); return false; } - + m_log.InfoFormat( - "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", - Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname, - acd.AgentID, acd.circuitcode); - + "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", + Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname, + acd.AgentID, acd.circuitcode); + if (CapsModule != null) { CapsModule.SetAgentCapsSeeds(acd); @@ -3890,13 +3927,13 @@ namespace OpenSim.Region.Framework.Scenes // Let the SP know how we got here. This has a lot of interesting // uses down the line. sp.TeleportFlags = (TPFlags)teleportFlags; - + if (sp.IsChildAgent) { m_log.DebugFormat( - "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", - acd.AgentID, RegionInfo.RegionName); - + "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", + acd.AgentID, RegionInfo.RegionName); + sp.AdjustKnownSeeds(); if (CapsModule != null) @@ -3915,7 +3952,7 @@ namespace OpenSim.Region.Framework.Scenes if (vialogin) { -// CleanDroppedAttachments(); + // CleanDroppedAttachments(); // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking) if (acd.startpos.X < 0) acd.startpos.X = 1f; @@ -3923,14 +3960,14 @@ namespace OpenSim.Region.Framework.Scenes if (acd.startpos.Y < 0) acd.startpos.Y = 1f; if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f; -// m_log.DebugFormat( -// "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", -// RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); + // m_log.DebugFormat( + // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", + // RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && - RegionInfo.EstateSettings.AllowDirectTeleport == false && - !viahome && !godlike) + RegionInfo.EstateSettings.AllowDirectTeleport == false && + !viahome && !godlike) { SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); @@ -3942,15 +3979,15 @@ namespace OpenSim.Region.Framework.Scenes { // We have multiple SpawnPoints, Route the agent to a random or sequential one if (SpawnPointRouting == "random") - acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( - telehub.AbsolutePosition, - telehub.GroupRotation - ); + acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); else - acd.startpos = spawnpoints[SpawnPoint()].GetLocation( - telehub.AbsolutePosition, - telehub.GroupRotation - ); + acd.startpos = spawnpoints[SpawnPoint()].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); } else if (spawnpoints.Count == 1) { @@ -3960,15 +3997,15 @@ namespace OpenSim.Region.Framework.Scenes else { m_log.DebugFormat( - "[SCENE]: No spawnpoints defined for telehub {0} for {1} in {2}. Continuing.", - RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); + "[SCENE]: No spawnpoints defined for telehub {0} for {1} in {2}. Continuing.", + RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); } } else { m_log.DebugFormat( - "[SCENE]: No telehub {0} found to direct {1} in {2}. Continuing.", - RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); + "[SCENE]: No telehub {0} found to direct {1} in {2}. Continuing.", + RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); } // Final permissions check; this time we don't allow changing the position @@ -4005,7 +4042,7 @@ namespace OpenSim.Region.Framework.Scenes { ILandObject land = LandChannel.GetLandObject(pos); if (land == null) - return true; + return true; if (land.IsBannedFromLand(agentID) || land.IsRestrictedFromLand(agentID)) { @@ -4019,21 +4056,21 @@ namespace OpenSim.Region.Framework.Scenes public bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY) { if (posX < 0) - posX = 0; + posX = 0; else if (posX >= (float)RegionInfo.RegionSizeX) - posX = (float)RegionInfo.RegionSizeX - 0.001f; + posX = (float)RegionInfo.RegionSizeX - 0.001f; if (posY < 0) - posY = 0; + posY = 0; else if (posY >= (float)RegionInfo.RegionSizeY) - posY = (float)RegionInfo.RegionSizeY - 0.001f; + posY = (float)RegionInfo.RegionSizeY - 0.001f; reason = String.Empty; if (Permissions.IsGod(agentID)) - return true; + return true; ILandObject land = LandChannel.GetLandObject(posX, posY); if (land == null) - return false; + return false; bool banned = land.IsBannedFromLand(agentID); bool restricted = land.IsRestrictedFromLand(agentID); @@ -4057,7 +4094,7 @@ namespace OpenSim.Region.Framework.Scenes else { reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", - RegionInfo.RegionName); + RegionInfo.RegionName); } return false; } @@ -4108,15 +4145,15 @@ namespace OpenSim.Region.Framework.Scenes if (!m_strictAccessControl) return true; if (Permissions.IsGod(agent.AgentID)) return true; - + if (AuthorizationService != null) { if (!AuthorizationService.IsAuthorizedForRegion( - agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) + agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because: {4}", - agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason); - + agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason); + return false; } } @@ -4132,9 +4169,9 @@ namespace OpenSim.Region.Framework.Scenes if (RegionInfo.EstateSettings.IsBanned(agent.AgentID)) { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", - agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); + agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); reason = String.Format("Denied access to region {0}: You have been banned from that region.", - RegionInfo.RegionName); + RegionInfo.RegionName); return false; } } @@ -4152,7 +4189,7 @@ namespace OpenSim.Region.Framework.Scenes if (GroupMembership != null) { for (int i = 0; i < GroupMembership.Length; i++) - agentGroups.Add(GroupMembership[i].GroupID); + agentGroups.Add(GroupMembership[i].GroupID); } else { @@ -4180,13 +4217,13 @@ namespace OpenSim.Region.Framework.Scenes } if (!RegionInfo.EstateSettings.PublicAccess && - !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && - !groupAccess) + !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && + !groupAccess) { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", - agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); + agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", - RegionInfo.RegionName); + RegionInfo.RegionName); return false; } } @@ -4242,69 +4279,69 @@ namespace OpenSim.Region.Framework.Scenes return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc); } -// /// -// /// The Grid has requested that we log-off a user. Log them off. -// /// -// /// Unique ID of the avatar to log-off -// /// SecureSessionID of the user, or the RegionSecret text when logging on to the grid -// /// message to display to the user. Reason for being logged off -// public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) -// { -// ScenePresence loggingOffUser = GetScenePresence(AvatarID); -// if (loggingOffUser != null) -// { -// UUID localRegionSecret = UUID.Zero; -// bool parsedsecret = UUID.TryParse(RegionInfo.regionSecret, out localRegionSecret); -// -// // Region Secret is used here in case a new sessionid overwrites an old one on the user server. -// // Will update the user server in a few revisions to use it. -// -// if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) -// { -// m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); -// loggingOffUser.ControllingClient.Kick(message); -// // Give them a second to receive the message! -// Thread.Sleep(1000); -// loggingOffUser.ControllingClient.Close(); -// } -// else -// { -// m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate"); -// } -// } -// else -// { -// m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString()); -// } -// } + // /// + // /// The Grid has requested that we log-off a user. Log them off. + // /// + // /// Unique ID of the avatar to log-off + // /// SecureSessionID of the user, or the RegionSecret text when logging on to the grid + // /// message to display to the user. Reason for being logged off + // public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) + // { + // ScenePresence loggingOffUser = GetScenePresence(AvatarID); + // if (loggingOffUser != null) + // { + // UUID localRegionSecret = UUID.Zero; + // bool parsedsecret = UUID.TryParse(RegionInfo.regionSecret, out localRegionSecret); + // + // // Region Secret is used here in case a new sessionid overwrites an old one on the user server. + // // Will update the user server in a few revisions to use it. + // + // if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) + // { + // m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); + // loggingOffUser.ControllingClient.Kick(message); + // // Give them a second to receive the message! + // Thread.Sleep(1000); + // loggingOffUser.ControllingClient.Close(); + // } + // else + // { + // m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate"); + // } + // } + // else + // { + // m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString()); + // } + // } -// /// -// /// Triggered when an agent crosses into this sim. Also happens on initial login. -// /// -// /// -// /// -// /// -// public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) -// { -// ScenePresence presence = GetScenePresence(agentID); -// if (presence != null) -// { -// try -// { -// presence.MakeRootAgent(position, isFlying); -// } -// catch (Exception e) -// { -// m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace); -// } -// } -// else -// { -// m_log.ErrorFormat( -// "[SCENE]: Could not find presence for agent {0} crossing into scene {1}", -// agentID, RegionInfo.RegionName); -// } -// } + // /// + // /// Triggered when an agent crosses into this sim. Also happens on initial login. + // /// + // /// + // /// + // /// + // public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) + // { + // ScenePresence presence = GetScenePresence(agentID); + // if (presence != null) + // { + // try + // { + // presence.MakeRootAgent(position, isFlying); + // } + // catch (Exception e) + // { + // m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace); + // } + // } + // else + // { + // m_log.ErrorFormat( + // "[SCENE]: Could not find presence for agent {0} crossing into scene {1}", + // agentID, RegionInfo.RegionName); + // } + // } /// /// We've got an update about an agent that sees into this region, @@ -4316,15 +4353,15 @@ namespace OpenSim.Region.Framework.Scenes public virtual bool IncomingUpdateChildAgent(AgentData cAgentData) { m_log.DebugFormat( - "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); + "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); // TODO: This check should probably be in QueryAccess(). ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2); if (nearestParcel == null) { m_log.InfoFormat( - "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", - cAgentData.AgentID, RegionInfo.RegionName); + "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", + cAgentData.AgentID, RegionInfo.RegionName); return false; } @@ -4340,11 +4377,11 @@ namespace OpenSim.Region.Framework.Scenes if (cAgentData.SessionID != sp.ControllingClient.SessionId) { m_log.WarnFormat( - "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", - sp.UUID, cAgentData.SessionID); + "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", + sp.UUID, cAgentData.SessionID); - Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", - sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID)); + Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", + sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID)); } sp.UpdateChildAgent(cAgentData); @@ -4353,19 +4390,19 @@ namespace OpenSim.Region.Framework.Scenes if (cAgentData.SenderWantsToWaitForRoot) { while (sp.IsChildAgent && ntimes-- > 0) - Thread.Sleep(1000); + Thread.Sleep(1000); if (sp.IsChildAgent) - m_log.WarnFormat( - "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}", - sp.Name, sp.UUID, Name); + m_log.WarnFormat( + "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}", + sp.Name, sp.UUID, Name); else - m_log.InfoFormat( - "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits", - sp.Name, sp.UUID, Name, 20 - ntimes); + m_log.InfoFormat( + "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits", + sp.Name, sp.UUID, Name, 20 - ntimes); if (sp.IsChildAgent) - return false; + return false; } return true; @@ -4382,17 +4419,17 @@ namespace OpenSim.Region.Framework.Scenes /// true if we handled it. public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData) { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: IncomingChildAgentDataUpdate POSITION for {0} in {1}, position {2}", -// cAgentData.AgentID, Name, cAgentData.Position); + // m_log.DebugFormat( + // "[SCENE PRESENCE]: IncomingChildAgentDataUpdate POSITION for {0} in {1}, position {2}", + // cAgentData.AgentID, Name, cAgentData.Position); ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); if (childAgentUpdate != null) { -// if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) -// // Only warn for now -// m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", -// childAgentUpdate.UUID, cAgentData.SessionID); + // if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) + // // Only warn for now + // m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", + // childAgentUpdate.UUID, cAgentData.SessionID); // I can't imagine *yet* why we would get an update if the agent is a root agent.. // however to avoid a race condition crossing borders.. @@ -4424,12 +4461,12 @@ namespace OpenSim.Region.Framework.Scenes int ntimes = 20; ScenePresence sp = null; while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) - Thread.Sleep(1000); + Thread.Sleep(1000); if (sp == null) - m_log.WarnFormat( - "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", - agentID, RegionInfo.RegionName); + m_log.WarnFormat( + "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", + agentID, RegionInfo.RegionName); return sp; } @@ -4451,8 +4488,8 @@ namespace OpenSim.Region.Framework.Scenes if (acd == null) { m_log.DebugFormat( - "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.", - agentID, Name); + "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.", + agentID, Name); return false; } @@ -4464,8 +4501,8 @@ namespace OpenSim.Region.Framework.Scenes else { m_log.WarnFormat( - "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}", - agentID, auth_token, Name); + "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}", + agentID, auth_token, Name); } return false; @@ -4491,8 +4528,8 @@ namespace OpenSim.Region.Framework.Scenes if (sp.DoNotCloseAfterTeleport) { m_log.DebugFormat( - "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection", - sp.IsChildAgent ? "child" : "root", sp.Name, Name); + "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection", + sp.IsChildAgent ? "child" : "root", sp.Name, Name); // Need to reset the flag so that a subsequent close after another teleport can succeed. sp.DoNotCloseAfterTeleport = false; @@ -4503,8 +4540,8 @@ namespace OpenSim.Region.Framework.Scenes if (sp.LifecycleState != ScenePresenceState.Running) { m_log.DebugFormat( - "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}", - sp.Name, Name, sp.LifecycleState); + "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}", + sp.Name, Name, sp.LifecycleState); return false; } @@ -4530,21 +4567,21 @@ namespace OpenSim.Region.Framework.Scenes lock (m_removeClientLock) { sp = GetScenePresence(agentID); - + if (sp == null) { m_log.DebugFormat( - "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", - agentID, Name); - + "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", + agentID, Name); + return false; } if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove) { m_log.DebugFormat( - "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}", - sp.Name, Name, sp.LifecycleState); + "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}", + sp.Name, Name, sp.LifecycleState); return false; } @@ -4555,8 +4592,8 @@ namespace OpenSim.Region.Framework.Scenes if (sp.DoNotCloseAfterTeleport) { m_log.DebugFormat( - "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection", - sp.IsChildAgent ? "child" : "root", sp.Name, Name); + "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection", + sp.IsChildAgent ? "child" : "root", sp.Name, Name); // Need to reset the flag so that a subsequent close after another teleport can succeed. sp.DoNotCloseAfterTeleport = false; @@ -4584,7 +4621,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, - Vector3 lookat, uint teleportFlags) + Vector3 lookat, uint teleportFlags) { GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName); @@ -4607,7 +4644,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, - Vector3 lookAt, uint teleportFlags) + Vector3 lookAt, uint teleportFlags) { ScenePresence sp = GetScenePresence(remoteClient.AgentId); if (sp != null) @@ -4706,8 +4743,8 @@ namespace OpenSim.Region.Framework.Scenes if (part.Name == cmdparams[2]) { part.Resize( - new Vector3(Convert.ToSingle(cmdparams[3]), Convert.ToSingle(cmdparams[4]), - Convert.ToSingle(cmdparams[5]))); + new Vector3(Convert.ToSingle(cmdparams[3]), Convert.ToSingle(cmdparams[4]), + Convert.ToSingle(cmdparams[5]))); m_log.DebugFormat("Edited scale of Primitive: {0}", part.Name); } @@ -4752,7 +4789,7 @@ namespace OpenSim.Region.Framework.Scenes #region Script Engine - private bool ScriptDanger(SceneObjectPart part,Vector3 pos) + private bool ScriptDanger(SceneObjectPart part, Vector3 pos) { ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y); if (part != null) @@ -4768,7 +4805,7 @@ namespace OpenSim.Region.Framework.Scenes return true; } else if (((parcel.LandData.Flags & (uint)ParcelFlags.AllowGroupScripts) != 0) - && (parcel.LandData.GroupID != UUID.Zero) && (parcel.LandData.GroupID == part.GroupID)) + && (parcel.LandData.GroupID != UUID.Zero) && (parcel.LandData.GroupID == part.GroupID)) { return true; } @@ -5110,15 +5147,15 @@ namespace OpenSim.Region.Framework.Scenes #endregion -// Commented pending deletion since this method no longer appears to do anything at all -// public bool NeedSceneCacheClear(UUID agentID) -// { -// IInventoryTransferModule inv = RequestModuleInterface(); -// if (inv == null) -// return true; -// -// return inv.NeedSceneCacheClear(agentID, this); -// } + // Commented pending deletion since this method no longer appears to do anything at all + // public bool NeedSceneCacheClear(UUID agentID) + // { + // IInventoryTransferModule inv = RequestModuleInterface(); + // if (inv == null) + // return true; + // + // return inv.NeedSceneCacheClear(agentID, this); + // } public void CleanTempObjects() { @@ -5134,7 +5171,7 @@ namespace OpenSim.Region.Framework.Scenes if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) { if (grp.RootPart.Expires <= DateTime.Now) - DeleteSceneObject(grp, false); + DeleteSceneObject(grp, false); } } } @@ -5160,21 +5197,21 @@ namespace OpenSim.Region.Framework.Scenes // 3 = We have seen a new user enter within the past 4 minutes // which can be seen as positive confirmation of sim health // - int health=1; // Start at 1, means we're up + int health = 1; // Start at 1, means we're up if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) - health += 1; + health += 1; else - return health; + return health; // A login in the last 4 mins? We can't be doing too badly // if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) - health++; + health++; else - return health; + return health; -// CheckHeartbeat(); + // CheckHeartbeat(); return health; } @@ -5204,41 +5241,41 @@ namespace OpenSim.Region.Framework.Scenes jointProxyObject.AngularVelocity = trackedBody.AngularVelocity; switch (joint.Type) { - case PhysicsJointType.Ball: + case PhysicsJointType.Ball: + { + Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint); + Vector3 proxyPos = jointAnchor; + jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update + } + break; + + case PhysicsJointType.Hinge: + { + Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint); + + // Normally, we would just ask the physics scene to return the axis for the joint. + // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should + // never occur. Therefore we cannot rely on ODE to always return a correct joint axis. + // Therefore the following call does not always work: + //PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint); + + // instead we compute the joint orientation by saving the original joint orientation + // relative to one of the jointed bodies, and applying this transformation + // to the current position of the jointed bodies (the tracked body) to compute the + // current joint orientation. + + if (joint.TrackedBodyName == null) { - Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint); - Vector3 proxyPos = jointAnchor; - jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update + jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene); } - break; - case PhysicsJointType.Hinge: - { - Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint); + Vector3 proxyPos = jointAnchor; + Quaternion q = trackedBody.RotationOffset * joint.LocalRotation; - // Normally, we would just ask the physics scene to return the axis for the joint. - // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should - // never occur. Therefore we cannot rely on ODE to always return a correct joint axis. - // Therefore the following call does not always work: - //PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint); - - // instead we compute the joint orientation by saving the original joint orientation - // relative to one of the jointed bodies, and applying this transformation - // to the current position of the jointed bodies (the tracked body) to compute the - // current joint orientation. - - if (joint.TrackedBodyName == null) - { - jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene); - } - - Vector3 proxyPos = jointAnchor; - Quaternion q = trackedBody.RotationOffset * joint.LocalRotation; - - jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update - jointProxyObject.ParentGroup.UpdateGroupRotationR(q); // schedules the entire group for a terse update - } - break; + jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update + jointProxyObject.ParentGroup.UpdateGroupRotationR(q); // schedules the entire group for a terse update + } + break; } } @@ -5279,30 +5316,30 @@ namespace OpenSim.Region.Framework.Scenes if (joint != null) { if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages) - return; + return; SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene); if (jointProxyObject != null) { SimChat(Utils.StringToBytes("[NINJA]: " + message), - ChatTypeEnum.DebugChannel, - 2147483647, - jointProxyObject.AbsolutePosition, - jointProxyObject.Name, - jointProxyObject.UUID, - false); + ChatTypeEnum.DebugChannel, + 2147483647, + jointProxyObject.AbsolutePosition, + jointProxyObject.Name, + jointProxyObject.UUID, + false); joint.ErrorMessageCount++; if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages) { SimChat(Utils.StringToBytes("[NINJA]: Too many messages for this joint, suppressing further messages."), - ChatTypeEnum.DebugChannel, - 2147483647, - jointProxyObject.AbsolutePosition, - jointProxyObject.Name, - jointProxyObject.UUID, - false); + ChatTypeEnum.DebugChannel, + 2147483647, + jointProxyObject.AbsolutePosition, + jointProxyObject.Name, + jointProxyObject.UUID, + false); } } else @@ -5315,9 +5352,9 @@ namespace OpenSim.Region.Framework.Scenes public Scene ConsoleScene() { if (MainConsole.Instance == null) - return null; + return null; if (MainConsole.Instance.ConsoleScene is Scene) - return (Scene)MainConsole.Instance.ConsoleScene; + return (Scene)MainConsole.Instance.ConsoleScene; return null; } @@ -5328,13 +5365,13 @@ namespace OpenSim.Region.Framework.Scenes public float GetGroundHeight(float x, float y) { if (x < 0) - x = 0; + x = 0; if (x >= Heightmap.Width) - x = Heightmap.Width - 1; + x = Heightmap.Width - 1; if (y < 0) - y = 0; + y = 0; if (y >= Heightmap.Height) - y = Heightmap.Height - 1; + y = Heightmap.Height - 1; Vector3 p0 = new Vector3(x, y, (float)Heightmap[(int)x, (int)y]); Vector3 p1 = p0; @@ -5342,11 +5379,11 @@ namespace OpenSim.Region.Framework.Scenes p1.X += 1.0f; if (p1.X < Heightmap.Width) - p1.Z = (float)Heightmap[(int)p1.X, (int)p1.Y]; + p1.Z = (float)Heightmap[(int)p1.X, (int)p1.Y]; p2.Y += 1.0f; if (p2.Y < Heightmap.Height) - p2.Z = (float)Heightmap[(int)p2.X, (int)p2.Y]; + p2.Z = (float)Heightmap[(int)p2.X, (int)p2.Y]; Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z); @@ -5366,14 +5403,14 @@ namespace OpenSim.Region.Framework.Scenes return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; } -// private void CheckHeartbeat() -// { -// if (m_firstHeartbeat) -// return; -// -// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000) -// StartTimer(); -// } + // private void CheckHeartbeat() + // { + // if (m_firstHeartbeat) + // return; + // + // if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000) + // StartTimer(); + // } public override ISceneObject DeserializeObject(string representation) { @@ -5416,7 +5453,7 @@ namespace OpenSim.Region.Framework.Scenes } ILandObject dest = LandChannel.GetLandObject(avatar.lastKnownAllowedPosition.X, avatar.lastKnownAllowedPosition.Y); - if (dest != excludeParcel) + if (dest != excludeParcel) { // Ultimate backup if we have no idea where they are and // the last allowed position was in another parcel @@ -5526,9 +5563,9 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar) { float xdistance = avatar.AbsolutePosition.X < RegionInfo.RegionSizeX / 2 - ? avatar.AbsolutePosition.X : RegionInfo.RegionSizeX - avatar.AbsolutePosition.X; + ? avatar.AbsolutePosition.X : RegionInfo.RegionSizeX - avatar.AbsolutePosition.X; float ydistance = avatar.AbsolutePosition.Y < RegionInfo.RegionSizeY / 2 - ? avatar.AbsolutePosition.Y : RegionInfo.RegionSizeY - avatar.AbsolutePosition.Y; + ? avatar.AbsolutePosition.Y : RegionInfo.RegionSizeY - avatar.AbsolutePosition.Y; //find out what vertical edge to go to if (xdistance < ydistance) @@ -5575,7 +5612,7 @@ namespace OpenSim.Region.Framework.Scenes { IEstateDataService estateDataService = EstateDataService; if (estateDataService == null) - return new List(0); + return new List(0); return estateDataService.GetRegions(estateID); } @@ -5598,8 +5635,8 @@ namespace OpenSim.Region.Framework.Scenes private void HandleReloadEstate(string module, string[] cmd) { if (MainConsole.Instance.ConsoleScene == null || - (MainConsole.Instance.ConsoleScene is Scene && - (Scene)MainConsole.Instance.ConsoleScene == this)) + (MainConsole.Instance.ConsoleScene is Scene && + (Scene)MainConsole.Instance.ConsoleScene == this)) { ReloadEstateData(); } @@ -5617,8 +5654,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// public static Vector3[] GetCombinedBoundingBox( - List objects, - out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) + List objects, + out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) { minX = float.MaxValue; maxX = float.MinValue; @@ -5636,10 +5673,10 @@ namespace OpenSim.Region.Framework.Scenes Vector3 vec = g.AbsolutePosition; g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); - -// m_log.DebugFormat( -// "[SCENE]: For {0} found AxisAlignedBoundingBoxRaw {1}, {2}", -// g.Name, new Vector3(ominX, ominY, ominZ), new Vector3(omaxX, omaxY, omaxZ)); + + // m_log.DebugFormat( + // "[SCENE]: For {0} found AxisAlignedBoundingBoxRaw {1}, {2}", + // g.Name, new Vector3(ominX, ominY, ominZ), new Vector3(omaxX, omaxY, omaxZ)); ominX += vec.X; omaxX += vec.X; @@ -5649,17 +5686,17 @@ namespace OpenSim.Region.Framework.Scenes omaxZ += vec.Z; if (minX > ominX) - minX = ominX; + minX = ominX; if (minY > ominY) - minY = ominY; + minY = ominY; if (minZ > ominZ) - minZ = ominZ; + minZ = ominZ; if (maxX < omaxX) - maxX = omaxX; + maxX = omaxX; if (maxY < omaxY) - maxY = omaxY; + maxY = omaxY; if (maxZ < omaxZ) - maxZ = omaxZ; + maxZ = omaxZ; } foreach (SceneObjectGroup g in objects) @@ -5684,7 +5721,7 @@ namespace OpenSim.Region.Framework.Scenes { IWorldMapModule mapModule = RequestModuleInterface(); if (mapModule != null) - mapModule.GenerateMaptile(); + mapModule.GenerateMaptile(); } private void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e) @@ -5695,7 +5732,7 @@ namespace OpenSim.Region.Framework.Scenes // so that all simulators can retrieve it string error = GridService.RegisterRegion(RegionInfo.ScopeID, new GridRegion(RegionInfo)); if (error != string.Empty) - throw new Exception(error); + throw new Exception(error); } /// @@ -5725,7 +5762,7 @@ namespace OpenSim.Region.Framework.Scenes } if (!AllowAvatarCrossing && !viaTeleport) - return false; + return false; // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. // However, the long term fix is to make sure root agent count is always accurate. @@ -5740,8 +5777,8 @@ namespace OpenSim.Region.Framework.Scenes reason = "The region is full"; m_log.DebugFormat( - "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}", - agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit); + "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}", + agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit); return false; } @@ -5755,7 +5792,7 @@ namespace OpenSim.Region.Framework.Scenes { client = presence.ControllingClient; if (client != null) - aCircuit = client.RequestClientInfo(); + aCircuit = client.RequestClientInfo(); } // We may be called before there is a presence or a client. @@ -5778,7 +5815,7 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception e) { - m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message); + m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} " + e.StackTrace, e.Message); reason = "Error authorizing agent: " + e.Message; return false; } @@ -5797,16 +5834,16 @@ namespace OpenSim.Region.Framework.Scenes Vector3 spawnPoint = sp.GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); ILandObject land = LandChannel.GetLandObject(spawnPoint.X, spawnPoint.Y); if (land == null) - continue; + continue; if (land.IsEitherBannedOrRestricted(agentID)) - continue; + continue; banned = false; break; } if (banned) { - if(Permissions.IsAdministrator(agentID) == false || Permissions.IsGridGod(agentID) == false) + if (Permissions.IsAdministrator(agentID) == false || Permissions.IsGridGod(agentID) == false) { reason = "No suitable landing point found"; return false; @@ -5842,9 +5879,9 @@ namespace OpenSim.Region.Framework.Scenes if (banned || restricted) { if (banned) - reason = "You are banned from the parcel"; + reason = "You are banned from the parcel"; else - reason = "The parcel is restricted"; + reason = "The parcel is restricted"; return false; } } @@ -5866,15 +5903,15 @@ namespace OpenSim.Region.Framework.Scenes if (presence.MovingToTarget) { double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget); -// m_log.DebugFormat( -// "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}", -// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget); + // m_log.DebugFormat( + // "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}", + // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget); // Check the error term of the current position in relation to the target position if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT) { // We are close enough to the target -// m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name); + // m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name); presence.Velocity = Vector3.Zero; presence.AbsolutePosition = presence.MoveToPositionTarget; @@ -5888,28 +5925,28 @@ namespace OpenSim.Region.Framework.Scenes // least be able to set collision status once, rather than 5 times to give it enough // weighting so that that PhysicsActor thinks it really is colliding. for (int i = 0; i < 5; i++) - presence.IsColliding = true; + presence.IsColliding = true; if (presence.LandAtTarget) - presence.Flying = false; + presence.Flying = false; -// Vector3 targetPos = presence.MoveToPositionTarget; -// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; -// if (targetPos.Z - terrainHeight < 0.2) -// { -// presence.Flying = false; -// } + // Vector3 targetPos = presence.MoveToPositionTarget; + // float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y]; + // if (targetPos.Z - terrainHeight < 0.2) + // { + // presence.Flying = false; + // } } -// m_log.DebugFormat( -// "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}", -// presence.AgentControlFlags, presence.MovementFlag, presence.Name); + // m_log.DebugFormat( + // "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}", + // presence.AgentControlFlags, presence.MovementFlag, presence.Name); } else { -// m_log.DebugFormat( -// "[SCENE]: Updating npc {0} at {1} for next movement to {2}", -// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); + // m_log.DebugFormat( + // "[SCENE]: Updating npc {0} at {1} for next movement to {2}", + // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget); Vector3 agent_control_v3 = new Vector3(); presence.HandleMoveToTargetUpdate(1, ref agent_control_v3); @@ -5924,11 +5961,11 @@ namespace OpenSim.Region.Framework.Scenes int spawnpoints = RegionInfo.RegionSettings.SpawnPoints().Count; if (spawnpoints == 0) - return 0; + return 0; m_SpawnPoint++; if (m_SpawnPoint > spawnpoints) - m_SpawnPoint = 1; + m_SpawnPoint = 1; return m_SpawnPoint - 1; } @@ -5958,12 +5995,12 @@ namespace OpenSim.Region.Framework.Scenes public string GetExtraSetting(string name) { if (m_extraSettings == null) - return String.Empty; + return String.Empty; string val; if (!m_extraSettings.TryGetValue(name, out val)) - return String.Empty; + return String.Empty; return val; } @@ -5971,14 +6008,14 @@ namespace OpenSim.Region.Framework.Scenes public void StoreExtraSetting(string name, string val) { if (m_extraSettings == null) - return; + return; string oldVal; if (m_extraSettings.TryGetValue(name, out oldVal)) { if (oldVal == val) - return; + return; } m_extraSettings[name] = val; @@ -5991,10 +6028,10 @@ namespace OpenSim.Region.Framework.Scenes public void RemoveExtraSetting(string name) { if (m_extraSettings == null) - return; + return; if (!m_extraSettings.ContainsKey(name)) - return; + return; m_extraSettings.Remove(name); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs old mode 100644 new mode 100755 index 51f50d9ea8..c2e9b61ea8 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -67,7 +67,9 @@ namespace OpenSim.Region.Framework.Scenes protected Scene m_parentScene; protected Dictionary m_updateList = new Dictionary(); protected int m_numRootAgents = 0; + protected int m_numTotalPrim = 0; protected int m_numPrim = 0; + protected int m_numMesh = 0; protected int m_numChildAgents = 0; protected int m_physicalPrim = 0; @@ -368,7 +370,8 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart[] parts = sceneObject.Parts; - // Clamp child prim sizes and add child prims to the m_numPrim count + // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives + // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count if (m_parentScene.m_clampPrimSize) { foreach (SceneObjectPart part in parts) @@ -382,7 +385,19 @@ namespace OpenSim.Region.Framework.Scenes part.Shape.Scale = scale; } } - m_numPrim += parts.Length; + m_numTotalPrim += parts.Length; + + // Go through all parts (geometric primitives and meshes) of this Scene Object + foreach (SceneObjectPart part in parts) + { + // Keep track of the total number of meshes or geometric primitives now in the scene; + // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to + // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives + if (part.GetPrimType() == PrimType.SCULPT) + m_numMesh++; + else + m_numPrim++; + } sceneObject.AttachToScene(m_parentScene); @@ -437,7 +452,21 @@ namespace OpenSim.Region.Framework.Scenes if (!resultOfObjectLinked) { - m_numPrim -= grp.PrimCount; + // Decrement the total number of primitives (meshes and geometric primitives) + // that are part of the Scene Object being removed + m_numTotalPrim -= grp.PrimCount; + + // Go through all parts (primitives and meshes) of this Scene Object + foreach (SceneObjectPart part in grp.Parts) + { + // Keep track of the total number of meshes or geometric primitives left in the scene; + // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to + // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives + if (part.GetPrimType() == PrimType.SCULPT) + m_numMesh--; + else + m_numPrim--; + } if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) RemovePhysicalPrim(grp.PrimCount); @@ -686,10 +715,20 @@ namespace OpenSim.Region.Framework.Scenes } public int GetTotalObjectsCount() + { + return m_numTotalPrim; + } + + public int GetTotalPrimObjectsCount() { return m_numPrim; } + public int GetTotalMeshObjectsCount() + { + return m_numMesh; + } + public int GetActiveObjectsCount() { return m_physicalPrim; @@ -1970,7 +2009,19 @@ namespace OpenSim.Region.Framework.Scenes // think it's selected, so it will never send a deselect... copy.IsSelected = false; - m_numPrim += copy.Parts.Length; + m_numTotalPrim += copy.Parts.Length; + + // Go through all parts (primitives and meshes) of this Scene Object + foreach (SceneObjectPart part in copy.Parts) + { + // Keep track of the total number of meshes or geometric primitives now in the scene; + // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to + // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives + if (part.GetPrimType() == PrimType.SCULPT) + m_numMesh++; + else + m_numPrim++; + } if (rot != Quaternion.Identity) { diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 0eab898c9f..8918c3b512 100755 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -61,6 +61,10 @@ namespace OpenSim.Region.Framework.Scenes private YourStatsAreWrong handlerStatsIncorrect; + // Determines the size of the array that is used to collect StatBlocks + // for sending to the SimStats and SimExtraStatsCollector + private const int m_statisticArraySize = 27; + /// /// These are the IDs of stats sent in the StatsPacket to the viewer. /// @@ -104,7 +108,12 @@ namespace OpenSim.Region.Framework.Scenes ScriptEps = 31, SimSpareMs = 32, SimSleepMs = 33, - SimIoPumpTime = 34 + SimIoPumpTime = 34, + FrameDilation = 35, + UsersLoggingIn = 36, + TotalGeoPrim = 37, + TotalMesh = 38, + ThreadCount = 39 } /// @@ -175,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes // saved last reported value so there is something available for llGetRegionFPS private float lastReportedSimFPS; - private float[] lastReportedSimStats = new float[22]; + private float[] lastReportedSimStats = new float[m_statisticArraySize]; private float m_pfps; /// @@ -202,6 +211,8 @@ namespace OpenSim.Region.Framework.Scenes private int m_rootAgents; private int m_childAgents; private int m_numPrim; + private int m_numGeoPrim; + private int m_numMesh; private int m_inPacketsPerSecond; private int m_outPacketsPerSecond; private int m_activePrim; @@ -214,26 +225,33 @@ namespace OpenSim.Region.Framework.Scenes private int m_objectCapacity = 45000; // This is the number of frames that will be stored and then averaged for - // the Total, Simulation, Physics, and Network Frame Time; It is set to - // 10 by default but can be changed by the OpenSim.ini configuration file + // the Total, Simulation, Physics, and Network Frame Time; It is set to + // 10 by default but can be changed by the OpenSim.ini configuration file // NumberOfFrames parameter private int m_numberFramesStored = Scene.m_defaultNumberFramesStored; - // The arrays that will hold the time it took to run the past N frames, + // The arrays that will hold the time it took to run the past N frames, // where N is the num_frames_to_average given by the configuration file private double[] m_totalFrameTimeMilliseconds; private double[] m_simulationFrameTimeMilliseconds; private double[] m_physicsFrameTimeMilliseconds; private double[] m_networkFrameTimeMilliseconds; - // The location of the next time in milliseconds that will be + // The location of the next time in milliseconds that will be // (over)written when the next frame completes private int m_nextLocation = 0; // The correct number of frames that have completed since the last stats // update for physics private int m_numberPhysicsFrames; - + + // The current number of users attempting to login to the region + private int m_usersLoggingIn; + + // The last reported value of threads from the SmartThreadPool inside of + // XEngine + private int m_inUseThreads; + private Scene m_scene; private RegionInfo ReportingRegion; @@ -246,11 +264,13 @@ namespace OpenSim.Region.Framework.Scenes { // Initialize the different frame time arrays to the correct sizes m_totalFrameTimeMilliseconds = new double[m_numberFramesStored]; - m_simulationFrameTimeMilliseconds = new - double[m_numberFramesStored]; + m_simulationFrameTimeMilliseconds = new double[m_numberFramesStored]; m_physicsFrameTimeMilliseconds = new double[m_numberFramesStored]; m_networkFrameTimeMilliseconds = new double[m_numberFramesStored]; - + + // Initialize the current number of users logging into the region + m_usersLoggingIn = 0; + m_scene = scene; m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps; m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); @@ -284,13 +304,14 @@ namespace OpenSim.Region.Framework.Scenes StatsManager.RegisterStat(SlowFramesStat); } + public SimStatsReporter(Scene scene, int numberOfFrames) : this (scene) { - // Store the number of frames from the OpenSim.ini configuration - // file - m_numberFramesStored = numberOfFrames; + // Store the number of frames from the OpenSim.ini configuration file + m_numberFramesStored = numberOfFrames; } - + + public void Close() { m_report.Elapsed -= TriggerStatsHeartbeat; @@ -328,11 +349,17 @@ namespace OpenSim.Region.Framework.Scenes double simulationSumFrameTime; double physicsSumFrameTime; double networkSumFrameTime; - + float frameDilation; + int currentFrame; + if (!m_scene.Active) return; - SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[22]; + // Create arrays to hold the statistics for this current scene, + // these will be passed to the SimExtraStatsCollector, they are also + // sent to the SimStats class + SimStatsPacket.StatBlock[] sb = new + SimStatsPacket.StatBlock[m_statisticArraySize]; SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock(); // Know what's not thread safe in Mono... modifying timers. @@ -354,21 +381,21 @@ namespace OpenSim.Region.Framework.Scenes #region various statistic googly moogly - // ORIGINAL code commented out until we have time to add our own - // statistics to the statistics window, this will be done as a - // new section given the title of our current project + // ORIGINAL code commented out until we have time to add our own + // statistics to the statistics window, this will be done as a + // new section given the title of our current project // We're going to lie about the FPS because we've been lying since 2008. The actual FPS is currently // locked at a maximum of 11. Maybe at some point this can change so that we're not lying. //int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor); - int reportedFPS = m_fps; - + int reportedFPS = m_fps; + // save the reported value so there is something available for llGetRegionFPS lastReportedSimFPS = reportedFPS / m_statsUpdateFactor; - // ORIGINAL code commented out until we have time to add our own - // statistics to the statistics window + // ORIGINAL code commented out until we have time to add our own + // statistics to the statistics window //float physfps = ((m_pfps / 1000)); - float physfps = m_numberPhysicsFrames; + float physfps = m_numberPhysicsFrames; //if (physfps > 600) //physfps = physfps - (physfps - 600); @@ -381,6 +408,8 @@ namespace OpenSim.Region.Framework.Scenes m_rootAgents = m_scene.SceneGraph.GetRootAgentCount(); m_childAgents = m_scene.SceneGraph.GetChildAgentCount(); m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount(); + m_numGeoPrim = m_scene.SceneGraph.GetTotalPrimObjectsCount(); + m_numMesh = m_scene.SceneGraph.GetTotalMeshObjectsCount(); m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount(); m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount(); @@ -406,11 +435,11 @@ namespace OpenSim.Region.Framework.Scenes if (framesUpdated == 0) framesUpdated = 1; - for (int i = 0; i < 22; i++) + for (int i = 0; i < m_statisticArraySize; i++) { sb[i] = new SimStatsPacket.StatBlock(); } - + // Resetting the sums of the frame times to prevent any errors // in calculating the moving average for frame time totalSumFrameTime = 0; @@ -425,12 +454,25 @@ namespace OpenSim.Region.Framework.Scenes // Sum up each frame time in order to calculate the moving // average of frame time totalSumFrameTime += m_totalFrameTimeMilliseconds[i]; - simulationSumFrameTime += + simulationSumFrameTime += m_simulationFrameTimeMilliseconds[i]; physicsSumFrameTime += m_physicsFrameTimeMilliseconds[i]; networkSumFrameTime += m_networkFrameTimeMilliseconds[i]; } - + + // Get the index that represents the current frame based on the next one known; go back + // to the last index if next one is stated to restart at 0 + if (m_nextLocation == 0) + currentFrame = m_numberFramesStored - 1; + else + currentFrame = m_nextLocation - 1; + + // Calculate the frame dilation; which is currently based on the ratio between the sum of the + // physics and simulation rate, and the set minimum time to run a scene's frame + frameDilation = (float)(m_simulationFrameTimeMilliseconds[currentFrame] + + m_physicsFrameTimeMilliseconds[currentFrame]) / m_scene.MinFrameTicks; + + // ORIGINAL code commented out until we have time to add our own sb[0].StatID = (uint) Stats.TimeDilation; sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); @@ -455,31 +497,28 @@ namespace OpenSim.Region.Framework.Scenes sb[7].StatID = (uint) Stats.ActivePrim; sb[7].StatValue = m_activePrim; - // ORIGINAL code commented out until we have time to add our own - // statistics to the statistics window + // ORIGINAL code commented out until we have time to add our own + // statistics to the statistics window sb[8].StatID = (uint)Stats.FrameMS; //sb[8].StatValue = m_frameMS / framesUpdated; - sb[8].StatValue = (float) totalSumFrameTime / - m_numberFramesStored; + sb[8].StatValue = (float) totalSumFrameTime / m_numberFramesStored; sb[9].StatID = (uint)Stats.NetMS; //sb[9].StatValue = m_netMS / framesUpdated; - sb[9].StatValue = (float) networkSumFrameTime / - m_numberFramesStored; + sb[9].StatValue = (float) networkSumFrameTime / m_numberFramesStored; sb[10].StatID = (uint)Stats.PhysicsMS; //sb[10].StatValue = m_physicsMS / framesUpdated; - sb[10].StatValue = (float) physicsSumFrameTime / - m_numberFramesStored; + sb[10].StatValue = (float) physicsSumFrameTime / m_numberFramesStored; sb[11].StatID = (uint)Stats.ImageMS ; sb[11].StatValue = m_imageMS / framesUpdated; sb[12].StatID = (uint)Stats.OtherMS; //sb[12].StatValue = m_otherMS / framesUpdated; - sb[12].StatValue = (float) simulationSumFrameTime / - m_numberFramesStored; - + sb[12].StatValue = (float) simulationSumFrameTime / + m_numberFramesStored; + sb[13].StatID = (uint)Stats.InPacketsPerSecond; sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor); @@ -507,7 +546,28 @@ namespace OpenSim.Region.Framework.Scenes sb[21].StatID = (uint)Stats.SimSpareMs; sb[21].StatValue = m_spareMS / framesUpdated; - for (int i = 0; i < 22; i++) + // Current ratio between the sum of physics and sim rate, and the + // minimum time to run a scene's frame + sb[22].StatID = (uint)Stats.FrameDilation; + sb[22].StatValue = frameDilation; + + // Current number of users currently attemptint to login to region + sb[23].StatID = (uint)Stats.UsersLoggingIn; + sb[23].StatValue = m_usersLoggingIn; + + // Total number of geometric primitives in the scene + sb[24].StatID = (uint)Stats.TotalGeoPrim; + sb[24].StatValue = m_numGeoPrim; + + // Total number of mesh objects in the scene + sb[25].StatID = (uint)Stats.TotalMesh; + sb[25].StatValue = m_numMesh; + + // Current number of threads that XEngine is using + sb[26].StatID = (uint)Stats.ThreadCount; + sb[26].StatValue = m_inUseThreads; + + for (int i = 0; i < m_statisticArraySize; i++) { lastReportedSimStats[i] = sb[i].StatValue; } @@ -554,8 +614,8 @@ namespace OpenSim.Region.Framework.Scenes { // Reset the number of frames that the physics library has // processed since the last stats report - m_numberPhysicsFrames = 0; - + m_numberPhysicsFrames = 0; + m_timeDilation = 0; m_fps = 0; m_pfps = 0; @@ -686,32 +746,32 @@ namespace OpenSim.Region.Framework.Scenes m_otherMS += ms; } - public void addPhysicsFrame(int frames) - { - // Add the number of physics frames to the correct total physics - // frames - m_numberPhysicsFrames += frames; - } + public void addPhysicsFrame(int frames) + { + // Add the number of physics frames to the correct total physics + // frames + m_numberPhysicsFrames += frames; + } - public void addFrameTimeMilliseconds(double total, double simulation, - double physics, double network) - { - // Save the frame times from the current frame into the appropriate - // arrays - m_totalFrameTimeMilliseconds[m_nextLocation] = total; - m_simulationFrameTimeMilliseconds[m_nextLocation] = simulation; - m_physicsFrameTimeMilliseconds[m_nextLocation] = physics; - m_networkFrameTimeMilliseconds[m_nextLocation] = network; + public void addFrameTimeMilliseconds(double total, double simulation, + double physics, double network) + { + // Save the frame times from the current frame into the appropriate + // arrays + m_totalFrameTimeMilliseconds[m_nextLocation] = total; + m_simulationFrameTimeMilliseconds[m_nextLocation] = simulation; + m_physicsFrameTimeMilliseconds[m_nextLocation] = physics; + m_networkFrameTimeMilliseconds[m_nextLocation] = network; - // Update to the next location in the list - m_nextLocation++; + // Update to the next location in the list + m_nextLocation++; + + // Since the list will begin to overwrite the oldest frame values + // first, the next location needs to loop back to the beginning of the + // list whenever it reaches the end + m_nextLocation = m_nextLocation % m_numberFramesStored; + } - // Since the list will begin to overwrite the oldest frame values - // first, the next location needs to loop back to the beginning of the - // list whenever it reaches the end - m_nextLocation = m_nextLocation % m_numberFramesStored; - } - public void AddPendingDownloads(int count) { m_pendingDownloads += count; @@ -734,6 +794,31 @@ namespace OpenSim.Region.Framework.Scenes AddunAckedBytes(unAckedBytes); } + public void UpdateUsersLoggingIn(bool isLoggingIn) + { + // Determine whether the user has started logging in or has completed + // logging into the region + if (isLoggingIn) + { + // The user is starting to login to the region so increment the + // number of users attempting to login to the region + m_usersLoggingIn++; + } + else + { + // The user has finished logging into the region so decrement the + // number of users logging into the region + m_usersLoggingIn--; + } + } + + public void SetThreadCount(int inUseThreads) + { + // Save the new number of threads to our member variable to send to + // the extra stats collector + m_inUseThreads = inUseThreads; + } + #endregion public Dictionary GetExtraSimStats() diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs old mode 100644 new mode 100755 index 54620d1c24..4e383f805f --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1872,6 +1872,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine IScriptInstance instance = GetInstance(itemID); if (instance != null) instance.ApiResetScript(); + + // Send the new number of threads that are in use by the thread + // pool, I believe that by adding them to the locations where the + // script is changing states that I will catch all changes to the + // thread pool + m_Scene.setThreadCount(m_ThreadPool.InUseThreads); } public void ResetScript(UUID itemID) @@ -1879,6 +1885,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine IScriptInstance instance = GetInstance(itemID); if (instance != null) instance.ResetScript(m_WaitForEventCompletionOnScriptStop); + + // Send the new number of threads that are in use by the thread + // pool, I believe that by adding them to the locations where the + // script is changing states that I will catch all changes to the + // thread pool + m_Scene.setThreadCount(m_ThreadPool.InUseThreads); } public void StartScript(UUID itemID) @@ -1888,6 +1900,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance.Start(); else m_runFlags.AddOrUpdate(itemID, true, 240); + + // Send the new number of threads that are in use by the thread + // pool, I believe that by adding them to the locations where the + // script is changing states that I will catch all changes to the + // thread pool + m_Scene.setThreadCount(m_ThreadPool.InUseThreads); } public void StopScript(UUID itemID) @@ -1903,6 +1921,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine // m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name); m_runFlags.AddOrUpdate(itemID, false, 240); } + + // Send the new number of threads that are in use by the thread + // pool, I believe that by adding them to the locations where the + // script is changing states that I will catch all changes to the + // thread pool + m_Scene.setThreadCount(m_ThreadPool.InUseThreads); } public DetectParams GetDetectParams(UUID itemID, int idx) @@ -2393,6 +2417,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance.Suspend(); // else // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); + + // Send the new number of threads that are in use by the thread + // pool, I believe that by adding them to the locations where the + // script is changing states that I will catch all changes to the + // thread pool + m_Scene.setThreadCount(m_ThreadPool.InUseThreads); } public void ResumeScript(UUID itemID) @@ -2404,6 +2434,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance.Resume(); // else // m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); + + // Send the new number of threads that are in use by the thread + // pool, I believe that by adding them to the locations where the + // script is changing states that I will catch all changes to the + // thread pool + m_Scene.setThreadCount(m_ThreadPool.InUseThreads); } public bool HasScript(UUID itemID, out bool running) diff --git a/bin/LukeSkywalker.IPNetwork.dll b/bin/LukeSkywalker.IPNetwork.dll old mode 100644 new mode 100755 diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini old mode 100644 new mode 100755 index af37ccc0f0..3422996f7f --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -296,7 +296,7 @@ ; Simulator Stats URI ; Enable JSON simulator data by setting a URI name (case sensitive) ; Returns regular sim stats (SimFPS, ...) - ; Stats_URI = "jsonSimStats" + Stats_URI = "jsonSimStats" ; Simulator StatsManager URI ; Enable fetch of StatsManager registered stats. Fetch is query which can optionally