Scene.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. /*
  2. * Copyright (c) Contributors, http://www.openmetaverse.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. */
  28. using System;
  29. using libsecondlife;
  30. using libsecondlife.Packets;
  31. using System.Collections.Generic;
  32. using System.Text;
  33. using System.Reflection;
  34. using System.IO;
  35. using System.Threading;
  36. using System.Timers;
  37. using OpenSim.Physics.Manager;
  38. using OpenSim.Framework.Interfaces;
  39. using OpenSim.Framework.Types;
  40. using OpenSim.Framework.Inventory;
  41. using OpenSim.Framework;
  42. using OpenSim.Region.Scripting;
  43. using OpenSim.Terrain;
  44. using OpenGrid.Framework.Communications;
  45. using OpenSim.Caches;
  46. namespace OpenSim.Region.Scenes
  47. {
  48. public delegate bool FilterAvatarList(Avatar avatar);
  49. public partial class Scene : SceneBase, ILocalStorageReceiver, IScriptAPI
  50. {
  51. protected System.Timers.Timer m_heartbeatTimer = new System.Timers.Timer();
  52. protected Dictionary<libsecondlife.LLUUID, Avatar> Avatars;
  53. protected Dictionary<libsecondlife.LLUUID, Primitive> Prims;
  54. private PhysicsScene phyScene;
  55. private float timeStep = 0.1f;
  56. public ILocalStorage localStorage;
  57. private Random Rand = new Random();
  58. private uint _primCount = 702000;
  59. private int storageCount;
  60. private Dictionary<LLUUID, ScriptHandler> m_scriptHandlers;
  61. private Dictionary<string, ScriptFactory> m_scripts;
  62. private Mutex updateLock;
  63. public string m_datastore;
  64. protected AuthenticateSessionsBase authenticateHandler;
  65. protected RegionCommsListener regionCommsHost;
  66. protected CommunicationsManager commsManager;
  67. public ParcelManager parcelManager;
  68. public EstateManager estateManager;
  69. #region Properties
  70. /// <summary>
  71. ///
  72. /// </summary>
  73. public PhysicsScene PhysScene
  74. {
  75. set
  76. {
  77. this.phyScene = value;
  78. }
  79. get
  80. {
  81. return (this.phyScene);
  82. }
  83. }
  84. #endregion
  85. #region Constructors
  86. /// <summary>
  87. /// Creates a new World class, and a region to go with it.
  88. /// </summary>
  89. /// <param name="clientThreads">Dictionary to contain client threads</param>
  90. /// <param name="regionHandle">Region Handle for this region</param>
  91. /// <param name="regionName">Region Name for this region</param>
  92. public Scene(Dictionary<uint, IClientAPI> clientThreads, RegionInfo regInfo, AuthenticateSessionsBase authen, CommunicationsManager commsMan, AssetCache assetCach)
  93. {
  94. try
  95. {
  96. updateLock = new Mutex(false);
  97. this.authenticateHandler = authen;
  98. this.commsManager = commsMan;
  99. this.assetCache = assetCach;
  100. m_clientThreads = clientThreads;
  101. m_regInfo = regInfo;
  102. m_regionHandle = m_regInfo.RegionHandle;
  103. m_regionName = m_regInfo.RegionName;
  104. this.m_datastore = m_regInfo.DataStore;
  105. this.RegisterRegionWithComms();
  106. parcelManager = new ParcelManager(this, this.m_regInfo);
  107. estateManager = new EstateManager(this, this.m_regInfo);
  108. m_scriptHandlers = new Dictionary<LLUUID, ScriptHandler>();
  109. m_scripts = new Dictionary<string, ScriptFactory>();
  110. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs - creating new entitities instance");
  111. Entities = new Dictionary<libsecondlife.LLUUID, Entity>();
  112. Avatars = new Dictionary<LLUUID, Avatar>();
  113. Prims = new Dictionary<LLUUID, Primitive>();
  114. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs - creating LandMap");
  115. TerrainManager = new TerrainManager(new SecondLife());
  116. Terrain = new TerrainEngine();
  117. Avatar.LoadAnims();
  118. }
  119. catch (Exception e)
  120. {
  121. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.CRITICAL, "World.cs: Constructor failed with exception " + e.ToString());
  122. }
  123. }
  124. #endregion
  125. /// <summary>
  126. ///
  127. /// </summary>
  128. public void StartTimer()
  129. {
  130. m_heartbeatTimer.Enabled = true;
  131. m_heartbeatTimer.Interval = 100;
  132. m_heartbeatTimer.Elapsed += new ElapsedEventHandler(this.Heartbeat);
  133. }
  134. #region Update Methods
  135. /// <summary>
  136. /// Performs per-frame updates regularly
  137. /// </summary>
  138. /// <param name="sender"></param>
  139. /// <param name="e"></param>
  140. void Heartbeat(object sender, System.EventArgs e)
  141. {
  142. this.Update();
  143. }
  144. /// <summary>
  145. /// Performs per-frame updates on the world, this should be the central world loop
  146. /// </summary>
  147. public override void Update()
  148. {
  149. updateLock.WaitOne();
  150. try
  151. {
  152. if (this.phyScene.IsThreaded)
  153. {
  154. this.phyScene.GetResults();
  155. }
  156. foreach (libsecondlife.LLUUID UUID in Entities.Keys)
  157. {
  158. Entities[UUID].addForces();
  159. }
  160. lock (this.m_syncRoot)
  161. {
  162. this.phyScene.Simulate(timeStep);
  163. }
  164. foreach (libsecondlife.LLUUID UUID in Entities.Keys)
  165. {
  166. Entities[UUID].update();
  167. }
  168. foreach (ScriptHandler scriptHandler in m_scriptHandlers.Values)
  169. {
  170. scriptHandler.OnFrame();
  171. }
  172. foreach (IScriptEngine scripteng in this.scriptEngines.Values)
  173. {
  174. scripteng.OnFrame();
  175. }
  176. //backup world data
  177. this.storageCount++;
  178. if (storageCount > 1200) //set to how often you want to backup
  179. {
  180. this.Backup();
  181. storageCount = 0;
  182. }
  183. }
  184. catch (Exception e)
  185. {
  186. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: Update() - Failed with exception " + e.ToString());
  187. }
  188. updateLock.ReleaseMutex();
  189. }
  190. /// <summary>
  191. ///
  192. /// </summary>
  193. /// <returns></returns>
  194. public bool Backup()
  195. {
  196. /*
  197. try
  198. {
  199. // Terrain backup routines
  200. if (Terrain.tainted > 0)
  201. {
  202. Terrain.tainted = 0;
  203. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Terrain tainted, saving.");
  204. localStorage.SaveMap(Terrain.getHeights1D());
  205. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Terrain saved, informing Physics.");
  206. lock (this.m_syncRoot)
  207. {
  208. phyScene.SetTerrain(Terrain.getHeights1D());
  209. }
  210. }
  211. // Primitive backup routines
  212. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Backing up Primitives");
  213. foreach (libsecondlife.LLUUID UUID in Entities.Keys)
  214. {
  215. Entities[UUID].BackUp();
  216. }
  217. //Parcel backup routines
  218. ParcelData[] parcels = new ParcelData[parcelManager.parcelList.Count];
  219. int i = 0;
  220. foreach (OpenSim.Region.Parcel parcel in parcelManager.parcelList.Values)
  221. {
  222. parcels[i] = parcel.parcelData;
  223. i++;
  224. }
  225. localStorage.SaveParcels(parcels);
  226. // Backup successful
  227. return true;
  228. }
  229. catch (Exception e)
  230. {
  231. // Backup failed
  232. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Backup() - Backup Failed with exception " + e.ToString());
  233. return false;
  234. }
  235. */
  236. return true;
  237. }
  238. #endregion
  239. #region Setup Methods
  240. /// <summary>
  241. /// Loads a new storage subsystem from a named library
  242. /// </summary>
  243. /// <param name="dllName">Storage Library</param>
  244. /// <returns>Successful or not</returns>
  245. public bool LoadStorageDLL(string dllName)
  246. {
  247. try
  248. {
  249. Assembly pluginAssembly = Assembly.LoadFrom(dllName);
  250. ILocalStorage store = null;
  251. foreach (Type pluginType in pluginAssembly.GetTypes())
  252. {
  253. if (pluginType.IsPublic)
  254. {
  255. if (!pluginType.IsAbstract)
  256. {
  257. Type typeInterface = pluginType.GetInterface("ILocalStorage", true);
  258. if (typeInterface != null)
  259. {
  260. ILocalStorage plug = (ILocalStorage)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
  261. store = plug;
  262. store.Initialise(this.m_datastore);
  263. break;
  264. }
  265. typeInterface = null;
  266. }
  267. }
  268. }
  269. pluginAssembly = null;
  270. this.localStorage = store;
  271. return (store == null);
  272. }
  273. catch (Exception e)
  274. {
  275. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: LoadStorageDLL() - Failed with exception " + e.ToString());
  276. return false;
  277. }
  278. }
  279. #endregion
  280. #region Regenerate Terrain
  281. /// <summary>
  282. /// Rebuilds the terrain using a procedural algorithm
  283. /// </summary>
  284. public void RegenerateTerrain()
  285. {
  286. try
  287. {
  288. Terrain.hills();
  289. lock (this.m_syncRoot)
  290. {
  291. this.phyScene.SetTerrain(Terrain.getHeights1D());
  292. }
  293. this.localStorage.SaveMap(this.Terrain.getHeights1D());
  294. foreach (IClientAPI client in m_clientThreads.Values)
  295. {
  296. this.SendLayerData(client);
  297. }
  298. foreach (libsecondlife.LLUUID UUID in Entities.Keys)
  299. {
  300. Entities[UUID].LandRenegerated();
  301. }
  302. }
  303. catch (Exception e)
  304. {
  305. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
  306. }
  307. }
  308. /// <summary>
  309. /// Rebuilds the terrain using a 2D float array
  310. /// </summary>
  311. /// <param name="newMap">256,256 float array containing heights</param>
  312. public void RegenerateTerrain(float[,] newMap)
  313. {
  314. try
  315. {
  316. this.Terrain.setHeights2D(newMap);
  317. lock (this.m_syncRoot)
  318. {
  319. this.phyScene.SetTerrain(this.Terrain.getHeights1D());
  320. }
  321. this.localStorage.SaveMap(this.Terrain.getHeights1D());
  322. foreach (IClientAPI client in m_clientThreads.Values)
  323. {
  324. this.SendLayerData(client);
  325. }
  326. foreach (libsecondlife.LLUUID UUID in Entities.Keys)
  327. {
  328. Entities[UUID].LandRenegerated();
  329. }
  330. }
  331. catch (Exception e)
  332. {
  333. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
  334. }
  335. }
  336. /// <summary>
  337. /// Rebuilds the terrain assuming changes occured at a specified point[?]
  338. /// </summary>
  339. /// <param name="changes">???</param>
  340. /// <param name="pointx">???</param>
  341. /// <param name="pointy">???</param>
  342. public void RegenerateTerrain(bool changes, int pointx, int pointy)
  343. {
  344. try
  345. {
  346. if (changes)
  347. {
  348. /* Dont save here, rely on tainting system instead */
  349. foreach (IClientAPI client in m_clientThreads.Values)
  350. {
  351. this.SendLayerData(pointx, pointy, client);
  352. }
  353. }
  354. }
  355. catch (Exception e)
  356. {
  357. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
  358. }
  359. }
  360. #endregion
  361. #region Load Terrain
  362. /// <summary>
  363. /// Loads the World heightmap
  364. /// </summary>
  365. public override void LoadWorldMap()
  366. {
  367. try
  368. {
  369. float[] map = this.localStorage.LoadWorld();
  370. if (map == null)
  371. {
  372. Console.WriteLine("creating new terrain");
  373. this.Terrain.hills();
  374. // this.localStorage.SaveMap(this.Terrain.getHeights1D());
  375. }
  376. else
  377. {
  378. this.Terrain.setHeights1D(map);
  379. }
  380. //create a texture asset of the terrain
  381. byte[] data =this.Terrain.exportJpegImage("defaultstripe.png");
  382. this.m_regInfo.estateSettings.terrainImageID= LLUUID.Random();
  383. AssetBase asset = new AssetBase();
  384. asset.FullID = this.m_regInfo.estateSettings.terrainImageID;
  385. asset.Data = data;
  386. asset.Name = "terrainImage";
  387. asset.Type = 0;
  388. this.assetCache.AddAsset(asset);
  389. }
  390. catch (Exception e)
  391. {
  392. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: LoadWorldMap() - Failed with exception " + e.ToString());
  393. }
  394. }
  395. #endregion
  396. #region Primitives Methods
  397. /// <summary>
  398. /// Loads the World's objects
  399. /// </summary>
  400. public void LoadPrimsFromStorage()
  401. {
  402. try
  403. {
  404. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: LoadPrimsFromStorage() - Loading primitives");
  405. this.localStorage.LoadPrimitives(this);
  406. }
  407. catch (Exception e)
  408. {
  409. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: LoadPrimsFromStorage() - Failed with exception " + e.ToString());
  410. }
  411. }
  412. /// <summary>
  413. /// Loads a specific object from storage
  414. /// </summary>
  415. /// <param name="prim">The object to load</param>
  416. public void PrimFromStorage(PrimData prim)
  417. {
  418. }
  419. /// <summary>
  420. ///
  421. /// </summary>
  422. /// <param name="addPacket"></param>
  423. /// <param name="agentClient"></param>
  424. public void AddNewPrim(Packet addPacket, IClientAPI agentClient)
  425. {
  426. AddNewPrim((ObjectAddPacket)addPacket, agentClient.AgentId);
  427. }
  428. /// <summary>
  429. ///
  430. /// </summary>
  431. /// <param name="addPacket"></param>
  432. /// <param name="ownerID"></param>
  433. public void AddNewPrim(ObjectAddPacket addPacket, LLUUID ownerID)
  434. {
  435. try
  436. {
  437. // MainConsole.Instance.Notice("World.cs: AddNewPrim() - Creating new prim");
  438. Primitive prim = new Primitive(m_regionHandle, this, addPacket, ownerID, this._primCount);
  439. this.Entities.Add(prim.uuid, prim);
  440. this._primCount++;
  441. }
  442. catch (Exception e)
  443. {
  444. // MainConsole.Instance.Warn("World.cs: AddNewPrim() - Failed with exception " + e.ToString());
  445. }
  446. }
  447. #endregion
  448. #region Add/Remove Avatar Methods
  449. /// <summary>
  450. ///
  451. /// </summary>
  452. /// <param name="remoteClient"></param
  453. /// <param name="agentID"></param>
  454. /// <param name="child"></param>
  455. public override void AddNewAvatar(IClientAPI remoteClient, LLUUID agentID, bool child)
  456. {
  457. remoteClient.OnRegionHandShakeReply += new GenericCall(this.SendLayerData);
  458. //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims);
  459. remoteClient.OnChatFromViewer += new ChatFromViewer(this.SimChat);
  460. remoteClient.OnRequestWearables += new GenericCall(this.InformClientOfNeighbours);
  461. remoteClient.OnAddPrim += new GenericCall4(this.AddNewPrim);
  462. remoteClient.OnUpdatePrimPosition += new UpdatePrimVector(this.UpdatePrimPosition);
  463. remoteClient.OnRequestMapBlocks += new RequestMapBlocks(this.RequestMapBlocks);
  464. remoteClient.OnTeleportLocationRequest += new TeleportLocationRequest(this.RequestTeleportLocation);
  465. /* remoteClient.OnParcelPropertiesRequest += new ParcelPropertiesRequest(parcelManager.handleParcelPropertiesRequest);
  466. remoteClient.OnParcelDivideRequest += new ParcelDivideRequest(parcelManager.handleParcelDivideRequest);
  467. remoteClient.OnParcelJoinRequest += new ParcelJoinRequest(parcelManager.handleParcelJoinRequest);
  468. remoteClient.OnParcelPropertiesUpdateRequest += new ParcelPropertiesUpdateRequest(parcelManager.handleParcelPropertiesUpdateRequest);
  469. remoteClient.OnEstateOwnerMessage += new EstateOwnerMessageRequest(estateManager.handleEstateOwnerMessage);
  470. */
  471. Avatar newAvatar = null;
  472. try
  473. {
  474. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent");
  475. newAvatar = new Avatar(remoteClient, this, m_clientThreads, this.m_regInfo);
  476. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs:AddViewerAgent() - Adding new avatar to world");
  477. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs:AddViewerAgent() - Starting RegionHandshake ");
  478. //newAvatar.SendRegionHandshake();
  479. this.estateManager.sendRegionHandshake(remoteClient);
  480. PhysicsVector pVec = new PhysicsVector(newAvatar.Pos.X, newAvatar.Pos.Y, newAvatar.Pos.Z);
  481. lock (this.m_syncRoot)
  482. {
  483. newAvatar.PhysActor = this.phyScene.AddAvatar(pVec);
  484. }
  485. lock (Entities)
  486. {
  487. if (!Entities.ContainsKey(agentID))
  488. {
  489. this.Entities.Add(agentID, newAvatar);
  490. }
  491. else
  492. {
  493. Entities[agentID] = newAvatar;
  494. }
  495. }
  496. lock (Avatars)
  497. {
  498. if (Avatars.ContainsKey(agentID))
  499. {
  500. Avatars[agentID] = newAvatar;
  501. }
  502. else
  503. {
  504. this.Avatars.Add(agentID, newAvatar);
  505. }
  506. }
  507. }
  508. catch (Exception e)
  509. {
  510. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: AddViewerAgent() - Failed with exception " + e.ToString());
  511. }
  512. return;
  513. }
  514. /// <summary>
  515. ///
  516. /// </summary>
  517. /// <param name="agentID"></param>
  518. public override void RemoveAvatar(LLUUID agentID)
  519. {
  520. return;
  521. }
  522. #endregion
  523. #region Request Avatars List Methods
  524. //The idea is to have a group of method that return a list of avatars meeting some requirement
  525. // ie it could be all Avatars within a certain range of the calling prim/avatar.
  526. /// <summary>
  527. /// Request a List of all Avatars in this World
  528. /// </summary>
  529. /// <returns></returns>
  530. public List<Avatar> RequestAvatarList()
  531. {
  532. List<Avatar> result = new List<Avatar>();
  533. foreach (Avatar avatar in Avatars.Values)
  534. {
  535. result.Add(avatar);
  536. }
  537. return result;
  538. }
  539. /// <summary>
  540. /// Request a filtered list of Avatars in this World
  541. /// </summary>
  542. /// <returns></returns>
  543. public List<Avatar> RequestAvatarList(FilterAvatarList filter)
  544. {
  545. List<Avatar> result = new List<Avatar>();
  546. foreach (Avatar avatar in Avatars.Values)
  547. {
  548. if (filter(avatar))
  549. {
  550. result.Add(avatar);
  551. }
  552. }
  553. return result;
  554. }
  555. /// <summary>
  556. /// Request a Avatar by UUID
  557. /// </summary>
  558. /// <param name="avatarID"></param>
  559. /// <returns></returns>
  560. public Avatar RequestAvatar(LLUUID avatarID)
  561. {
  562. if (this.Avatars.ContainsKey(avatarID))
  563. {
  564. return Avatars[avatarID];
  565. }
  566. return null;
  567. }
  568. #endregion
  569. #region ShutDown
  570. /// <summary>
  571. /// Tidy before shutdown
  572. /// </summary>
  573. public override void Close()
  574. {
  575. try
  576. {
  577. this.localStorage.ShutDown();
  578. }
  579. catch (Exception e)
  580. {
  581. OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Close() - Failed with exception " + e.ToString());
  582. }
  583. }
  584. #endregion
  585. #region RegionCommsHost
  586. /// <summary>
  587. ///
  588. /// </summary>
  589. public void RegisterRegionWithComms()
  590. {
  591. this.regionCommsHost = this.commsManager.GridServer.RegisterRegion(this.m_regInfo);
  592. if (this.regionCommsHost != null)
  593. {
  594. this.regionCommsHost.OnExpectUser += new ExpectUserDelegate(this.NewUserConnection);
  595. this.regionCommsHost.OnAvatarCrossingIntoRegion += new AgentCrossing(this.AgentCrossing);
  596. }
  597. }
  598. /// <summary>
  599. ///
  600. /// </summary>
  601. /// <param name="regionHandle"></param>
  602. /// <param name="agent"></param>
  603. public void NewUserConnection(ulong regionHandle, AgentCircuitData agent)
  604. {
  605. // Console.WriteLine("World.cs - add new user connection");
  606. //should just check that its meant for this region
  607. if (regionHandle == this.m_regInfo.RegionHandle)
  608. {
  609. this.authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
  610. }
  611. }
  612. public void AgentCrossing(ulong regionHandle, libsecondlife.LLUUID agentID, libsecondlife.LLVector3 position)
  613. {
  614. if (regionHandle == this.m_regInfo.RegionHandle)
  615. {
  616. if (this.Avatars.ContainsKey(agentID))
  617. {
  618. this.Avatars[agentID].UpGradeAvatar(position);
  619. }
  620. }
  621. }
  622. /// <summary>
  623. ///
  624. /// </summary>
  625. protected void InformClientOfNeighbours(IClientAPI remoteClient)
  626. {
  627. // Console.WriteLine("informing client of neighbouring regions");
  628. List<RegionInfo> neighbours = this.commsManager.GridServer.RequestNeighbours(this.m_regInfo);
  629. //Console.WriteLine("we have " + neighbours.Count + " neighbouring regions");
  630. if (neighbours != null)
  631. {
  632. for (int i = 0; i < neighbours.Count; i++)
  633. {
  634. // Console.WriteLine("sending neighbours data");
  635. AgentCircuitData agent = remoteClient.RequestClientInfo();
  636. agent.BaseFolder = LLUUID.Zero;
  637. agent.InventoryFolder = LLUUID.Zero;
  638. agent.startpos = new LLVector3(128, 128, 70);
  639. agent.child = true;
  640. this.commsManager.InterRegion.InformNeighbourOfChildAgent(neighbours[i].RegionHandle, agent);
  641. remoteClient.InformClientOfNeighbour(neighbours[i].RegionHandle, System.Net.IPAddress.Parse(neighbours[i].IPListenAddr), (ushort)neighbours[i].IPListenPort);
  642. }
  643. }
  644. }
  645. /// <summary>
  646. ///
  647. /// </summary>
  648. /// <param name="regionHandle"></param>
  649. /// <returns></returns>
  650. public RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle)
  651. {
  652. return this.commsManager.GridServer.RequestNeighbourInfo(regionHandle);
  653. }
  654. /// <summary>
  655. ///
  656. /// </summary>
  657. /// <param name="minX"></param>
  658. /// <param name="minY"></param>
  659. /// <param name="maxX"></param>
  660. /// <param name="maxY"></param>
  661. public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY)
  662. {
  663. List<MapBlockData> mapBlocks;
  664. mapBlocks = this.commsManager.GridServer.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
  665. remoteClient.SendMapBlock(mapBlocks);
  666. }
  667. /// <summary>
  668. ///
  669. /// </summary>
  670. /// <param name="remoteClient"></param>
  671. /// <param name="RegionHandle"></param>
  672. /// <param name="position"></param>
  673. /// <param name="lookAt"></param>
  674. /// <param name="flags"></param>
  675. public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, LLVector3 lookAt, uint flags)
  676. {
  677. if (regionHandle == this.m_regionHandle)
  678. {
  679. if (this.Avatars.ContainsKey(remoteClient.AgentId))
  680. {
  681. remoteClient.SendTeleportLocationStart();
  682. remoteClient.SendLocalTeleport(position, lookAt, flags);
  683. this.Avatars[remoteClient.AgentId].Teleport(position);
  684. }
  685. }
  686. else
  687. {
  688. remoteClient.SendTeleportCancel();
  689. }
  690. }
  691. /// <summary>
  692. ///
  693. /// </summary>
  694. /// <param name="regionhandle"></param>
  695. /// <param name="agentID"></param>
  696. /// <param name="position"></param>
  697. public void InformNeighbourOfCrossing(ulong regionhandle, LLUUID agentID, LLVector3 position)
  698. {
  699. this.commsManager.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position);
  700. }
  701. #endregion
  702. /// <summary>
  703. ///
  704. /// </summary>
  705. /// <param name="px"></param>
  706. /// <param name="py"></param>
  707. /// <param name="RemoteClient"></param>
  708. public override void SendLayerData(int px, int py, IClientAPI RemoteClient)
  709. {
  710. RemoteClient.SendLayerData( Terrain.getHeights1D() );
  711. }
  712. }
  713. }