SceneManager.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  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 copyright
  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 OpenSim 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.Net;
  30. using System.Reflection;
  31. using OpenMetaverse;
  32. using log4net;
  33. using OpenSim.Framework;
  34. using OpenSim.Region.Environment.Interfaces;
  35. namespace OpenSim.Region.Environment.Scenes
  36. {
  37. public delegate void RestartSim(RegionInfo thisregion);
  38. /// <summary>
  39. /// Manager for adding, closing and restarting scenes.
  40. /// </summary>
  41. public class SceneManager
  42. {
  43. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  44. public event RestartSim OnRestartSim;
  45. private readonly List<Scene> m_localScenes;
  46. private Scene m_currentScene = null;
  47. public List<Scene> Scenes
  48. {
  49. get { return m_localScenes; }
  50. }
  51. public Scene CurrentScene
  52. {
  53. get { return m_currentScene; }
  54. }
  55. public Scene CurrentOrFirstScene
  56. {
  57. get
  58. {
  59. if (m_currentScene == null)
  60. {
  61. return m_localScenes[0];
  62. }
  63. else
  64. {
  65. return m_currentScene;
  66. }
  67. }
  68. }
  69. public SceneManager()
  70. {
  71. m_localScenes = new List<Scene>();
  72. }
  73. public void Close()
  74. {
  75. // collect known shared modules in sharedModules
  76. Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>();
  77. for (int i = 0; i < m_localScenes.Count; i++)
  78. {
  79. // extract known shared modules from scene
  80. foreach (string k in m_localScenes[i].Modules.Keys)
  81. {
  82. if (m_localScenes[i].Modules[k].IsSharedModule &&
  83. !sharedModules.ContainsKey(k))
  84. sharedModules[k] = m_localScenes[i].Modules[k];
  85. }
  86. // close scene/region
  87. m_localScenes[i].Close();
  88. }
  89. // all regions/scenes are now closed, we can now safely
  90. // close all shared modules
  91. foreach (IRegionModule mod in sharedModules.Values)
  92. {
  93. mod.Close();
  94. }
  95. }
  96. public void Close(Scene cscene)
  97. {
  98. if (m_localScenes.Contains(cscene))
  99. {
  100. for (int i = 0; i < m_localScenes.Count; i++)
  101. {
  102. if (m_localScenes[i].Equals(cscene))
  103. {
  104. m_localScenes[i].Close();
  105. }
  106. }
  107. }
  108. }
  109. public void Add(Scene scene)
  110. {
  111. scene.OnRestart += HandleRestart;
  112. m_localScenes.Add(scene);
  113. }
  114. public void HandleRestart(RegionInfo rdata)
  115. {
  116. m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main");
  117. int RegionSceneElement = -1;
  118. for (int i = 0; i < m_localScenes.Count; i++)
  119. {
  120. if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName)
  121. {
  122. RegionSceneElement = i;
  123. }
  124. }
  125. // Now we make sure the region is no longer known about by the SceneManager
  126. // Prevents duplicates.
  127. if (RegionSceneElement >= 0)
  128. {
  129. m_localScenes.RemoveAt(RegionSceneElement);
  130. }
  131. // Send signal to main that we're restarting this sim.
  132. OnRestartSim(rdata);
  133. }
  134. public void SendSimOnlineNotification(ulong regionHandle)
  135. {
  136. RegionInfo Result = null;
  137. for (int i = 0; i < m_localScenes.Count; i++)
  138. {
  139. if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle)
  140. {
  141. // Inform other regions to tell their avatar about me
  142. Result = m_localScenes[i].RegionInfo;
  143. }
  144. }
  145. if (Result != null)
  146. {
  147. for (int i = 0; i < m_localScenes.Count; i++)
  148. {
  149. if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle)
  150. {
  151. // Inform other regions to tell their avatar about me
  152. //m_localScenes[i].OtherRegionUp(Result);
  153. }
  154. }
  155. }
  156. else
  157. {
  158. m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up");
  159. }
  160. }
  161. /// <summary>
  162. /// Save the prims in the current scene to an xml file in OpenSimulator's original 'xml' format
  163. /// </summary>
  164. /// <param name="filename"></param>
  165. public void SaveCurrentSceneToXml(string filename)
  166. {
  167. IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
  168. if (serialiser != null)
  169. serialiser.SavePrimsToXml(CurrentOrFirstScene, filename);
  170. }
  171. /// <summary>
  172. /// Load an xml file of prims in OpenSimulator's original 'xml' file format to the current scene
  173. /// </summary>
  174. /// <param name="filename"></param>
  175. /// <param name="generateNewIDs"></param>
  176. /// <param name="loadOffset"></param>
  177. public void LoadCurrentSceneFromXml(string filename, bool generateNewIDs, Vector3 loadOffset)
  178. {
  179. IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
  180. if (serialiser != null)
  181. serialiser.LoadPrimsFromXml(CurrentOrFirstScene, filename, generateNewIDs, loadOffset);
  182. }
  183. /// <summary>
  184. /// Save the prims in the current scene to an xml file in OpenSimulator's current 'xml2' format
  185. /// </summary>
  186. /// <param name="filename"></param>
  187. public void SaveCurrentSceneToXml2(string filename)
  188. {
  189. IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
  190. if (serialiser != null)
  191. serialiser.SavePrimsToXml2(CurrentOrFirstScene, filename);
  192. }
  193. public void SaveNamedPrimsToXml2(string primName, string filename)
  194. {
  195. IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
  196. if (serialiser != null)
  197. serialiser.SaveNamedPrimsToXml2(CurrentOrFirstScene, primName, filename);
  198. }
  199. /// <summary>
  200. /// Load an xml file of prims in OpenSimulator's current 'xml2' file format to the current scene
  201. /// </summary>
  202. public void LoadCurrentSceneFromXml2(string filename)
  203. {
  204. IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
  205. if (serialiser != null)
  206. serialiser.LoadPrimsFromXml2(CurrentOrFirstScene, filename);
  207. }
  208. /// <summary>
  209. /// Save the current scene to an OpenSimulator archive. This archive will eventually include the prim's assets
  210. /// as well as the details of the prims themselves.
  211. /// </summary>
  212. /// <param name="filename"></param>
  213. public void SaveCurrentSceneToArchive(string filename)
  214. {
  215. IRegionArchiverModule archiver = CurrentOrFirstScene.RequestModuleInterface<IRegionArchiverModule>();
  216. if (archiver != null)
  217. archiver.ArchiveRegion(filename);
  218. }
  219. /// <summary>
  220. /// Load an OpenSim archive into the current scene. This will load both the shapes of the prims and upload
  221. /// their assets to the asset service.
  222. /// </summary>
  223. /// <param name="filename"></param>
  224. public void LoadArchiveToCurrentScene(string filename)
  225. {
  226. IRegionArchiverModule archiver = CurrentOrFirstScene.RequestModuleInterface<IRegionArchiverModule>();
  227. if (archiver != null)
  228. archiver.DearchiveRegion(filename);
  229. }
  230. public string SaveCurrentSceneMapToXmlString()
  231. {
  232. return CurrentOrFirstScene.Heightmap.SaveToXmlString();
  233. }
  234. public void LoadCurrenSceneMapFromXmlString(string mapData)
  235. {
  236. CurrentOrFirstScene.Heightmap.LoadFromXmlString(mapData);
  237. }
  238. [Obsolete("TODO: Remove this warning by 0.7")]
  239. public bool RunTerrainCmdOnCurrentScene(string[] cmdparams, ref string result)
  240. {
  241. m_log.Warn("DEPRECATED: The terrain engine has been replaced with a new terrain plugin module. Please type 'plugin terrain help' for new commands.");
  242. return false;
  243. }
  244. public void SendCommandToPluginModules(string[] cmdparams)
  245. {
  246. ForEachCurrentScene(delegate(Scene scene) { scene.SendCommandToPlugins(cmdparams); });
  247. }
  248. public void SetBypassPermissionsOnCurrentScene(bool bypassPermissions)
  249. {
  250. ForEachCurrentScene(delegate(Scene scene) { scene.Permissions.SetBypassPermissions(bypassPermissions); });
  251. }
  252. private void ForEachCurrentScene(Action<Scene> func)
  253. {
  254. if (m_currentScene == null)
  255. {
  256. m_localScenes.ForEach(func);
  257. }
  258. else
  259. {
  260. func(m_currentScene);
  261. }
  262. }
  263. public void RestartCurrentScene()
  264. {
  265. ForEachCurrentScene(delegate(Scene scene) { scene.RestartNow(); });
  266. }
  267. public void BackupCurrentScene()
  268. {
  269. ForEachCurrentScene(delegate(Scene scene) { scene.Backup(); });
  270. }
  271. public void HandleAlertCommandOnCurrentScene(string[] cmdparams)
  272. {
  273. ForEachCurrentScene(delegate(Scene scene) { scene.HandleAlertCommand(cmdparams); });
  274. }
  275. public void SendGeneralMessage(string msg)
  276. {
  277. ForEachCurrentScene(delegate(Scene scene) { scene.HandleAlertCommand(new string[] { "general", msg }); });
  278. }
  279. public bool TrySetCurrentScene(string regionName)
  280. {
  281. if ((String.Compare(regionName, "root") == 0)
  282. || (String.Compare(regionName, "..") == 0)
  283. || (String.Compare(regionName, "/") == 0))
  284. {
  285. m_currentScene = null;
  286. return true;
  287. }
  288. else
  289. {
  290. foreach (Scene scene in m_localScenes)
  291. {
  292. if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0)
  293. {
  294. m_currentScene = scene;
  295. return true;
  296. }
  297. }
  298. return false;
  299. }
  300. }
  301. public bool TrySetCurrentScene(UUID regionID)
  302. {
  303. Console.WriteLine("Searching for Region: '{0}'", regionID.ToString());
  304. foreach (Scene scene in m_localScenes)
  305. {
  306. if (scene.RegionInfo.RegionID == regionID)
  307. {
  308. m_currentScene = scene;
  309. return true;
  310. }
  311. }
  312. return false;
  313. }
  314. public bool TryGetScene(string regionName, out Scene scene)
  315. {
  316. foreach (Scene mscene in m_localScenes)
  317. {
  318. if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0)
  319. {
  320. scene = mscene;
  321. return true;
  322. }
  323. }
  324. scene = null;
  325. return false;
  326. }
  327. public bool TryGetScene(UUID regionID, out Scene scene)
  328. {
  329. foreach (Scene mscene in m_localScenes)
  330. {
  331. if (mscene.RegionInfo.RegionID == regionID)
  332. {
  333. scene = mscene;
  334. return true;
  335. }
  336. }
  337. scene = null;
  338. return false;
  339. }
  340. public bool TryGetScene(uint locX, uint locY, out Scene scene)
  341. {
  342. foreach (Scene mscene in m_localScenes)
  343. {
  344. if (mscene.RegionInfo.RegionLocX == locX &&
  345. mscene.RegionInfo.RegionLocY == locY)
  346. {
  347. scene = mscene;
  348. return true;
  349. }
  350. }
  351. scene = null;
  352. return false;
  353. }
  354. public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene)
  355. {
  356. foreach (Scene mscene in m_localScenes)
  357. {
  358. if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) &&
  359. (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port))
  360. {
  361. scene = mscene;
  362. return true;
  363. }
  364. }
  365. scene = null;
  366. return false;
  367. }
  368. /// <summary>
  369. /// Set the debug packet level on the current scene. This level governs which packets are printed out to the
  370. /// console.
  371. /// </summary>
  372. /// <param name="newDebug"></param>
  373. public void SetDebugPacketLevelOnCurrentScene(int newDebug)
  374. {
  375. ForEachCurrentScene(delegate(Scene scene)
  376. {
  377. List<ScenePresence> scenePresences = scene.GetScenePresences();
  378. foreach (ScenePresence scenePresence in scenePresences)
  379. {
  380. if (!scenePresence.IsChildAgent)
  381. {
  382. m_log.ErrorFormat("Packet debug for {0} {1} set to {2}",
  383. scenePresence.Firstname,
  384. scenePresence.Lastname,
  385. newDebug);
  386. scenePresence.ControllingClient.SetDebugPacketLevel(newDebug);
  387. }
  388. }
  389. });
  390. }
  391. public List<ScenePresence> GetCurrentSceneAvatars()
  392. {
  393. List<ScenePresence> avatars = new List<ScenePresence>();
  394. ForEachCurrentScene(delegate(Scene scene)
  395. {
  396. List<ScenePresence> scenePresences = scene.GetScenePresences();
  397. foreach (ScenePresence scenePresence in scenePresences)
  398. {
  399. if (!scenePresence.IsChildAgent)
  400. {
  401. avatars.Add(scenePresence);
  402. }
  403. }
  404. });
  405. return avatars;
  406. }
  407. public List<ScenePresence> GetCurrentScenePresences()
  408. {
  409. List<ScenePresence> presences = new List<ScenePresence>();
  410. ForEachCurrentScene(delegate(Scene scene)
  411. {
  412. List<ScenePresence> scenePresences = scene.GetScenePresences();
  413. presences.AddRange(scenePresences);
  414. });
  415. return presences;
  416. }
  417. public RegionInfo GetRegionInfo(ulong regionHandle)
  418. {
  419. foreach (Scene scene in m_localScenes)
  420. {
  421. if (scene.RegionInfo.RegionHandle == regionHandle)
  422. {
  423. return scene.RegionInfo;
  424. }
  425. }
  426. return null;
  427. }
  428. public void ForceCurrentSceneClientUpdate()
  429. {
  430. ForEachCurrentScene(delegate(Scene scene) { scene.ForceClientUpdate(); });
  431. }
  432. public void HandleEditCommandOnCurrentScene(string[] cmdparams)
  433. {
  434. ForEachCurrentScene(delegate(Scene scene) { scene.HandleEditCommand(cmdparams); });
  435. }
  436. public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
  437. {
  438. foreach (Scene scene in m_localScenes)
  439. {
  440. if (scene.TryGetAvatar(avatarId, out avatar))
  441. {
  442. return true;
  443. }
  444. }
  445. avatar = null;
  446. return false;
  447. }
  448. public bool TryGetAvatarsScene(UUID avatarId, out Scene scene)
  449. {
  450. ScenePresence avatar = null;
  451. foreach (Scene mScene in m_localScenes)
  452. {
  453. if (mScene.TryGetAvatar(avatarId, out avatar))
  454. {
  455. scene = mScene;
  456. return true;
  457. }
  458. }
  459. scene = null;
  460. return false;
  461. }
  462. public void CloseScene(Scene scene)
  463. {
  464. m_localScenes.Remove(scene);
  465. scene.Close();
  466. }
  467. public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
  468. {
  469. foreach (Scene scene in m_localScenes)
  470. {
  471. if (scene.TryGetAvatarByName(avatarName, out avatar))
  472. {
  473. return true;
  474. }
  475. }
  476. avatar = null;
  477. return false;
  478. }
  479. public void ForEachScene(Action<Scene> action)
  480. {
  481. m_localScenes.ForEach(action);
  482. }
  483. }
  484. }