/OpenSim/Region/Framework/Scenes/Scene.cs
C# | 5682 lines | 3694 code | 784 blank | 1204 comment | 637 complexity | 17fb1c987083bed6ec02376aba030ede MD5 | raw file
Possible License(s): BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- /*
- * 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 copyrightD
- * 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;
- using System.Diagnostics;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Text;
- using System.Threading;
- using System.Timers;
- using System.Xml;
- using Nini.Config;
- using OpenMetaverse;
- using OpenMetaverse.Packets;
- using OpenMetaverse.Imaging;
- using OpenSim.Framework;
- using OpenSim.Framework.Monitoring;
- using OpenSim.Services.Interfaces;
- using OpenSim.Framework.Communications;
- using OpenSim.Framework.Console;
- 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 TPFlags = OpenSim.Framework.Constants.TeleportFlags;
- using GridRegion = OpenSim.Services.Interfaces.GridRegion;
- namespace OpenSim.Region.Framework.Scenes
- {
- public delegate bool FilterAvatarList(ScenePresence avatar);
- public partial class Scene : SceneBase
- {
- private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
- private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
- public delegate void SynchronizeSceneHandler(Scene scene);
- #region Fields
- public bool EmergencyMonitoring = false;
- /// <summary>
- /// Show debug information about animations.
- /// </summary>
- public bool DebugAnimations { get; set; }
- /// <summary>
- /// Show debug information about teleports.
- /// </summary>
- public bool DebugTeleporting { get; set; }
- /// <summary>
- /// Show debug information about the scene loop.
- /// </summary>
- public bool DebugUpdates { get; set; }
- /// <summary>
- /// If true then the scene is saved to persistent storage periodically, every m_update_backup frames and
- /// if objects meet required conditions (m_dontPersistBefore and m_dontPersistAfter).
- /// </summary>
- /// <remarks>
- /// Even if false, the scene will still be saved on clean shutdown.
- /// FIXME: Currently, setting this to false will mean that objects are not periodically returned from parcels.
- /// This needs to be fixed.
- /// </remarks>
- public bool PeriodicBackup { get; set; }
- /// <summary>
- /// If false then the scene is never saved to persistence storage even if PeriodicBackup == true and even
- /// if the scene is being shut down for the final time.
- /// </summary>
- public bool UseBackup { get; set; }
- /// <summary>
- /// If false then physical objects are disabled, though collisions will continue as normal.
- /// </summary>
- public bool PhysicsEnabled { get; set; }
- /// <summary>
- /// If false then scripts are not enabled on the smiulator
- /// </summary>
- public bool ScriptsEnabled
- {
- get { return m_scripts_enabled; }
- set
- {
- if (m_scripts_enabled != value)
- {
- if (!value)
- {
- m_log.Info("Stopping all Scripts in Scene");
- EntityBase[] entities = Entities.GetEntities();
- foreach (EntityBase ent in entities)
- {
- if (ent is SceneObjectGroup)
- ((SceneObjectGroup)ent).RemoveScriptInstances(false);
- }
- }
- else
- {
- m_log.Info("Starting all Scripts in Scene");
-
- EntityBase[] entities = Entities.GetEntities();
- foreach (EntityBase ent in entities)
- {
- if (ent is SceneObjectGroup)
- {
- SceneObjectGroup sog = (SceneObjectGroup)ent;
- sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
- sog.ResumeScripts();
- }
- }
- }
- m_scripts_enabled = value;
- }
- }
- }
- private bool m_scripts_enabled;
- public SynchronizeSceneHandler SynchronizeScene;
- /// <summary>
- /// Used to prevent simultaneous calls to RemoveClient() for the same agent from interfering with each other.
- /// </summary>
- private object m_removeClientLock = new object();
- /// <summary>
- /// Statistical information for this scene.
- /// </summary>
- public SimStatsReporter StatsReporter { get; private set; }
- public List<Border> NorthBorders = new List<Border>();
- public List<Border> EastBorders = new List<Border>();
- public List<Border> SouthBorders = new List<Border>();
- public List<Border> WestBorders = new List<Border>();
- /// <summary>
- /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a
- /// PhysicsScene in order to perform collision detection
- /// </summary>
- public bool PhysicalPrims { get; private set; }
- /// <summary>
- /// Controls whether prims can be collided with.
- /// </summary>
- /// <remarks>
- /// If this is set to false then prims cannot be subject to physics either.
- /// </summary>
- public bool CollidablePrims { get; private set; }
- /// <summary>
- /// Minimum value of the size of a non-physical prim in each axis
- /// </summary>
- public float m_minNonphys = 0.001f;
- /// <summary>
- /// Maximum value of the size of a non-physical prim in each axis
- /// </summary>
- public float m_maxNonphys = 256;
- /// <summary>
- /// Minimum value of the size of a physical prim in each axis
- /// </summary>
- public float m_minPhys = 0.01f;
- /// <summary>
- /// Maximum value of the size of a physical prim in each axis
- /// </summary>
- public float m_maxPhys = 10;
- /// <summary>
- /// Max prims an object will hold
- /// </summary>
- public int m_linksetCapacity = 0;
- public bool m_clampPrimSize;
- public bool m_trustBinaries;
- public bool m_allowScriptCrossings;
- public bool m_useFlySlow;
- public bool m_useTrashOnDelete = true;
- /// <summary>
- /// Temporarily setting to trigger appearance resends at 60 second intervals.
- /// </summary>
- public bool SendPeriodicAppearanceUpdates { get; set; }
- protected float m_defaultDrawDistance = 255.0f;
- public float DefaultDrawDistance
- {
- get { return m_defaultDrawDistance; }
- }
- private List<string> m_AllowedViewers = new List<string>();
- private List<string> m_BannedViewers = new List<string>();
-
- // 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;
- public int MaxUndoCount { get; set; }
- // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
- public bool LoginLock = false;
- public bool StartDisabled = false;
- public bool LoadingPrims;
- public IXfer XferManager;
- // the minimum time that must elapse before a changed object will be considered for persisted
- public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L;
- // the maximum time that must elapse before a changed object will be considered for persisted
- public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
- protected int m_splitRegionID;
- protected Timer m_restartWaitTimer = new Timer();
- protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
- protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
- protected string m_simulatorVersion = "OpenSimulator Server";
- protected AgentCircuitManager m_authenticateHandler;
- protected SceneCommunicationService m_sceneGridService;
- protected ISimulationDataService m_SimulationDataService;
- protected IEstateDataService m_EstateDataService;
- protected IAssetService m_AssetService;
- protected IAuthorizationService m_AuthorizationService;
- protected IInventoryService m_InventoryService;
- protected IGridService m_GridService;
- protected ILibraryService m_LibraryService;
- protected ISimulationService m_simulationService;
- protected IAuthenticationService m_AuthenticationService;
- protected IPresenceService m_PresenceService;
- protected IUserAccountService m_UserAccountService;
- protected IAvatarService m_AvatarService;
- protected IGridUserService m_GridUserService;
- protected IXMLRPC m_xmlrpcModule;
- protected IWorldComm m_worldCommModule;
- protected IAvatarFactoryModule m_AvatarFactory;
- protected IConfigSource m_config;
- protected IRegionSerialiserModule m_serialiser;
- protected IDialogModule m_dialogModule;
- protected ICapabilitiesModule m_capsModule;
- protected IGroupsModule m_groupsModule;
- private Dictionary<string, string> m_extraSettings;
- /// <summary>
- /// Current scene frame number
- /// </summary>
- public uint Frame
- {
- get;
- protected set;
- }
- /// <summary>
- /// Current maintenance run number
- /// </summary>
- public uint MaintenanceRun { get; private set; }
- /// <summary>
- /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we
- /// will sleep for the remaining period.
- /// </summary>
- /// <remarks>
- /// 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).
- /// </remarks>
- public float MinFrameTime { get; private set; }
- /// <summary>
- /// The minimum length of time in seconds that will be taken for a maintenance run.
- /// </summary>
- public float MinMaintenanceTime { get; private set; }
- private int m_update_physics = 1;
- private int m_update_entitymovement = 1;
- private int m_update_objects = 1;
- private int m_update_temp_cleaning = 1000;
- private int m_update_presences = 1; // Update scene presence movements
- 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_coarse_locations = 50;
- private int agentMS;
- private int frameMS;
- private int physicsMS2;
- private int physicsMS;
- private int otherMS;
- private int tempOnRezMS;
- private int eventMS;
- private int backupMS;
- private int terrainMS;
- private int landMS;
- private int spareMS;
- /// <summary>
- /// Tick at which the last frame was processed.
- /// </summary>
- private int m_lastFrameTick;
- /// <summary>
- /// Tick at which the last maintenance run occurred.
- /// </summary>
- private int m_lastMaintenanceTick;
- /// <summary>
- /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
- /// asynchronously from the update loop.
- /// </summary>
- private bool m_cleaningTemps = false;
- // private Object m_heartbeatLock = new Object();
- // TODO: Possibly stop other classes being able to manipulate this directly.
- private SceneGraph m_sceneGraph;
- private volatile int m_bordersLocked;
- private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
- private volatile bool m_backingup;
- private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
- private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
- private string m_defaultScriptEngine;
- /// <summary>
- /// Tick at which the last login occurred.
- /// </summary>
- private int m_LastLogin;
- /// <summary>
- /// Thread that runs the scene loop.
- /// </summary>
- private Thread m_heartbeatThread;
- /// <summary>
- /// True if these scene is in the process of shutting down or is shutdown.
- /// </summary>
- public bool ShuttingDown
- {
- get { return m_shuttingDown; }
- }
- private volatile bool m_shuttingDown;
- /// <summary>
- /// Is the scene active?
- /// </summary>
- /// <remarks>
- /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if
- /// the scene is not active.
- /// </remarks>
- public bool Active
- {
- get { return m_active; }
- set
- {
- if (value)
- {
- if (!m_active)
- Start();
- }
- else
- {
- m_active = false;
- }
- }
- }
- private volatile bool m_active;
- // private int m_lastUpdate;
- // private bool m_firstHeartbeat = true;
-
- private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
- private bool m_reprioritizationEnabled = true;
- private double m_reprioritizationInterval = 5000.0;
- private double m_rootReprioritizationDistance = 10.0;
- private double m_childReprioritizationDistance = 20.0;
- private Timer m_mapGenerationTimer = new Timer();
- private bool m_generateMaptiles;
- #endregion Fields
- #region Properties
- /* Used by the loadbalancer plugin on GForge */
- public int SplitRegionID
- {
- get { return m_splitRegionID; }
- set { m_splitRegionID = value; }
- }
- public bool BordersLocked
- {
- get { return m_bordersLocked == 1; }
- set
- {
- if (value == true)
- m_bordersLocked = 1;
- else
- m_bordersLocked = 0;
- }
- }
-
- public new float TimeDilation
- {
- get { return m_sceneGraph.PhysicsScene.TimeDilation; }
- }
- public SceneCommunicationService SceneGridService
- {
- get { return m_sceneGridService; }
- }
- public ISimulationDataService SimulationDataService
- {
- get
- {
- if (m_SimulationDataService == null)
- {
- m_SimulationDataService = RequestModuleInterface<ISimulationDataService>();
- if (m_SimulationDataService == null)
- {
- throw new Exception("No ISimulationDataService available.");
- }
- }
- return m_SimulationDataService;
- }
- }
- public IEstateDataService EstateDataService
- {
- get
- {
- if (m_EstateDataService == null)
- {
- m_EstateDataService = RequestModuleInterface<IEstateDataService>();
- if (m_EstateDataService == null)
- {
- throw new Exception("No IEstateDataService available.");
- }
- }
- return m_EstateDataService;
- }
- }
- public IAssetService AssetService
- {
- get
- {
- if (m_AssetService == null)
- {
- m_AssetService = RequestModuleInterface<IAssetService>();
- if (m_AssetService == null)
- {
- throw new Exception("No IAssetService available.");
- }
- }
- return m_AssetService;
- }
- }
-
- public IAuthorizationService AuthorizationService
- {
- get
- {
- if (m_AuthorizationService == null)
- {
- m_AuthorizationService = RequestModuleInterface<IAuthorizationService>();
- //if (m_AuthorizationService == null)
- //{
- // // don't throw an exception if no authorization service is set for the time being
- // m_log.InfoFormat("[SCENE]: No Authorization service is configured");
- //}
- }
- return m_AuthorizationService;
- }
- }
- public IInventoryService InventoryService
- {
- get
- {
- if (m_InventoryService == null)
- {
- m_InventoryService = RequestModuleInterface<IInventoryService>();
- if (m_InventoryService == null)
- {
- throw new Exception("No IInventoryService available. This could happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. Please also check that you have the correct version of your inventory service dll. Sometimes old versions of this dll will still exist. Do a clean checkout and re-create the opensim.ini from the opensim.ini.example.");
- }
- }
- return m_InventoryService;
- }
- }
- public IGridService GridService
- {
- get
- {
- if (m_GridService == null)
- {
- m_GridService = RequestModuleInterface<IGridService>();
- if (m_GridService == null)
- {
- throw new Exception("No IGridService available. This could happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. Please also check that you have the correct version of your inventory service dll. Sometimes old versions of this dll will still exist. Do a clean checkout and re-create the opensim.ini from the opensim.ini.example.");
- }
- }
- return m_GridService;
- }
- }
- public ILibraryService LibraryService
- {
- get
- {
- if (m_LibraryService == null)
- m_LibraryService = RequestModuleInterface<ILibraryService>();
- return m_LibraryService;
- }
- }
- public ISimulationService SimulationService
- {
- get
- {
- if (m_simulationService == null)
- m_simulationService = RequestModuleInterface<ISimulationService>();
- return m_simulationService;
- }
- }
- public IAuthenticationService AuthenticationService
- {
- get
- {
- if (m_AuthenticationService == null)
- m_AuthenticationService = RequestModuleInterface<IAuthenticationService>();
- return m_AuthenticationService;
- }
- }
- public IPresenceService PresenceService
- {
- get
- {
- if (m_PresenceService == null)
- m_PresenceService = RequestModuleInterface<IPresenceService>();
- return m_PresenceService;
- }
- }
- public IUserAccountService UserAccountService
- {
- get
- {
- if (m_UserAccountService == null)
- m_UserAccountService = RequestModuleInterface<IUserAccountService>();
- return m_UserAccountService;
- }
- }
- public IAvatarService AvatarService
- {
- get
- {
- if (m_AvatarService == null)
- m_AvatarService = RequestModuleInterface<IAvatarService>();
- return m_AvatarService;
- }
- }
- public IGridUserService GridUserService
- {
- get
- {
- if (m_GridUserService == null)
- m_GridUserService = RequestModuleInterface<IGridUserService>();
- return m_GridUserService;
- }
- }
- public IAttachmentsModule AttachmentsModule { get; set; }
- public IEntityTransferModule EntityTransferModule { get; private set; }
- public IAgentAssetTransactions AgentTransactionsModule { get; private set; }
- public IUserManagement UserManagementModule { get; private set; }
- public IAvatarFactoryModule AvatarFactory
- {
- get { return m_AvatarFactory; }
- }
-
- public ICapabilitiesModule CapsModule
- {
- get { return m_capsModule; }
- }
- public int MonitorFrameTime { get { return frameMS; } }
- public int MonitorPhysicsUpdateTime { get { return physicsMS; } }
- public int MonitorPhysicsSyncTime { get { return physicsMS2; } }
- public int MonitorOtherTime { get { return otherMS; } }
- public int MonitorTempOnRezTime { get { return tempOnRezMS; } }
- public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event?
- public int MonitorBackupTime { get { return backupMS; } }
- public int MonitorTerrainTime { get { return terrainMS; } }
- public int MonitorLandTime { get { return landMS; } }
- public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
- public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
- public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
- public double ReprioritizationInterval { get { return m_reprioritizationInterval; } }
- public double RootReprioritizationDistance { get { return m_rootReprioritizationDistance; } }
- public double ChildReprioritizationDistance { get { return m_childReprioritizationDistance; } }
- public AgentCircuitManager AuthenticateHandler
- {
- get { return m_authenticateHandler; }
- }
- // an instance to the physics plugin's Scene object.
- public PhysicsScene PhysicsScene
- {
- get { return m_sceneGraph.PhysicsScene; }
- set
- {
- // If we're not doing the initial set
- // Then we've got to remove the previous
- // event handler
- if (PhysicsScene != null && PhysicsScene.SupportsNINJAJoints)
- {
- PhysicsScene.OnJointMoved -= jointMoved;
- PhysicsScene.OnJointDeactivated -= jointDeactivated;
- PhysicsScene.OnJointErrorMessage -= jointErrorMessage;
- }
- m_sceneGraph.PhysicsScene = value;
- if (PhysicsScene != null && m_sceneGraph.PhysicsScene.SupportsNINJAJoints)
- {
- // register event handlers to respond to joint movement/deactivation
- PhysicsScene.OnJointMoved += jointMoved;
- PhysicsScene.OnJointDeactivated += jointDeactivated;
- PhysicsScene.OnJointErrorMessage += jointErrorMessage;
- }
- }
- }
- public string DefaultScriptEngine
- {
- get { return m_defaultScriptEngine; }
- }
- public EntityManager Entities
- {
- 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;
- }
- // allow landmarks to pass
- public bool TelehubAllowLandmarks
- {
- get; private set;
- }
- #endregion Properties
- #region Constructors
- public Scene(RegionInfo regInfo, AgentCircuitManager authen,
- SceneCommunicationService sceneGridService,
- ISimulationDataService simDataService, IEstateDataService estateDataService,
- IConfigSource config, string simulatorVersion)
- : this(regInfo)
- {
- m_config = config;
- MinFrameTime = 0.089f;
- MinMaintenanceTime = 1;
- Random random = new Random();
- m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4);
- m_authenticateHandler = authen;
- m_sceneGridService = sceneGridService;
- m_SimulationDataService = simDataService;
- m_EstateDataService = estateDataService;
- m_regionHandle = RegionInfo.RegionHandle;
- m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
- m_asyncSceneObjectDeleter.Enabled = true;
- m_asyncInventorySender = new AsyncInventorySender(this);
- #region Region Settings
- // Load region settings
- // LoadRegionSettings creates new region settings in persistence if they don't already exist for this region.
- // However, in this case, the default textures are not set in memory properly, so we need to do it here and
- // resave.
- // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
- // region is set up and avoid these gyrations.
- RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
- m_extraSettings = simDataService.GetExtra(RegionInfo.RegionID);
- bool updatedTerrainTextures = false;
- if (rs.TerrainTexture1 == UUID.Zero)
- {
- rs.TerrainTexture1 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_1;
- updatedTerrainTextures = true;
- }
- if (rs.TerrainTexture2 == UUID.Zero)
- {
- rs.TerrainTexture2 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_2;
- updatedTerrainTextures = true;
- }
- if (rs.TerrainTexture3 == UUID.Zero)
- {
- rs.TerrainTexture3 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_3;
- updatedTerrainTextures = true;
- }
- if (rs.TerrainTexture4 == UUID.Zero)
- {
- rs.TerrainTexture4 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_4;
- updatedTerrainTextures = true;
- }
- if (updatedTerrainTextures)
- rs.Save();
- RegionInfo.RegionSettings = rs;
- if (estateDataService != null)
- 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);
- EventManager.OnLandObjectRemoved +=
- new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
- m_sceneGraph = new SceneGraph(this);
- // If the scene graph has an Unrecoverable error, restart this sim.
- // Currently the only thing that causes it to happen is two kinds of specific
- // Physics based crashes.
- //
- // 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();
- };
- RegisterDefaultSceneEvents();
- // XXX: Don't set the public property since we don't want to activate here. This needs to be handled
- // better in the future.
- m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts;
- PhysicsEnabled = !RegionInfo.RegionSettings.DisablePhysics;
- m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")";
- #region Region Config
- // Region config overrides global config
- //
- if (m_config.Configs["Startup"] != null)
- {
- IConfig startupConfig = m_config.Configs["Startup"];
- StartDisabled = startupConfig.GetBoolean("StartDisabled", false);
- 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);
-
- //Animation states
- m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
- MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
- PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims);
- CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims);
- m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
- if (RegionInfo.NonphysPrimMin > 0)
- {
- m_minNonphys = RegionInfo.NonphysPrimMin;
- }
- m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
- if (RegionInfo.NonphysPrimMax > 0)
- {
- m_maxNonphys = RegionInfo.NonphysPrimMax;
- }
- m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
- if (RegionInfo.PhysPrimMin > 0)
- {
- m_minPhys = RegionInfo.PhysPrimMin;
- }
- m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
- if (RegionInfo.PhysPrimMax > 0)
- {
- m_maxPhys = RegionInfo.PhysPrimMax;
- }
- // Here, if clamping is requested in either global or
- // local config, it will be used
- //
- m_clampPrimSize = startupConfig.GetBoolean("ClampPrimSize", m_clampPrimSize);
- if (RegionInfo.ClampPrimSize)
- {
- m_clampPrimSize = true;
- }
- m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
- if (RegionInfo.LinksetCapacity > 0)
- {
- m_linksetCapacity = RegionInfo.LinksetCapacity;
- }
- m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete", m_useTrashOnDelete);
- m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
- m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
- m_dontPersistBefore =
- startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
- m_dontPersistBefore *= 10000000;
- m_persistAfter =
- startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
- m_persistAfter *= 10000000;
- m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
- SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
- TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
- m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
- string[] possibleMapConfigSections = new string[] { "Map", "Startup" };
- m_generateMaptiles
- = Util.GetConfigVarFromSections<bool>(config, "GenerateMaptiles", possibleMapConfigSections, true);
- if (m_generateMaptiles)
- {
- int maptileRefresh = startupConfig.GetInt("MaptileRefresh", 0);
- if (maptileRefresh != 0)
- {
- m_mapGenerationTimer.Interval = maptileRefresh * 1000;
- m_mapGenerationTimer.Elapsed += RegenerateMaptileAndReregister;
- m_mapGenerationTimer.AutoReset = true;
- m_mapGenerationTimer.Start();
- }
- }
- else
- {
- string tile
- = Util.GetConfigVarFromSections<string>(
- config, "MaptileStaticUUID", possibleMapConfigSections, UUID.Zero.ToString());
- UUID tileID;
- if (tile != UUID.Zero.ToString() && UUID.TryParse(tile, out tileID))
- {
- RegionInfo.RegionSettings.TerrainImageID = tileID;
- }
- else
- {
- RegionInfo.RegionSettings.TerrainImageID = RegionInfo.MaptileStaticUUID;
- m_log.InfoFormat("[SCENE]: Region {0}, maptile set to {1}", RegionInfo.RegionName, RegionInfo.MaptileStaticUUID.ToString());
- }
- }
- string grant = startupConfig.GetString("AllowedClients", String.Empty);
- if (grant.Length > 0)
- {
- foreach (string viewer in grant.Split('|'))
- {
- m_AllowedViewers.Add(viewer.Trim().ToLower());
- }
- }
- grant = startupConfig.GetString("BannedClients", String.Empty);
- if (grant.Length > 0)
- {
- foreach (string viewer in grant.Split('|'))
- {
- m_BannedViewers.Add(viewer.Trim().ToLower());
- }
- }
- MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime);
- 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( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
- }
- // FIXME: Ultimately this should be in a module.
- SendPeriodicAppearanceUpdates = true;
-
- IConfig appearanceConfig = m_config.Configs["Appearance"];
- if (appearanceConfig != null)
- {
- SendPeriodicAppearanceUpdates
- = appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates);
- }
- #endregion Region Config
- #region Interest Management
- IConfig interestConfig = m_config.Configs["InterestManagement"];
- if (interestConfig != null)
- {
- string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
- try
- {
- m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
- }
- catch (Exception)
- {
- m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
- m_priorityScheme = UpdatePrioritizationSchemes.Time;
- }
- m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
- m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
- m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
- m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
- }
- m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme);
- #endregion Interest Management
- StatsReporter = new SimStatsReporter(this);
- StatsReporter.OnSendStatsResult += SendSimStatsPackets;
- StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
- }
- public Scene(RegionInfo regInfo) : base(regInfo)
- {
- PhysicalPrims = true;
- CollidablePrims = true;
- PhysicsEnabled = true;
- PeriodicBackup = true;
- UseBackup = true;
- BordersLocked = true;
- Border northBorder = new Border();
- northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
- northBorder.CrossDirection = Cardinals.N;
- NorthBorders.Add(northBorder);
- Border southBorder = new Border();
- southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
- southBorder.CrossDirection = Cardinals.S;
- SouthBorders.Add(southBorder);
- Border eastBorder = new Border();
- eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
- eastBorder.CrossDirection = Cardinals.E;
- EastBorders.Add(eastBorder);
- Border westBorder = new Border();
- westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
- westBorder.CrossDirection = Cardinals.W;
- WestBorders.Add(westBorder);
- BordersLocked = false;
- m_eventManager = new EventManager();
- m_permissions = new ScenePermissions(this);
- }
- #endregion
- #region Startup / Close Methods
- /// <value>
- /// The scene graph for this scene
- /// </value>
- /// TODO: Possibly stop other classes being able to manipulate this directly.
- public SceneGraph SceneGraph
- {
- get { return m_sceneGraph; }
- }
- protected virtual void RegisterDefaultSceneEvents()
- {
- IDialogModule dm = RequestModuleInterface<IDialogModule>();
- if (dm != null)
- m_eventManager.OnPermissionError += dm.SendAlertToUser;
- m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
- }
- public override string GetSimulatorVersion()
- {
- return m_simulatorVersion;
- }
- /// <summary>
- /// Process the fact that a neighbouring region has come up.
- /// </summary>
- /// <remarks>
- /// We only add it to the neighbor list if it's within 1 region from here.
- /// Agents may have draw distance values that cross two regions though, so
- /// we add it to the notify list regardless of distance. We'll check
- /// the agent's draw distance before notifying them though.
- /// </remarks>
- /// <param name="otherRegion">RegionInfo handle for the new region.</param>
- /// <returns>True after all operations complete, throws exceptions otherwise.</returns>
- public override void OtherRegionUp(GridRegion otherRegion)
- {
- uint xcell = (uint)((int)otherRegion.RegionLocX / (int)Constants.RegionSize);
- uint ycell = (uint)((int)otherRegion.RegionLocY / (int)Constants.RegionSize);
- //m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}",
- // RegionInfo.RegionName, otherRegion.RegionName, xcell, ycell);
- if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
- {
- // If these are cast to INT because long + negative values + abs returns invalid data
- int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX);
- int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY);
- if (resultX <= 1 && resultY <= 1)
- {
- // Let the grid service module know, so this can be cached
- m_eventManager.TriggerOnRegionUp(otherRegion);
- try
- {
- ForEachRootScenePresence(delegate(ScenePresence agent)
- {
- //agent.ControllingClient.new
- //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
- List<ulong> old = new List<ulong>();
- old.Add(otherRegion.RegionHandle);
- agent.DropOldNeighbours(old);
- if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
- EntityTransferModule.EnableChildAgent(agent, otherRegion);
- });
- }
- catch (NullReferenceException)
- {
- // This means that we're not booted up completely yet.
- // This shouldn't happen too often anymore.
- m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
- }
- }
- else
- {
- m_log.InfoFormat(
- "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})",
- otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY);
- }
- }
- }
- public void AddNeighborRegion(RegionInfo region)
- {
- lock (m_neighbours)
- {
- if (!CheckNeighborRegion(region))
- {
- m_neighbours.Add(region);
- }
- }
- }
- public bool CheckNeighborRegion(RegionInfo region)
- {
- bool found = false;
- lock (m_neighbours)
- {
- foreach (RegionInfo reg in m_neighbours)
- {
- if (reg.RegionHandle == region.RegionHandle)
- {
- found = true;
- break;
- }
- }
- }
- return found;
- }
- /// <summary>
- /// Checks whether this region has a neighbour in the given direction.
- /// </summary>
- /// <param name="car"></param>
- /// <param name="fix"></param>
- /// <returns>
- /// An integer which represents a compass point. N == 1, going clockwise until we reach NW == 8.
- /// Returns a positive integer if there is a region in that direction, a negative integer if not.
- /// </returns>
- public int HaveNeighbor(Cardinals car, ref int[] fix)
- {
- uint neighbourx = RegionInfo.RegionLocX;
- uint neighboury = RegionInfo.RegionLocY;
- int dir = (int)car;
- if (dir > 1 && dir < 5) //Heading East
- neighbourx++;
- else if (dir > 5) // Heading West
- neighbourx--;
- if (dir < 3 || dir == 8) // Heading North
- neighboury++;
- else if (dir > 3 && dir < 7) // Heading Sout
- neighboury--;
- int x = (int)(neighbourx * Constants.RegionSize);
- int y = (int)(neighboury * Constants.RegionSize);
- GridRegion neighbourRegion = GridService.GetRegionByPosition(RegionInfo.ScopeID, x, y);
- if (neighbourRegion == null)
- {
- fix[0] = (int)(RegionInfo.RegionLocX - neighbourx);
- fix[1] = (int)(RegionInfo.RegionLocY - neighboury);
- return dir * (-1);
- }
- else
- return dir;
- }
- // Alias IncomingHelloNeighbour OtherRegionUp, for now
- public GridRegion IncomingHelloNeighbour(RegionInfo neighbour)
- {
- OtherRegionUp(new GridRegion(neighbour));
- return new GridRegion(RegionInfo);
- }
- // This causes the region to restart immediatley.
- public void RestartNow()
- {
- IConfig startupConfig = m_config.Configs["Startup"];
- if (startupConfig != null)
- {
- if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
- {
- MainConsole.Instance.RunCommand("shutdown");
- return;
- }
- }
- m_log.InfoFormat("[REGION]: Restarting region {0}", Name);
- Close();
- base.Restart();
- }
- // This is a helper function that notifies root agents in this region that a new sim near them has come up
- // This is in the form of a timer because when an instance of OpenSim.exe is started,
- // Even though the sims initialize, they don't listen until 'all of the sims are initialized'
- // If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
- // subsequently the agent will never see the region come back online.
- public void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
- {
- m_restartWaitTimer.Stop();
- lock (m_regionRestartNotifyList)
- {
- foreach (RegionInfo region in m_regionRestartNotifyList)
- {
- GridRegion r = new GridRegion(region);
- try
- {
- ForEachRootScenePresence(delegate(ScenePresence agent)
- {
- if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
- EntityTransferModule.EnableChildAgent(agent, r);
- });
- }
- catch (NullReferenceException)
- {
- // This means that we're not booted up completely yet.
- // This shouldn't happen too often anymore.
- }
- }
- // Reset list to nothing.
- m_regionRestartNotifyList.Clear();
- …
Large files files are truncated, but you can click here to view the full file