PageRenderTime 100ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 2ms

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

https://bitbucket.org/AlethiaGrid/opensimulator-0.7-.x
C# | 5690 lines | 3699 code | 787 blank | 1204 comment | 637 complexity | a1705233d09363ab7ed15e1aa9d5314e MD5 | raw file
Possible License(s): MIT, BSD-3-Clause

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

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