PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/VirtualReality/taiga
C# | 4980 lines | 3384 code | 694 blank | 902 comment | 506 complexity | cb7c8e4c8650ce7af238a32b7e33a597 MD5 | raw file

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.Drawing;
  30. using System.Drawing.Imaging;
  31. using System.IO;
  32. using System.Text;
  33. using System.Threading;
  34. using System.Timers;
  35. using System.Xml;
  36. using Nini.Config;
  37. using OpenMetaverse;
  38. using OpenMetaverse.Packets;
  39. using OpenMetaverse.Imaging;
  40. using OpenSim.Framework;
  41. using OpenSim.Services.Interfaces;
  42. using OpenSim.Framework.Communications;
  43. using OpenSim.Framework.Communications.Cache;
  44. using OpenSim.Framework.Communications.Clients;
  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. public enum UpdatePrioritizationSchemes {
  59. Time = 0,
  60. Distance = 1,
  61. SimpleAngularDistance = 2,
  62. FrontBack = 3,
  63. }
  64. public delegate void SynchronizeSceneHandler(Scene scene);
  65. public SynchronizeSceneHandler SynchronizeScene = null;
  66. /* Used by the loadbalancer plugin on GForge */
  67. protected int m_splitRegionID = 0;
  68. public int SplitRegionID
  69. {
  70. get { return m_splitRegionID; }
  71. set { m_splitRegionID = value; }
  72. }
  73. private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
  74. private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
  75. #region Fields
  76. protected Timer m_restartWaitTimer = new Timer();
  77. public SimStatsReporter StatsReporter;
  78. protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
  79. protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
  80. private volatile int m_bordersLocked = 0;
  81. public bool BordersLocked
  82. {
  83. get { return m_bordersLocked == 1; }
  84. set
  85. {
  86. if (value == true)
  87. m_bordersLocked = 1;
  88. else
  89. m_bordersLocked = 0;
  90. }
  91. }
  92. public List<Border> NorthBorders = new List<Border>();
  93. public List<Border> EastBorders = new List<Border>();
  94. public List<Border> SouthBorders = new List<Border>();
  95. public List<Border> WestBorders = new List<Border>();
  96. /// <value>
  97. /// The scene graph for this scene
  98. /// </value>
  99. /// TODO: Possibly stop other classes being able to manipulate this directly.
  100. private SceneGraph m_sceneGraph;
  101. /// <summary>
  102. /// Are we applying physics to any of the prims in this scene?
  103. /// </summary>
  104. public bool m_physicalPrim;
  105. public float m_maxNonphys = 256;
  106. public float m_maxPhys = 10;
  107. public bool m_clampPrimSize;
  108. public bool m_trustBinaries;
  109. public bool m_allowScriptCrossings;
  110. public bool m_useFlySlow;
  111. public bool m_usePreJump;
  112. public bool m_seeIntoRegionFromNeighbor;
  113. // TODO: need to figure out how allow client agents but deny
  114. // root agents when ACL denies access to root agent
  115. public bool m_strictAccessControl = true;
  116. public int MaxUndoCount = 5;
  117. private int m_RestartTimerCounter;
  118. private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
  119. private int m_incrementsof15seconds;
  120. private volatile bool m_backingup;
  121. private bool m_useAsyncWhenPossible;
  122. private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
  123. private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
  124. protected string m_simulatorVersion = "OpenSimulator Server";
  125. protected ModuleLoader m_moduleLoader;
  126. protected StorageManager m_storageManager;
  127. protected AgentCircuitManager m_authenticateHandler;
  128. public CommunicationsManager CommsManager;
  129. protected SceneCommunicationService m_sceneGridService;
  130. public bool LoginsDisabled = true;
  131. public new float TimeDilation
  132. {
  133. get { return m_sceneGraph.PhysicsScene.TimeDilation; }
  134. }
  135. public SceneCommunicationService SceneGridService
  136. {
  137. get { return m_sceneGridService; }
  138. }
  139. public IXfer XferManager;
  140. protected IAssetService m_AssetService;
  141. protected IAuthorizationService m_AuthorizationService;
  142. private Object m_heartbeatLock = new Object();
  143. public IAssetService AssetService
  144. {
  145. get
  146. {
  147. if (m_AssetService == null)
  148. {
  149. m_AssetService = RequestModuleInterface<IAssetService>();
  150. if (m_AssetService == null)
  151. {
  152. throw new Exception("No IAssetService available.");
  153. }
  154. }
  155. return m_AssetService;
  156. }
  157. }
  158. public IAuthorizationService AuthorizationService
  159. {
  160. get
  161. {
  162. if (m_AuthorizationService == null)
  163. {
  164. m_AuthorizationService = RequestModuleInterface<IAuthorizationService>();
  165. if (m_AuthorizationService == null)
  166. {
  167. // don't throw an exception if no authorization service is set for the time being
  168. m_log.InfoFormat("[SCENE]: No Authorization service is configured");
  169. }
  170. }
  171. return m_AuthorizationService;
  172. }
  173. }
  174. protected IInventoryService m_InventoryService;
  175. public IInventoryService InventoryService
  176. {
  177. get
  178. {
  179. if (m_InventoryService == null)
  180. {
  181. m_InventoryService = RequestModuleInterface<IInventoryService>();
  182. if (m_InventoryService == null)
  183. {
  184. 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.");
  185. }
  186. }
  187. return m_InventoryService;
  188. }
  189. }
  190. protected IGridService m_GridService;
  191. public IGridService GridService
  192. {
  193. get
  194. {
  195. if (m_GridService == null)
  196. {
  197. m_GridService = RequestModuleInterface<IGridService>();
  198. if (m_GridService == null)
  199. {
  200. 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.");
  201. }
  202. }
  203. return m_GridService;
  204. }
  205. }
  206. protected IXMLRPC m_xmlrpcModule;
  207. protected IWorldComm m_worldCommModule;
  208. protected IAvatarFactory m_AvatarFactory;
  209. public IAvatarFactory AvatarFactory
  210. {
  211. get { return m_AvatarFactory; }
  212. }
  213. protected IConfigSource m_config;
  214. protected IRegionSerialiserModule m_serialiser;
  215. protected IInterregionCommsOut m_interregionCommsOut;
  216. protected IInterregionCommsIn m_interregionCommsIn;
  217. protected IDialogModule m_dialogModule;
  218. protected ITeleportModule m_teleportModule;
  219. protected ICapabilitiesModule m_capsModule;
  220. public ICapabilitiesModule CapsModule
  221. {
  222. get { return m_capsModule; }
  223. }
  224. protected override IConfigSource GetConfig()
  225. {
  226. return m_config;
  227. }
  228. // Central Update Loop
  229. protected int m_fps = 10;
  230. protected uint m_frame;
  231. protected float m_timespan = 0.089f;
  232. protected DateTime m_lastupdate = DateTime.UtcNow;
  233. private int m_update_physics = 1;
  234. private int m_update_entitymovement = 1;
  235. private int m_update_objects = 1; // Update objects which have scheduled themselves for updates
  236. private int m_update_presences = 1; // Update scene presence movements
  237. private int m_update_events = 1;
  238. private int m_update_backup = 200;
  239. private int m_update_terrain = 50;
  240. private int m_update_land = 1;
  241. private int frameMS;
  242. private int physicsMS2;
  243. private int physicsMS;
  244. private int otherMS;
  245. private int tempOnRezMS;
  246. private int eventMS;
  247. private int backupMS;
  248. private int terrainMS;
  249. private int landMS;
  250. private int lastCompletedFrame;
  251. public int MonitorFrameTime { get { return frameMS; } }
  252. public int MonitorPhysicsUpdateTime { get { return physicsMS; } }
  253. public int MonitorPhysicsSyncTime { get { return physicsMS2; } }
  254. public int MonitorOtherTime { get { return otherMS; } }
  255. public int MonitorTempOnRezTime { get { return tempOnRezMS; } }
  256. public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event?
  257. public int MonitorBackupTime { get { return backupMS; } }
  258. public int MonitorTerrainTime { get { return terrainMS; } }
  259. public int MonitorLandTime { get { return landMS; } }
  260. public int MonitorLastFrameTick { get { return lastCompletedFrame; } }
  261. private bool m_physics_enabled = true;
  262. private bool m_scripts_enabled = true;
  263. private string m_defaultScriptEngine;
  264. private int m_LastLogin;
  265. private Thread HeartbeatThread;
  266. private volatile bool shuttingdown;
  267. private int m_lastUpdate;
  268. private bool m_firstHeartbeat = true;
  269. private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
  270. private bool m_reprioritization_enabled = true;
  271. private double m_reprioritization_interval = 5000.0;
  272. private double m_root_reprioritization_distance = 10.0;
  273. private double m_child_reprioritization_distance = 20.0;
  274. private object m_deleting_scene_object = new object();
  275. // the minimum time that must elapse before a changed object will be considered for persisted
  276. public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L;
  277. // the maximum time that must elapse before a changed object will be considered for persisted
  278. public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
  279. #endregion
  280. #region Properties
  281. public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } }
  282. public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } }
  283. public double ReprioritizationInterval { get { return m_reprioritization_interval; } }
  284. public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } }
  285. public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } }
  286. public AgentCircuitManager AuthenticateHandler
  287. {
  288. get { return m_authenticateHandler; }
  289. }
  290. public SceneGraph SceneContents
  291. {
  292. get { return m_sceneGraph; }
  293. }
  294. // an instance to the physics plugin's Scene object.
  295. public PhysicsScene PhysicsScene
  296. {
  297. get { return m_sceneGraph.PhysicsScene; }
  298. set
  299. {
  300. // If we're not doing the initial set
  301. // Then we've got to remove the previous
  302. // event handler
  303. if (PhysicsScene != null && PhysicsScene.SupportsNINJAJoints)
  304. {
  305. PhysicsScene.OnJointMoved -= jointMoved;
  306. PhysicsScene.OnJointDeactivated -= jointDeactivated;
  307. PhysicsScene.OnJointErrorMessage -= jointErrorMessage;
  308. }
  309. m_sceneGraph.PhysicsScene = value;
  310. if (PhysicsScene != null && m_sceneGraph.PhysicsScene.SupportsNINJAJoints)
  311. {
  312. // register event handlers to respond to joint movement/deactivation
  313. PhysicsScene.OnJointMoved += jointMoved;
  314. PhysicsScene.OnJointDeactivated += jointDeactivated;
  315. PhysicsScene.OnJointErrorMessage += jointErrorMessage;
  316. }
  317. }
  318. }
  319. // This gets locked so things stay thread safe.
  320. public object SyncRoot
  321. {
  322. get { return m_sceneGraph.m_syncRoot; }
  323. }
  324. /// <summary>
  325. /// This is for llGetRegionFPS
  326. /// </summary>
  327. public float SimulatorFPS
  328. {
  329. get { return StatsReporter.getLastReportedSimFPS(); }
  330. }
  331. public float[] SimulatorStats
  332. {
  333. get { return StatsReporter.getLastReportedSimStats(); }
  334. }
  335. public string DefaultScriptEngine
  336. {
  337. get { return m_defaultScriptEngine; }
  338. }
  339. public EntityManager Entities
  340. {
  341. get { return m_sceneGraph.Entities; }
  342. }
  343. public Dictionary<UUID, ScenePresence> m_restorePresences
  344. {
  345. get { return m_sceneGraph.RestorePresences; }
  346. set { m_sceneGraph.RestorePresences = value; }
  347. }
  348. public int objectCapacity = 45000;
  349. #endregion
  350. #region BinaryStats
  351. public class StatLogger
  352. {
  353. public DateTime StartTime;
  354. public string Path;
  355. public System.IO.BinaryWriter Log;
  356. }
  357. static StatLogger m_statLog = null;
  358. static TimeSpan m_statLogPeriod = TimeSpan.FromSeconds(300);
  359. static string m_statsDir = String.Empty;
  360. static Object m_statLockObject = new Object();
  361. private void LogSimStats(SimStats stats)
  362. {
  363. SimStatsPacket pack = new SimStatsPacket();
  364. pack.Region = new SimStatsPacket.RegionBlock();
  365. pack.Region.RegionX = stats.RegionX;
  366. pack.Region.RegionY = stats.RegionY;
  367. pack.Region.RegionFlags = stats.RegionFlags;
  368. pack.Region.ObjectCapacity = stats.ObjectCapacity;
  369. //pack.Region = //stats.RegionBlock;
  370. pack.Stat = stats.StatsBlock;
  371. pack.Header.Reliable = false;
  372. // note that we are inside the reporter lock when called
  373. DateTime now = DateTime.Now;
  374. // hide some time information into the packet
  375. pack.Header.Sequence = (uint)now.Ticks;
  376. lock (m_statLockObject) // m_statLog is shared so make sure there is only executer here
  377. {
  378. try
  379. {
  380. if (m_statLog == null || now > m_statLog.StartTime + m_statLogPeriod)
  381. {
  382. // First log file or time has expired, start writing to a new log file
  383. if (m_statLog != null && m_statLog.Log != null)
  384. {
  385. m_statLog.Log.Close();
  386. }
  387. m_statLog = new StatLogger();
  388. m_statLog.StartTime = now;
  389. m_statLog.Path = (m_statsDir.Length > 0 ? m_statsDir + System.IO.Path.DirectorySeparatorChar.ToString() : "")
  390. + String.Format("stats-{0}.log", now.ToString("yyyyMMddHHmmss"));
  391. m_statLog.Log = new BinaryWriter(File.Open(m_statLog.Path, FileMode.Append, FileAccess.Write));
  392. }
  393. // Write the serialized data to disk
  394. if (m_statLog != null && m_statLog.Log != null)
  395. m_statLog.Log.Write(pack.ToBytes());
  396. }
  397. catch (Exception ex)
  398. {
  399. m_log.Error("statistics gathering failed: " + ex.Message, ex);
  400. if (m_statLog != null && m_statLog.Log != null)
  401. {
  402. m_statLog.Log.Close();
  403. }
  404. m_statLog = null;
  405. }
  406. }
  407. return;
  408. }
  409. #endregion
  410. #region Constructors
  411. public Scene(RegionInfo regInfo, AgentCircuitManager authen,
  412. CommunicationsManager commsMan, SceneCommunicationService sceneGridService,
  413. StorageManager storeManager,
  414. ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
  415. bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
  416. {
  417. m_config = config;
  418. Random random = new Random();
  419. BordersLocked = true;
  420. Border northBorder = new Border();
  421. northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  422. northBorder.CrossDirection = Cardinals.N;
  423. NorthBorders.Add(northBorder);
  424. Border southBorder = new Border();
  425. southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
  426. southBorder.CrossDirection = Cardinals.S;
  427. SouthBorders.Add(southBorder);
  428. Border eastBorder = new Border();
  429. eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  430. eastBorder.CrossDirection = Cardinals.E;
  431. EastBorders.Add(eastBorder);
  432. Border westBorder = new Border();
  433. westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
  434. westBorder.CrossDirection = Cardinals.W;
  435. WestBorders.Add(westBorder);
  436. BordersLocked = false;
  437. m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4);
  438. m_moduleLoader = moduleLoader;
  439. m_authenticateHandler = authen;
  440. CommsManager = commsMan;
  441. m_sceneGridService = sceneGridService;
  442. m_storageManager = storeManager;
  443. m_regInfo = regInfo;
  444. m_regionHandle = m_regInfo.RegionHandle;
  445. m_regionName = m_regInfo.RegionName;
  446. m_datastore = m_regInfo.DataStore;
  447. m_lastUpdate = Util.EnvironmentTickCount();
  448. m_physicalPrim = physicalPrim;
  449. m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
  450. m_eventManager = new EventManager();
  451. m_permissions = new ScenePermissions(this);
  452. m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
  453. m_asyncSceneObjectDeleter.Enabled = true;
  454. // Load region settings
  455. m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
  456. if (m_storageManager.EstateDataStore != null)
  457. {
  458. m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
  459. }
  460. //Bind Storage Manager functions to some land manager functions for this scene
  461. EventManager.OnLandObjectAdded +=
  462. new EventManager.LandObjectAdded(m_storageManager.DataStore.StoreLandObject);
  463. EventManager.OnLandObjectRemoved +=
  464. new EventManager.LandObjectRemoved(m_storageManager.DataStore.RemoveLandObject);
  465. m_sceneGraph = new SceneGraph(this, m_regInfo);
  466. // If the scene graph has an Unrecoverable error, restart this sim.
  467. // Currently the only thing that causes it to happen is two kinds of specific
  468. // Physics based crashes.
  469. //
  470. // Out of memory
  471. // Operating system has killed the plugin
  472. m_sceneGraph.UnRecoverableError += RestartNow;
  473. RegisterDefaultSceneEvents();
  474. DumpAssetsToFile = dumpAssetsToFile;
  475. m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts;
  476. m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics;
  477. StatsReporter = new SimStatsReporter(this);
  478. StatsReporter.OnSendStatsResult += SendSimStatsPackets;
  479. StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
  480. StatsReporter.SetObjectCapacity(objectCapacity);
  481. // Old
  482. /*
  483. m_simulatorVersion = simulatorVersion
  484. + " (OS " + Util.GetOperatingSystemInformation() + ")"
  485. + " ChilTasks:" + m_seeIntoRegionFromNeighbor.ToString()
  486. + " PhysPrim:" + m_physicalPrim.ToString();
  487. */
  488. m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")";
  489. try
  490. {
  491. // Region config overrides global config
  492. //
  493. IConfig startupConfig = m_config.Configs["Startup"];
  494. // Should we try to run loops synchronously or asynchronously?
  495. m_useAsyncWhenPossible = startupConfig.GetBoolean("use_async_when_possible", false);
  496. //Animation states
  497. m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
  498. // TODO: Change default to true once the feature is supported
  499. m_usePreJump = startupConfig.GetBoolean("enableprejump", false);
  500. m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
  501. if (RegionInfo.NonphysPrimMax > 0)
  502. {
  503. m_maxNonphys = RegionInfo.NonphysPrimMax;
  504. }
  505. m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
  506. if (RegionInfo.PhysPrimMax > 0)
  507. {
  508. m_maxPhys = RegionInfo.PhysPrimMax;
  509. }
  510. // Here, if clamping is requested in either global or
  511. // local config, it will be used
  512. //
  513. m_clampPrimSize = startupConfig.GetBoolean("ClampPrimSize", m_clampPrimSize);
  514. if (RegionInfo.ClampPrimSize)
  515. {
  516. m_clampPrimSize = true;
  517. }
  518. m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
  519. m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
  520. m_dontPersistBefore =
  521. startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
  522. m_dontPersistBefore *= 10000000;
  523. m_persistAfter =
  524. startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
  525. m_persistAfter *= 10000000;
  526. m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
  527. IConfig packetConfig = m_config.Configs["PacketPool"];
  528. if (packetConfig != null)
  529. {
  530. PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
  531. PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
  532. }
  533. m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
  534. IConfig interest_management_config = m_config.Configs["InterestManagement"];
  535. if (interest_management_config != null)
  536. {
  537. string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
  538. switch (update_prioritization_scheme)
  539. {
  540. case "time":
  541. m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
  542. break;
  543. case "distance":
  544. m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance;
  545. break;
  546. case "simpleangulardistance":
  547. m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance;
  548. break;
  549. case "frontback":
  550. m_update_prioritization_scheme = UpdatePrioritizationSchemes.FrontBack;
  551. break;
  552. default:
  553. m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time");
  554. m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
  555. break;
  556. }
  557. m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true);
  558. m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0);
  559. m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0);
  560. m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0);
  561. }
  562. m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme");
  563. #region BinaryStats
  564. try
  565. {
  566. IConfig statConfig = m_config.Configs["Statistics.Binary"];
  567. if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled"))
  568. {
  569. if (statConfig.Contains("collect_region_stats"))
  570. {
  571. if (statConfig.GetBoolean("collect_region_stats"))
  572. {
  573. // if enabled, add us to the event. If not enabled, I won't get called
  574. StatsReporter.OnSendStatsResult += LogSimStats;
  575. }
  576. }
  577. if (statConfig.Contains("region_stats_period_seconds"))
  578. {
  579. m_statLogPeriod = TimeSpan.FromSeconds(statConfig.GetInt("region_stats_period_seconds"));
  580. }
  581. if (statConfig.Contains("stats_dir"))
  582. {
  583. m_statsDir = statConfig.GetString("stats_dir");
  584. }
  585. }
  586. }
  587. catch
  588. {
  589. // if it doesn't work, we don't collect anything
  590. }
  591. #endregion BinaryStats
  592. }
  593. catch
  594. {
  595. m_log.Warn("[SCENE]: Failed to load StartupConfig");
  596. }
  597. }
  598. /// <summary>
  599. /// Mock constructor for scene group persistency unit tests.
  600. /// SceneObjectGroup RegionId property is delegated to Scene.
  601. /// </summary>
  602. /// <param name="regInfo"></param>
  603. public Scene(RegionInfo regInfo)
  604. {
  605. BordersLocked = true;
  606. Border northBorder = new Border();
  607. northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  608. northBorder.CrossDirection = Cardinals.N;
  609. NorthBorders.Add(northBorder);
  610. Border southBorder = new Border();
  611. southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
  612. southBorder.CrossDirection = Cardinals.S;
  613. SouthBorders.Add(southBorder);
  614. Border eastBorder = new Border();
  615. eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  616. eastBorder.CrossDirection = Cardinals.E;
  617. EastBorders.Add(eastBorder);
  618. Border westBorder = new Border();
  619. westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
  620. westBorder.CrossDirection = Cardinals.W;
  621. WestBorders.Add(westBorder);
  622. BordersLocked = false;
  623. m_regInfo = regInfo;
  624. m_eventManager = new EventManager();
  625. m_lastUpdate = Util.EnvironmentTickCount();
  626. }
  627. #endregion
  628. #region Startup / Close Methods
  629. public bool ShuttingDown
  630. {
  631. get { return shuttingdown; }
  632. }
  633. /// <value>
  634. /// The scene graph for this scene
  635. /// </value>
  636. /// TODO: Possibly stop other classes being able to manipulate this directly.
  637. public SceneGraph SceneGraph
  638. {
  639. get { return m_sceneGraph; }
  640. }
  641. protected virtual void RegisterDefaultSceneEvents()
  642. {
  643. IDialogModule dm = RequestModuleInterface<IDialogModule>();
  644. if (dm != null)
  645. m_eventManager.OnPermissionError += dm.SendAlertToUser;
  646. }
  647. public override string GetSimulatorVersion()
  648. {
  649. return m_simulatorVersion;
  650. }
  651. /// <summary>
  652. /// Another region is up.
  653. ///
  654. /// We only add it to the neighbor list if it's within 1 region from here.
  655. /// Agents may have draw distance values that cross two regions though, so
  656. /// we add it to the notify list regardless of distance. We'll check
  657. /// the agent's draw distance before notifying them though.
  658. /// </summary>
  659. /// <param name="otherRegion">RegionInfo handle for the new region.</param>
  660. /// <returns>True after all operations complete, throws exceptions otherwise.</returns>
  661. public override void OtherRegionUp(GridRegion otherRegion)
  662. {
  663. uint xcell = (uint)((int)otherRegion.RegionLocX / (int)Constants.RegionSize);
  664. uint ycell = (uint)((int)otherRegion.RegionLocY / (int)Constants.RegionSize);
  665. m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}",
  666. RegionInfo.RegionName, otherRegion.RegionName, xcell, ycell);
  667. if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
  668. {
  669. // If these are cast to INT because long + negative values + abs returns invalid data
  670. int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX);
  671. int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY);
  672. if (resultX <= 1 && resultY <= 1)
  673. {
  674. // Let the grid service module know, so this can be cached
  675. m_eventManager.TriggerOnRegionUp(otherRegion);
  676. RegionInfo regInfo = new RegionInfo(xcell, ycell, otherRegion.InternalEndPoint, otherRegion.ExternalHostName);
  677. regInfo.RegionID = otherRegion.RegionID;
  678. regInfo.RegionName = otherRegion.RegionName;
  679. regInfo.ScopeID = otherRegion.ScopeID;
  680. regInfo.ExternalHostName = otherRegion.ExternalHostName;
  681. try
  682. {
  683. ForEachScenePresence(delegate(ScenePresence agent)
  684. {
  685. // If agent is a root agent.
  686. if (!agent.IsChildAgent)
  687. {
  688. //agent.ControllingClient.new
  689. //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
  690. List<ulong> old = new List<ulong>();
  691. old.Add(otherRegion.RegionHandle);
  692. agent.DropOldNeighbours(old);
  693. InformClientOfNeighbor(agent, regInfo);
  694. }
  695. }
  696. );
  697. }
  698. catch (NullReferenceException)
  699. {
  700. // This means that we're not booted up completely yet.
  701. // This shouldn't happen too often anymore.
  702. m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
  703. }
  704. }
  705. else
  706. {
  707. m_log.Info("[INTERGRID]: Got notice about far away Region: " + otherRegion.RegionName.ToString() +
  708. " at (" + otherRegion.RegionLocX.ToString() + ", " +
  709. otherRegion.RegionLocY.ToString() + ")");
  710. }
  711. }
  712. }
  713. public void AddNeighborRegion(RegionInfo region)
  714. {
  715. lock (m_neighbours)
  716. {
  717. if (!CheckNeighborRegion(region))
  718. {
  719. m_neighbours.Add(region);
  720. }
  721. }
  722. }
  723. public bool CheckNeighborRegion(RegionInfo region)
  724. {
  725. bool found = false;
  726. lock (m_neighbours)
  727. {
  728. foreach (RegionInfo reg in m_neighbours)
  729. {
  730. if (reg.RegionHandle == region.RegionHandle)
  731. {
  732. found = true;
  733. break;
  734. }
  735. }
  736. }
  737. return found;
  738. }
  739. // Alias IncomingHelloNeighbour OtherRegionUp, for now
  740. public GridRegion IncomingHelloNeighbour(RegionInfo neighbour)
  741. {
  742. OtherRegionUp(new GridRegion(neighbour));
  743. return new GridRegion(RegionInfo);
  744. }
  745. /// <summary>
  746. /// Given float seconds, this will restart the region.
  747. /// </summary>
  748. /// <param name="seconds">float indicating duration before restart.</param>
  749. public virtual void Restart(float seconds)
  750. {
  751. // notifications are done in 15 second increments
  752. // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
  753. // It's a 'Cancel restart' request.
  754. // RestartNow() does immediate restarting.
  755. if (seconds < 15)
  756. {
  757. m_restartTimer.Stop();
  758. m_dialogModule.SendGeneralAlert("Restart Aborted");
  759. }
  760. else
  761. {
  762. // Now we figure out what to set the timer to that does the notifications and calls, RestartNow()
  763. m_restartTimer.Interval = 15000;
  764. m_incrementsof15seconds = (int)seconds / 15;
  765. m_RestartTimerCounter = 0;
  766. m_restartTimer.AutoReset = true;
  767. m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
  768. m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
  769. m_restartTimer.Start();
  770. m_dialogModule.SendNotificationToUsersInRegion(
  771. UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0)));
  772. }
  773. }
  774. // The Restart timer has occured.
  775. // We have to figure out if this is a notification or if the number of seconds specified in Restart
  776. // have elapsed.
  777. // If they have elapsed, call RestartNow()
  778. public void RestartTimer_Elapsed(object sender, ElapsedEventArgs e)
  779. {
  780. m_RestartTimerCounter++;
  781. if (m_RestartTimerCounter <= m_incrementsof15seconds)
  782. {
  783. if (m_RestartTimerCounter == 4 || m_RestartTimerCounter == 6 || m_RestartTimerCounter == 7)
  784. m_dialogModule.SendNotificationToUsersInRegion(
  785. UUID.Random(),
  786. String.Empty,
  787. RegionInfo.RegionName + ": Restarting in " + ((8 - m_RestartTimerCounter) * 15) + " seconds");
  788. }
  789. else
  790. {
  791. m_restartTimer.Stop();
  792. m_restartTimer.AutoReset = false;
  793. RestartNow();
  794. }
  795. }
  796. // This causes the region to restart immediatley.
  797. public void RestartNow()
  798. {
  799. IConfig startupConfig = m_config.Configs["Startup"];
  800. if (startupConfig != null)
  801. {
  802. if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
  803. {
  804. MainConsole.Instance.RunCommand("shutdown");
  805. return;
  806. }
  807. }
  808. if (PhysicsScene != null)
  809. {
  810. PhysicsScene.Dispose();
  811. }
  812. m_log.Error("[REGION]: Closing");
  813. Close();
  814. m_log.Error("[REGION]: Firing Region Restart Message");
  815. base.Restart(0);
  816. }
  817. // This is a helper function that notifies root agents in this region that a new sim near them has come up
  818. // This is in the form of a timer because when an instance of OpenSim.exe is started,
  819. // Even though the sims initialize, they don't listen until 'all of the sims are initialized'
  820. // If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
  821. // subsequently the agent will never see the region come back online.
  822. public void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
  823. {
  824. m_restartWaitTimer.Stop();
  825. lock (m_regionRestartNotifyList)
  826. {
  827. foreach (RegionInfo region in m_regionRestartNotifyList)
  828. {
  829. try
  830. {
  831. ForEachScenePresence(delegate(ScenePresence agent)
  832. {
  833. // If agent is a root agent.
  834. if (!agent.IsChildAgent)
  835. {
  836. //agent.ControllingClient.new
  837. //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
  838. InformClientOfNeighbor(agent, region);
  839. }
  840. }
  841. );
  842. }
  843. catch (NullReferenceException)
  844. {
  845. // This means that we're not booted up completely yet.
  846. // This shouldn't happen too often anymore.
  847. }
  848. }
  849. // Reset list to nothing.
  850. m_regionRestartNotifyList.Clear();
  851. }
  852. }
  853. public void SetSceneCoreDebug(bool ScriptEngine, bool CollisionEvents, bool PhysicsEngine)
  854. {
  855. if (m_scripts_enabled != !ScriptEngine)
  856. {
  857. // Tedd! Here's the method to disable the scripting engine!
  858. if (ScriptEngine)
  859. {
  860. m_log.Info("Stopping all Scripts in Scene");
  861. foreach (EntityBase ent in Entities)
  862. {
  863. if (ent is SceneObjectGroup)
  864. {
  865. ((SceneObjectGroup) ent).RemoveScriptInstances(false);
  866. }
  867. }
  868. }
  869. else
  870. {
  871. m_log.Info("Starting all Scripts in Scene");
  872. lock (Entities)
  873. {
  874. foreach (EntityBase ent in Entities)
  875. {
  876. if (ent is SceneObjectGroup)
  877. {
  878. ((SceneObjectGroup)ent).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
  879. }
  880. }
  881. }
  882. }
  883. m_scripts_enabled = !ScriptEngine;
  884. m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine");
  885. }
  886. if (m_physics_enabled != !PhysicsEngine)
  887. {
  888. m_physics_enabled = !PhysicsEngine;
  889. }
  890. }
  891. public int GetInaccurateNeighborCount()
  892. {
  893. return m_neighbours.Count;
  894. }
  895. // This is the method that shuts down the scene.
  896. public override void Close()
  897. {
  898. m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
  899. m_restartTimer.Stop();
  900. m_restartTimer.Close();
  901. // Kick all ROOT agents with the message, 'The simulator is going down'
  902. ForEachScenePresence(delegate(ScenePresence avatar)
  903. {
  904. if (avatar.KnownChildRegionHandles.Contains(RegionInfo.RegionHandle))
  905. avatar.KnownChildRegionHandles.Remove(RegionInfo.RegionHandle);
  906. if (!avatar.IsChildAgent)
  907. avatar.ControllingClient.Kick("The simulator is going down.");
  908. avatar.ControllingClient.SendShutdownConnectionNotice();
  909. });
  910. // Wait here, or the kick messages won't actually get to the agents before the scene terminates.
  911. Thread.Sleep(500);
  912. // Stop all client threads.
  913. ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
  914. // Stop updating the scene objects and agents.
  915. //m_heartbeatTimer.Close();
  916. shuttingdown = true;
  917. m_log.Debug("[SCENE]: Persisting changed objects");
  918. List<EntityBase> entities = GetEntities();
  919. foreach (EntityBase entity in entities)
  920. {
  921. if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged)
  922. {
  923. ((SceneObjectGroup)entity).ProcessBackup(m_storageManager.DataStore, false);
  924. }
  925. }
  926. m_sceneGraph.Close();
  927. // De-register with region communications (events cleanup)
  928. UnRegisterRegionWithComms();
  929. // call the base class Close method.
  930. base.Close();
  931. }
  932. /// <summary>
  933. /// Start the timer which triggers regular scene updates
  934. /// </summary>
  935. public void StartTimer()
  936. {
  937. //m_log.Debug("[SCENE]: Starting timer");
  938. //m_heartbeatTimer.Enabled = true;
  939. //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
  940. //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
  941. if (HeartbeatThread != null)
  942. {
  943. HeartbeatThread.Abort();
  944. HeartbeatThread = null;
  945. }
  946. m_lastUpdate = Util.EnvironmentTickCount();
  947. HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false);
  948. }
  949. /// <summary>
  950. /// Sets up references to modules required by the scene
  951. /// </summary>
  952. public void SetModuleInterfaces()
  953. {
  954. m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
  955. m_worldCommModule = RequestModuleInterface<IWorldComm>();
  956. XferManager = RequestModuleInterface<IXfer>();
  957. m_AvatarFactory = RequestModuleInterface<IAvatarFactory>();
  958. m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
  959. m_interregionCommsOut = RequestModuleInterface<IInterregionCommsOut>();
  960. m_interregionCommsIn = RequestModuleInterface<IInterregionCommsIn>();
  961. m_dialogModule = RequestModuleInterface<IDialogModule>();
  962. m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
  963. m_teleportModule = RequestModuleInterface<ITeleportModule>();
  964. }
  965. #endregion
  966. #region Update Methods
  967. /// <summary>
  968. /// Performs per-frame updates regularly
  969. /// </summary>
  970. private void Heartbeat()
  971. {
  972. if (!Monitor.TryEnter(m_heartbeatLock))
  973. {
  974. Watchdog.RemoveThread();
  975. return;
  976. }
  977. try
  978. {
  979. Update();
  980. m_lastUpdate = Util.EnvironmentTickCount();
  981. m_firstHeartbeat = false;
  982. }
  983. catch (ThreadAbortException)
  984. {
  985. }
  986. finally
  987. {
  988. Monitor.Pulse(m_heartbeatLock);
  989. Monitor.Exit(m_heartbeatLock);
  990. }
  991. Watchdog.RemoveThread();
  992. }
  993. /// <summary>
  994. /// Performs per-frame updates on the scene, this should be the central scene loop
  995. /// </summary>
  996. public override void Update()
  997. {
  998. float physicsFPS;
  999. int maintc;
  1000. while (!shuttingdown)
  1001. {
  1002. TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
  1003. physicsFPS = 0f;
  1004. maintc = Util.EnvironmentTickCount();
  1005. int tmpFrameMS = maintc;
  1006. tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
  1007. // Increment the frame counter
  1008. ++m_frame;
  1009. try
  1010. {
  1011. // Check if any objects have reached their targets
  1012. CheckAtTargets();
  1013. // Update SceneObjectGroups that have scheduled themselves for updates
  1014. // Objects queue their updates onto all scene presences
  1015. if (m_frame % m_update_objects == 0)
  1016. m_sceneGraph.UpdateObjectGroups();
  1017. // Run through all ScenePresences looking for updates
  1018. // Presence updates and queued object updates for each presence are sent to clients
  1019. if (m_frame % m_update_presences == 0)
  1020. m_sceneGraph.UpdatePresences();
  1021. int tmpPhysicsMS2 = Util.EnvironmentTickCount();
  1022. if ((m_frame % m_update_physics == 0) && m_physics_enabled)
  1023. m_sceneGraph.UpdatePreparePhysics();
  1024. physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
  1025. if (m_frame % m_update_entitymovement == 0)
  1026. m_sceneGraph.UpdateScenePresenceMovement();
  1027. int tmpPhysicsMS = Util.EnvironmentTickCount();
  1028. if (m_frame % m_update_physics == 0)

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