PageRenderTime 63ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 1ms

/OpenSim/Region/Framework/Scenes/Scene.cs

https://github.com/AlericInglewood/opensimulator
C# | 5755 lines | 3637 code | 813 blank | 1305 comment | 664 complexity | e0f2cdc7033a60097e9eee922b9f3d83 MD5 | raw file
Possible License(s): MIT

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyrightD
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Diagnostics;
  30. using System.Drawing;
  31. using System.Drawing.Imaging;
  32. using System.IO;
  33. using System.Text;
  34. using System.Threading;
  35. using System.Timers;
  36. using System.Xml;
  37. using Nini.Config;
  38. using OpenMetaverse;
  39. using OpenMetaverse.Packets;
  40. using OpenMetaverse.Imaging;
  41. using OpenSim.Framework;
  42. using OpenSim.Framework.Monitoring;
  43. using OpenSim.Services.Interfaces;
  44. using OpenSim.Framework.Communications;
  45. using OpenSim.Framework.Console;
  46. using OpenSim.Region.Framework.Interfaces;
  47. using OpenSim.Region.Framework.Scenes.Scripting;
  48. using OpenSim.Region.Framework.Scenes.Serialization;
  49. using OpenSim.Region.Physics.Manager;
  50. using Timer=System.Timers.Timer;
  51. using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
  52. using GridRegion = OpenSim.Services.Interfaces.GridRegion;
  53. using PermissionMask = OpenSim.Framework.PermissionMask;
  54. namespace OpenSim.Region.Framework.Scenes
  55. {
  56. public delegate bool FilterAvatarList(ScenePresence avatar);
  57. public partial class Scene : SceneBase
  58. {
  59. private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
  60. private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
  61. public delegate void SynchronizeSceneHandler(Scene scene);
  62. #region Fields
  63. public bool EmergencyMonitoring = false;
  64. /// <summary>
  65. /// Show debug information about animations.
  66. /// </summary>
  67. public bool DebugAnimations { get; set; }
  68. /// <summary>
  69. /// Show debug information about teleports.
  70. /// </summary>
  71. public bool DebugTeleporting { get; set; }
  72. /// <summary>
  73. /// Show debug information about the scene loop.
  74. /// </summary>
  75. public bool DebugUpdates { get; set; }
  76. /// <summary>
  77. /// If true then the scene is saved to persistent storage periodically, every m_update_backup frames and
  78. /// if objects meet required conditions (m_dontPersistBefore and m_dontPersistAfter).
  79. /// </summary>
  80. /// <remarks>
  81. /// Even if false, the scene will still be saved on clean shutdown.
  82. /// FIXME: Currently, setting this to false will mean that objects are not periodically returned from parcels.
  83. /// This needs to be fixed.
  84. /// </remarks>
  85. public bool PeriodicBackup { get; set; }
  86. /// <summary>
  87. /// If false then the scene is never saved to persistence storage even if PeriodicBackup == true and even
  88. /// if the scene is being shut down for the final time.
  89. /// </summary>
  90. public bool UseBackup { get; set; }
  91. /// <summary>
  92. /// If false then physical objects are disabled, though collisions will continue as normal.
  93. /// </summary>
  94. public bool PhysicsEnabled { get; set; }
  95. /// <summary>
  96. /// If false then scripts are not enabled on the smiulator
  97. /// </summary>
  98. public bool ScriptsEnabled
  99. {
  100. get { return m_scripts_enabled; }
  101. set
  102. {
  103. if (m_scripts_enabled != value)
  104. {
  105. if (!value)
  106. {
  107. m_log.Info("Stopping all Scripts in Scene");
  108. EntityBase[] entities = Entities.GetEntities();
  109. foreach (EntityBase ent in entities)
  110. {
  111. if (ent is SceneObjectGroup)
  112. ((SceneObjectGroup)ent).RemoveScriptInstances(false);
  113. }
  114. }
  115. else
  116. {
  117. m_log.Info("Starting all Scripts in Scene");
  118. EntityBase[] entities = Entities.GetEntities();
  119. foreach (EntityBase ent in entities)
  120. {
  121. if (ent is SceneObjectGroup)
  122. {
  123. SceneObjectGroup sog = (SceneObjectGroup)ent;
  124. sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
  125. sog.ResumeScripts();
  126. }
  127. }
  128. }
  129. m_scripts_enabled = value;
  130. }
  131. }
  132. }
  133. private bool m_scripts_enabled;
  134. public SynchronizeSceneHandler SynchronizeScene;
  135. /// <summary>
  136. /// Used to prevent simultaneous calls to code that adds and removes agents.
  137. /// </summary>
  138. private object m_removeClientLock = new object();
  139. /// <summary>
  140. /// Statistical information for this scene.
  141. /// </summary>
  142. public SimStatsReporter StatsReporter { get; private set; }
  143. /// <summary>
  144. /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a
  145. /// PhysicsScene in order to perform collision detection
  146. /// </summary>
  147. public bool PhysicalPrims { get; private set; }
  148. /// <summary>
  149. /// Controls whether prims can be collided with.
  150. /// </summary>
  151. /// <remarks>
  152. /// If this is set to false then prims cannot be subject to physics either.
  153. /// </summary>
  154. public bool CollidablePrims { get; private set; }
  155. /// <summary>
  156. /// Minimum value of the size of a non-physical prim in each axis
  157. /// </summary>
  158. public float m_minNonphys = 0.001f;
  159. /// <summary>
  160. /// Maximum value of the size of a non-physical prim in each axis
  161. /// </summary>
  162. public float m_maxNonphys = 256;
  163. /// <summary>
  164. /// Minimum value of the size of a physical prim in each axis
  165. /// </summary>
  166. public float m_minPhys = 0.01f;
  167. /// <summary>
  168. /// Maximum value of the size of a physical prim in each axis
  169. /// </summary>
  170. public float m_maxPhys = 10;
  171. /// <summary>
  172. /// Max prims an object will hold
  173. /// </summary>
  174. public int m_linksetCapacity = 0;
  175. public bool m_clampPrimSize;
  176. public bool m_trustBinaries;
  177. public bool m_allowScriptCrossings;
  178. public bool m_useFlySlow;
  179. public bool m_useTrashOnDelete = true;
  180. /// <summary>
  181. /// Temporarily setting to trigger appearance resends at 60 second intervals.
  182. /// </summary>
  183. public bool SendPeriodicAppearanceUpdates { get; set; }
  184. protected float m_defaultDrawDistance = 255.0f;
  185. public float DefaultDrawDistance
  186. {
  187. // get { return m_defaultDrawDistance; }
  188. get {
  189. if (RegionInfo != null)
  190. {
  191. float largestDimension = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
  192. m_defaultDrawDistance = Math.Max(m_defaultDrawDistance, largestDimension);
  193. }
  194. return m_defaultDrawDistance;
  195. }
  196. }
  197. private List<string> m_AllowedViewers = new List<string>();
  198. private List<string> m_BannedViewers = new List<string>();
  199. // TODO: need to figure out how allow client agents but deny
  200. // root agents when ACL denies access to root agent
  201. public bool m_strictAccessControl = true;
  202. public int MaxUndoCount { get; set; }
  203. public bool SeeIntoRegion { get; set; }
  204. // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
  205. public bool LoginLock = false;
  206. public bool StartDisabled = false;
  207. public bool LoadingPrims;
  208. public IXfer XferManager;
  209. // the minimum time that must elapse before a changed object will be considered for persisted
  210. public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L;
  211. // the maximum time that must elapse before a changed object will be considered for persisted
  212. public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
  213. protected int m_splitRegionID;
  214. protected Timer m_restartWaitTimer = new Timer();
  215. protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
  216. protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
  217. protected string m_simulatorVersion = "OpenSimulator Server";
  218. protected AgentCircuitManager m_authenticateHandler;
  219. protected SceneCommunicationService m_sceneGridService;
  220. protected ISimulationDataService m_SimulationDataService;
  221. protected IEstateDataService m_EstateDataService;
  222. protected IAssetService m_AssetService;
  223. protected IAuthorizationService m_AuthorizationService;
  224. protected IInventoryService m_InventoryService;
  225. protected IGridService m_GridService;
  226. protected ILibraryService m_LibraryService;
  227. protected ISimulationService m_simulationService;
  228. protected IAuthenticationService m_AuthenticationService;
  229. protected IPresenceService m_PresenceService;
  230. protected IUserAccountService m_UserAccountService;
  231. protected IAvatarService m_AvatarService;
  232. protected IGridUserService m_GridUserService;
  233. protected IXMLRPC m_xmlrpcModule;
  234. protected IWorldComm m_worldCommModule;
  235. protected IAvatarFactoryModule m_AvatarFactory;
  236. protected IConfigSource m_config;
  237. protected IRegionSerialiserModule m_serialiser;
  238. protected IDialogModule m_dialogModule;
  239. protected ICapabilitiesModule m_capsModule;
  240. protected IGroupsModule m_groupsModule;
  241. private Dictionary<string, string> m_extraSettings;
  242. /// <summary>
  243. /// Current scene frame number
  244. /// </summary>
  245. public uint Frame
  246. {
  247. get;
  248. protected set;
  249. }
  250. /// <summary>
  251. /// Current maintenance run number
  252. /// </summary>
  253. public uint MaintenanceRun { get; private set; }
  254. /// <summary>
  255. /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we
  256. /// will sleep for the remaining period.
  257. /// </summary>
  258. /// <remarks>
  259. /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations
  260. /// occur too quickly (viewer 1) or with even more slide (viewer 2).
  261. /// </remarks>
  262. public float MinFrameTime { get; private set; }
  263. /// <summary>
  264. /// The minimum length of time in seconds that will be taken for a maintenance run.
  265. /// </summary>
  266. public float MinMaintenanceTime { get; private set; }
  267. private int m_update_physics = 1;
  268. private int m_update_entitymovement = 1;
  269. private int m_update_objects = 1;
  270. private int m_update_temp_cleaning = 1000;
  271. private int m_update_presences = 1; // Update scene presence movements
  272. private int m_update_events = 1;
  273. private int m_update_backup = 200;
  274. private int m_update_terrain = 50;
  275. // private int m_update_land = 1;
  276. private int m_update_coarse_locations = 50;
  277. private int agentMS;
  278. private int frameMS;
  279. private int physicsMS2;
  280. private int physicsMS;
  281. private int otherMS;
  282. private int tempOnRezMS;
  283. private int eventMS;
  284. private int backupMS;
  285. private int terrainMS;
  286. private int landMS;
  287. private int spareMS;
  288. /// <summary>
  289. /// Tick at which the last frame was processed.
  290. /// </summary>
  291. private int m_lastFrameTick;
  292. /// <summary>
  293. /// Tick at which the last maintenance run occurred.
  294. /// </summary>
  295. private int m_lastMaintenanceTick;
  296. /// <summary>
  297. /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
  298. /// asynchronously from the update loop.
  299. /// </summary>
  300. private bool m_cleaningTemps = false;
  301. // private Object m_heartbeatLock = new Object();
  302. // TODO: Possibly stop other classes being able to manipulate this directly.
  303. private SceneGraph m_sceneGraph;
  304. private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
  305. private volatile bool m_backingup;
  306. private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
  307. private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
  308. private string m_defaultScriptEngine;
  309. /// <summary>
  310. /// Tick at which the last login occurred.
  311. /// </summary>
  312. private int m_LastLogin;
  313. /// <summary>
  314. /// Thread that runs the scene loop.
  315. /// </summary>
  316. private Thread m_heartbeatThread;
  317. /// <summary>
  318. /// True if these scene is in the process of shutting down or is shutdown.
  319. /// </summary>
  320. public bool ShuttingDown
  321. {
  322. get { return m_shuttingDown; }
  323. }
  324. private volatile bool m_shuttingDown;
  325. /// <summary>
  326. /// Is the scene active?
  327. /// </summary>
  328. /// <remarks>
  329. /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if
  330. /// the scene is not active.
  331. /// </remarks>
  332. public bool Active
  333. {
  334. get { return m_active; }
  335. set
  336. {
  337. if (value)
  338. {
  339. if (!m_active)
  340. Start(false);
  341. }
  342. else
  343. {
  344. // This appears assymetric with Start() above but is not - setting m_active = false stops the loops
  345. // XXX: Possibly this should be in an explicit Stop() method for symmetry.
  346. m_active = false;
  347. }
  348. }
  349. }
  350. private volatile bool m_active;
  351. // private int m_lastUpdate;
  352. // private bool m_firstHeartbeat = true;
  353. private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
  354. private bool m_reprioritizationEnabled = true;
  355. private double m_reprioritizationInterval = 5000.0;
  356. private double m_rootReprioritizationDistance = 10.0;
  357. private double m_childReprioritizationDistance = 20.0;
  358. private Timer m_mapGenerationTimer = new Timer();
  359. private bool m_generateMaptiles;
  360. #endregion Fields
  361. #region Properties
  362. /* Used by the loadbalancer plugin on GForge */
  363. public int SplitRegionID
  364. {
  365. get { return m_splitRegionID; }
  366. set { m_splitRegionID = value; }
  367. }
  368. public new float TimeDilation
  369. {
  370. get { return m_sceneGraph.PhysicsScene.TimeDilation; }
  371. }
  372. public SceneCommunicationService SceneGridService
  373. {
  374. get { return m_sceneGridService; }
  375. }
  376. public ISimulationDataService SimulationDataService
  377. {
  378. get
  379. {
  380. if (m_SimulationDataService == null)
  381. {
  382. m_SimulationDataService = RequestModuleInterface<ISimulationDataService>();
  383. if (m_SimulationDataService == null)
  384. {
  385. throw new Exception("No ISimulationDataService available.");
  386. }
  387. }
  388. return m_SimulationDataService;
  389. }
  390. }
  391. public IEstateDataService EstateDataService
  392. {
  393. get
  394. {
  395. if (m_EstateDataService == null)
  396. {
  397. m_EstateDataService = RequestModuleInterface<IEstateDataService>();
  398. if (m_EstateDataService == null)
  399. {
  400. throw new Exception("No IEstateDataService available.");
  401. }
  402. }
  403. return m_EstateDataService;
  404. }
  405. }
  406. public IAssetService AssetService
  407. {
  408. get
  409. {
  410. if (m_AssetService == null)
  411. {
  412. m_AssetService = RequestModuleInterface<IAssetService>();
  413. if (m_AssetService == null)
  414. {
  415. throw new Exception("No IAssetService available.");
  416. }
  417. }
  418. return m_AssetService;
  419. }
  420. }
  421. public IAuthorizationService AuthorizationService
  422. {
  423. get
  424. {
  425. if (m_AuthorizationService == null)
  426. {
  427. m_AuthorizationService = RequestModuleInterface<IAuthorizationService>();
  428. //if (m_AuthorizationService == null)
  429. //{
  430. // // don't throw an exception if no authorization service is set for the time being
  431. // m_log.InfoFormat("[SCENE]: No Authorization service is configured");
  432. //}
  433. }
  434. return m_AuthorizationService;
  435. }
  436. }
  437. public IInventoryService InventoryService
  438. {
  439. get
  440. {
  441. if (m_InventoryService == null)
  442. {
  443. m_InventoryService = RequestModuleInterface<IInventoryService>();
  444. if (m_InventoryService == null)
  445. {
  446. 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.");
  447. }
  448. }
  449. return m_InventoryService;
  450. }
  451. }
  452. public IGridService GridService
  453. {
  454. get
  455. {
  456. if (m_GridService == null)
  457. {
  458. m_GridService = RequestModuleInterface<IGridService>();
  459. if (m_GridService == null)
  460. {
  461. 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.");
  462. }
  463. }
  464. return m_GridService;
  465. }
  466. }
  467. public ILibraryService LibraryService
  468. {
  469. get
  470. {
  471. if (m_LibraryService == null)
  472. m_LibraryService = RequestModuleInterface<ILibraryService>();
  473. return m_LibraryService;
  474. }
  475. }
  476. public ISimulationService SimulationService
  477. {
  478. get
  479. {
  480. if (m_simulationService == null)
  481. m_simulationService = RequestModuleInterface<ISimulationService>();
  482. return m_simulationService;
  483. }
  484. }
  485. public IAuthenticationService AuthenticationService
  486. {
  487. get
  488. {
  489. if (m_AuthenticationService == null)
  490. m_AuthenticationService = RequestModuleInterface<IAuthenticationService>();
  491. return m_AuthenticationService;
  492. }
  493. }
  494. public IPresenceService PresenceService
  495. {
  496. get
  497. {
  498. if (m_PresenceService == null)
  499. m_PresenceService = RequestModuleInterface<IPresenceService>();
  500. return m_PresenceService;
  501. }
  502. }
  503. public IUserAccountService UserAccountService
  504. {
  505. get
  506. {
  507. if (m_UserAccountService == null)
  508. m_UserAccountService = RequestModuleInterface<IUserAccountService>();
  509. return m_UserAccountService;
  510. }
  511. }
  512. public IAvatarService AvatarService
  513. {
  514. get
  515. {
  516. if (m_AvatarService == null)
  517. m_AvatarService = RequestModuleInterface<IAvatarService>();
  518. return m_AvatarService;
  519. }
  520. }
  521. public IGridUserService GridUserService
  522. {
  523. get
  524. {
  525. if (m_GridUserService == null)
  526. m_GridUserService = RequestModuleInterface<IGridUserService>();
  527. return m_GridUserService;
  528. }
  529. }
  530. public IAttachmentsModule AttachmentsModule { get; set; }
  531. public IEntityTransferModule EntityTransferModule { get; private set; }
  532. public IAgentAssetTransactions AgentTransactionsModule { get; private set; }
  533. public IUserManagement UserManagementModule { get; private set; }
  534. public IAvatarFactoryModule AvatarFactory
  535. {
  536. get { return m_AvatarFactory; }
  537. }
  538. public ICapabilitiesModule CapsModule
  539. {
  540. get { return m_capsModule; }
  541. }
  542. public int MonitorFrameTime { get { return frameMS; } }
  543. public int MonitorPhysicsUpdateTime { get { return physicsMS; } }
  544. public int MonitorPhysicsSyncTime { get { return physicsMS2; } }
  545. public int MonitorOtherTime { get { return otherMS; } }
  546. public int MonitorTempOnRezTime { get { return tempOnRezMS; } }
  547. public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event?
  548. public int MonitorBackupTime { get { return backupMS; } }
  549. public int MonitorTerrainTime { get { return terrainMS; } }
  550. public int MonitorLandTime { get { return landMS; } }
  551. public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
  552. public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
  553. public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
  554. public double ReprioritizationInterval { get { return m_reprioritizationInterval; } }
  555. public double RootReprioritizationDistance { get { return m_rootReprioritizationDistance; } }
  556. public double ChildReprioritizationDistance { get { return m_childReprioritizationDistance; } }
  557. public AgentCircuitManager AuthenticateHandler
  558. {
  559. get { return m_authenticateHandler; }
  560. }
  561. // an instance to the physics plugin's Scene object.
  562. public PhysicsScene PhysicsScene
  563. {
  564. get { return m_sceneGraph.PhysicsScene; }
  565. set
  566. {
  567. // If we're not doing the initial set
  568. // Then we've got to remove the previous
  569. // event handler
  570. if (PhysicsScene != null && PhysicsScene.SupportsNINJAJoints)
  571. {
  572. PhysicsScene.OnJointMoved -= jointMoved;
  573. PhysicsScene.OnJointDeactivated -= jointDeactivated;
  574. PhysicsScene.OnJointErrorMessage -= jointErrorMessage;
  575. }
  576. m_sceneGraph.PhysicsScene = value;
  577. if (PhysicsScene != null && m_sceneGraph.PhysicsScene.SupportsNINJAJoints)
  578. {
  579. // register event handlers to respond to joint movement/deactivation
  580. PhysicsScene.OnJointMoved += jointMoved;
  581. PhysicsScene.OnJointDeactivated += jointDeactivated;
  582. PhysicsScene.OnJointErrorMessage += jointErrorMessage;
  583. }
  584. }
  585. }
  586. public string DefaultScriptEngine
  587. {
  588. get { return m_defaultScriptEngine; }
  589. }
  590. public EntityManager Entities
  591. {
  592. get { return m_sceneGraph.Entities; }
  593. }
  594. // used in sequence see: SpawnPoint()
  595. private int m_SpawnPoint;
  596. // can be closest/random/sequence
  597. public string SpawnPointRouting
  598. {
  599. get; private set;
  600. }
  601. // allow landmarks to pass
  602. public bool TelehubAllowLandmarks
  603. {
  604. get; private set;
  605. }
  606. #endregion Properties
  607. #region Constructors
  608. public Scene(RegionInfo regInfo, AgentCircuitManager authen,
  609. SceneCommunicationService sceneGridService,
  610. ISimulationDataService simDataService, IEstateDataService estateDataService,
  611. IConfigSource config, string simulatorVersion)
  612. : this(regInfo)
  613. {
  614. m_config = config;
  615. MinFrameTime = 0.089f;
  616. MinMaintenanceTime = 1;
  617. SeeIntoRegion = true;
  618. Random random = new Random();
  619. m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4);
  620. m_authenticateHandler = authen;
  621. m_sceneGridService = sceneGridService;
  622. m_SimulationDataService = simDataService;
  623. m_EstateDataService = estateDataService;
  624. m_regionHandle = RegionInfo.RegionHandle;
  625. m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
  626. m_asyncSceneObjectDeleter.Enabled = true;
  627. m_asyncInventorySender = new AsyncInventorySender(this);
  628. #region Region Settings
  629. // Load region settings
  630. // LoadRegionSettings creates new region settings in persistence if they don't already exist for this region.
  631. // However, in this case, the default textures are not set in memory properly, so we need to do it here and
  632. // resave.
  633. // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
  634. // region is set up and avoid these gyrations.
  635. RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
  636. m_extraSettings = simDataService.GetExtra(RegionInfo.RegionID);
  637. bool updatedTerrainTextures = false;
  638. if (rs.TerrainTexture1 == UUID.Zero)
  639. {
  640. rs.TerrainTexture1 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_1;
  641. updatedTerrainTextures = true;
  642. }
  643. if (rs.TerrainTexture2 == UUID.Zero)
  644. {
  645. rs.TerrainTexture2 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_2;
  646. updatedTerrainTextures = true;
  647. }
  648. if (rs.TerrainTexture3 == UUID.Zero)
  649. {
  650. rs.TerrainTexture3 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_3;
  651. updatedTerrainTextures = true;
  652. }
  653. if (rs.TerrainTexture4 == UUID.Zero)
  654. {
  655. rs.TerrainTexture4 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_4;
  656. updatedTerrainTextures = true;
  657. }
  658. if (updatedTerrainTextures)
  659. rs.Save();
  660. RegionInfo.RegionSettings = rs;
  661. if (estateDataService != null)
  662. RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
  663. #endregion Region Settings
  664. //Bind Storage Manager functions to some land manager functions for this scene
  665. EventManager.OnLandObjectAdded +=
  666. new EventManager.LandObjectAdded(simDataService.StoreLandObject);
  667. EventManager.OnLandObjectRemoved +=
  668. new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
  669. m_sceneGraph = new SceneGraph(this);
  670. // If the scene graph has an Unrecoverable error, restart this sim.
  671. // Currently the only thing that causes it to happen is two kinds of specific
  672. // Physics based crashes.
  673. //
  674. // Out of memory
  675. // Operating system has killed the plugin
  676. m_sceneGraph.UnRecoverableError
  677. += () =>
  678. {
  679. m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name);
  680. RestartNow();
  681. };
  682. RegisterDefaultSceneEvents();
  683. // XXX: Don't set the public property since we don't want to activate here. This needs to be handled
  684. // better in the future.
  685. m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts;
  686. PhysicsEnabled = !RegionInfo.RegionSettings.DisablePhysics;
  687. m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")";
  688. #region Region Config
  689. // Region config overrides global config
  690. //
  691. if (m_config.Configs["Startup"] != null)
  692. {
  693. IConfig startupConfig = m_config.Configs["Startup"];
  694. StartDisabled = startupConfig.GetBoolean("StartDisabled", false);
  695. m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance);
  696. UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup);
  697. if (!UseBackup)
  698. m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName);
  699. //Animation states
  700. m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
  701. SeeIntoRegion = startupConfig.GetBoolean("see_into_region", SeeIntoRegion);
  702. MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
  703. PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims);
  704. CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims);
  705. m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
  706. if (RegionInfo.NonphysPrimMin > 0)
  707. {
  708. m_minNonphys = RegionInfo.NonphysPrimMin;
  709. }
  710. m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
  711. if (RegionInfo.NonphysPrimMax > 0)
  712. {
  713. m_maxNonphys = RegionInfo.NonphysPrimMax;
  714. }
  715. m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
  716. if (RegionInfo.PhysPrimMin > 0)
  717. {
  718. m_minPhys = RegionInfo.PhysPrimMin;
  719. }
  720. m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
  721. if (RegionInfo.PhysPrimMax > 0)
  722. {
  723. m_maxPhys = RegionInfo.PhysPrimMax;
  724. }
  725. // Here, if clamping is requested in either global or
  726. // local config, it will be used
  727. //
  728. m_clampPrimSize = startupConfig.GetBoolean("ClampPrimSize", m_clampPrimSize);
  729. if (RegionInfo.ClampPrimSize)
  730. {
  731. m_clampPrimSize = true;
  732. }
  733. m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
  734. if (RegionInfo.LinksetCapacity > 0)
  735. {
  736. m_linksetCapacity = RegionInfo.LinksetCapacity;
  737. }
  738. m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete", m_useTrashOnDelete);
  739. m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
  740. m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
  741. m_dontPersistBefore =
  742. startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
  743. m_dontPersistBefore *= 10000000;
  744. m_persistAfter =
  745. startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
  746. m_persistAfter *= 10000000;
  747. m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
  748. SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
  749. TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
  750. m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
  751. string[] possibleMapConfigSections = new string[] { "Map", "Startup" };
  752. m_generateMaptiles
  753. = Util.GetConfigVarFromSections<bool>(config, "GenerateMaptiles", possibleMapConfigSections, true);
  754. if (m_generateMaptiles)
  755. {
  756. int maptileRefresh = Util.GetConfigVarFromSections<int>(config, "MaptileRefresh", possibleMapConfigSections, 0);
  757. m_log.InfoFormat("[SCENE]: Region {0}, WORLD MAP refresh time set to {1} seconds", RegionInfo.RegionName, maptileRefresh);
  758. if (maptileRefresh != 0)
  759. {
  760. m_mapGenerationTimer.Interval = maptileRefresh * 1000;
  761. m_mapGenerationTimer.Elapsed += RegenerateMaptileAndReregister;
  762. m_mapGenerationTimer.AutoReset = true;
  763. m_mapGenerationTimer.Start();
  764. }
  765. }
  766. else
  767. {
  768. string tile
  769. = Util.GetConfigVarFromSections<string>(
  770. config, "MaptileStaticUUID", possibleMapConfigSections, UUID.Zero.ToString());
  771. UUID tileID;
  772. if (tile != UUID.Zero.ToString() && UUID.TryParse(tile, out tileID))
  773. {
  774. RegionInfo.RegionSettings.TerrainImageID = tileID;
  775. }
  776. else
  777. {
  778. RegionInfo.RegionSettings.TerrainImageID = RegionInfo.MaptileStaticUUID;
  779. m_log.InfoFormat("[SCENE]: Region {0}, maptile set to {1}", RegionInfo.RegionName, RegionInfo.MaptileStaticUUID.ToString());
  780. }
  781. }
  782. string[] possibleAccessControlConfigSections = new string[] { "AccessControl", "Startup" };
  783. string grant
  784. = Util.GetConfigVarFromSections<string>(
  785. config, "AllowedClients", possibleAccessControlConfigSections, "");
  786. if (grant.Length > 0)
  787. {
  788. foreach (string viewer in grant.Split('|'))
  789. {
  790. m_AllowedViewers.Add(viewer.Trim().ToLower());
  791. }
  792. }
  793. grant
  794. = Util.GetConfigVarFromSections<string>(
  795. config, "BannedClients", possibleAccessControlConfigSections, "");
  796. if (grant.Length > 0)
  797. {
  798. foreach (string viewer in grant.Split('|'))
  799. {
  800. m_BannedViewers.Add(viewer.Trim().ToLower());
  801. }
  802. }
  803. MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime);
  804. m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup);
  805. m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
  806. m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement);
  807. m_update_events = startupConfig.GetInt( "UpdateEventsEveryNFrames", m_update_events);
  808. m_update_objects = startupConfig.GetInt( "UpdateObjectsEveryNFrames", m_update_objects);
  809. m_update_physics = startupConfig.GetInt( "UpdatePhysicsEveryNFrames", m_update_physics);
  810. m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences);
  811. m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
  812. m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
  813. }
  814. // FIXME: Ultimately this should be in a module.
  815. SendPeriodicAppearanceUpdates = true;
  816. IConfig appearanceConfig = m_config.Configs["Appearance"];
  817. if (appearanceConfig != null)
  818. {
  819. SendPeriodicAppearanceUpdates
  820. = appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates);
  821. }
  822. #endregion Region Config
  823. #region Interest Management
  824. IConfig interestConfig = m_config.Configs["InterestManagement"];
  825. if (interestConfig != null)
  826. {
  827. string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
  828. try
  829. {
  830. m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
  831. }
  832. catch (Exception)
  833. {
  834. m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
  835. m_priorityScheme = UpdatePrioritizationSchemes.Time;
  836. }
  837. m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
  838. m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
  839. m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
  840. m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
  841. }
  842. m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme);
  843. #endregion Interest Management
  844. StatsReporter = new SimStatsReporter(this);
  845. StatsReporter.OnSendStatsResult += SendSimStatsPackets;
  846. StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
  847. }
  848. public Scene(RegionInfo regInfo) : base(regInfo)
  849. {
  850. PhysicalPrims = true;
  851. CollidablePrims = true;
  852. PhysicsEnabled = true;
  853. PeriodicBackup = true;
  854. UseBackup = true;
  855. m_eventManager = new EventManager();
  856. m_permissions = new ScenePermissions(this);
  857. }
  858. #endregion
  859. #region Startup / Close Methods
  860. /// <value>
  861. /// The scene graph for this scene
  862. /// </value>
  863. /// TODO: Possibly stop other classes being able to manipulate this directly.
  864. public SceneGraph SceneGraph
  865. {
  866. get { return m_sceneGraph; }
  867. }
  868. protected virtual void RegisterDefaultSceneEvents()
  869. {
  870. IDialogModule dm = RequestModuleInterface<IDialogModule>();
  871. if (dm != null)
  872. m_eventManager.OnPermissionError += dm.SendAlertToUser;
  873. m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
  874. }
  875. public override string GetSimulatorVersion()
  876. {
  877. return m_simulatorVersion;
  878. }
  879. /// <summary>
  880. /// Process the fact that a neighbouring region has come up.
  881. /// </summary>
  882. /// <remarks>
  883. /// We only add it to the neighbor list if it's within 1 region from here.
  884. /// Agents may have draw distance values that cross two regions though, so
  885. /// we add it to the notify list regardless of distance. We'll check
  886. /// the agent's draw distance before notifying them though.
  887. /// </remarks>
  888. /// <param name="otherRegion">RegionInfo handle for the new region.</param>
  889. /// <returns>True after all operations complete, throws exceptions otherwise.</returns>
  890. public override void OtherRegionUp(GridRegion otherRegion)
  891. {
  892. uint xcell = Util.WorldToRegionLoc((uint)otherRegion.RegionLocX);
  893. uint ycell = Util.WorldToRegionLoc((uint)otherRegion.RegionLocY);
  894. //m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}",
  895. // RegionInfo.RegionName, otherRegion.RegionName, xcell, ycell);
  896. if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
  897. {
  898. // If these are cast to INT because long + negative values + abs returns invalid data
  899. int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX);
  900. int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY);
  901. if (resultX <= 1 && resultY <= 1)
  902. {
  903. // Let the grid service module know, so this can be cached
  904. m_eventManager.TriggerOnRegionUp(otherRegion);
  905. try
  906. {
  907. ForEachRootScenePresence(delegate(ScenePresence agent)
  908. {
  909. //agent.ControllingClient.new
  910. //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
  911. List<ulong> old = new List<ulong>();
  912. old.Add(otherRegion.RegionHandle);
  913. agent.DropOldNeighbours(old);
  914. if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
  915. EntityTransferModule.EnableChildAgent(agent, otherRegion);
  916. });
  917. }
  918. catch (NullReferenceException)
  919. {
  920. // This means that we're not booted up completely yet.
  921. // This shouldn't happen too often anymore.
  922. m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
  923. }
  924. }
  925. else
  926. {
  927. m_log.InfoFormat(
  928. "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})",
  929. otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY);
  930. }
  931. }
  932. }
  933. public void AddNeighborRegion(RegionInfo region)
  934. {
  935. lock (m_neighbours)
  936. {
  937. if (!CheckNeighborRegion(region))
  938. {
  939. m_neighbours.Add(region);
  940. }
  941. }
  942. }
  943. public bool CheckNeighborRegion(RegionInfo region)
  944. {
  945. bool found = false;
  946. lock (m_neighbours)
  947. {
  948. foreach (RegionInfo reg in m_neighbours)
  949. {
  950. if (reg.RegionHandle == region.RegionHandle)
  951. {
  952. found = true;
  953. break;
  954. }
  955. }
  956. }
  957. return found;
  958. }
  959. // Alias IncomingHelloNeighbour OtherRegionUp, for now
  960. public GridRegion IncomingHelloNeighbour(RegionInfo neighbour)
  961. {
  962. OtherRegionUp(new GridRegion(neighbour));
  963. return new GridRegion(RegionInfo);
  964. }
  965. // This causes the region to restart immediatley.
  966. public void RestartNow()
  967. {
  968. IConfig startupConfig = m_config.Configs["Startup"];
  969. if (startupConfig != null)
  970. {
  971. if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
  972. {
  973. MainConsole.Instance.RunCommand("shutdown");
  974. return;
  975. }
  976. }
  977. m_log.InfoFormat("[REGION]: Restarting region {0}", Name);
  978. Close();
  979. base.Restart();
  980. }
  981. // This is a helper function that notifies root agents in this region that a new sim near them has come up
  982. // This is in the form of a timer because when an instance of OpenSim.exe is started,
  983. // Even though the sims initialize, they don't listen until 'all of the sims are initialized'
  984. // If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
  985. // subsequently the agent will never see the region come back online.
  986. public void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
  987. {
  988. m_restartWaitTimer.Stop();
  989. lock (m_regionRestartNotifyList)
  990. {
  991. foreach (RegionInfo region in m_regionRestartNotifyList)
  992. {
  993. GridRegion r = new GridRegion(region);
  994. try
  995. {
  996. ForEachRootScenePresence(delegate(ScenePresence agent)
  997. {
  998. if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
  999. EntityTransferModule.EnableChildAgent(agent, r);
  1000. });
  1001. }
  1002. catch (NullReferenceException)
  1003. {
  1004. // This means that we're not booted up completely yet.
  1005. // This shouldn't happen too often anymore.
  1006. }
  1007. }
  1008. // Reset list to nothing.
  1009. m_regionRestartNotifyList.Clear();
  1010. }
  1011. }
  1012. public int GetInaccurateNeighborCount()
  1013. {
  1014. return m_neighbours.Count;
  1015. }
  1016. // This is the method that shuts down the scene.
  1017. public override void Close()
  1018. {
  1019. if (m_shuttingDown)
  1020. {
  1021. m_log.WarnFormat("[SCENE]: Ignoring close request because already closing {0}", Name);
  1022. return;
  1023. }
  1024. m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
  1025. StatsReporter.Close();
  1026. m_restartTimer.Stop();
  1027. m_restartTimer.Close();
  1028. // Kick all ROOT agents with the message, 'The simulator is going down'
  1029. ForEachScenePresence(delegate(ScenePresence avatar)
  1030. {
  1031. avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle);
  1032. if (!avatar.IsChildAgent)
  1033. avatar.ControllingClient.Kick("The simulator is going down.");
  1034. avatar.ControllingClient.SendShutdownConnectionNotice();
  1035. });
  1036. // Stop updating the scene objects and agents.
  1037. m_shuttingDown = true;
  1038. // Wait here, or the kick messages won't actually get to the agents before the scene terminates.
  1039. // We also need to wait to avoid a race condition with the scene update loop which might not yet
  1040. // have checked ShuttingDown.
  1041. Thread.Sleep(500);
  1042. // Stop all client threads.
  1043. ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); });
  1044. m_log.Debug("[SCENE]: Persisting changed objects");
  1045. EventManager.TriggerSceneShuttingDown(this);
  1046. Backup(false);
  1047. m_sceneGraph.Close();
  1048. i

Large files files are truncated, but you can click here to view the full file