LandObject.cs 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397
  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 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.Reflection;
  30. using log4net;
  31. using OpenMetaverse;
  32. using OpenSim.Framework;
  33. using OpenSim.Region.Framework.Interfaces;
  34. using OpenSim.Region.Framework.Scenes;
  35. using RegionFlags = OpenMetaverse.RegionFlags;
  36. namespace OpenSim.Region.CoreModules.World.Land
  37. {
  38. /// <summary>
  39. /// Keeps track of a specific piece of land's information
  40. /// </summary>
  41. public class LandObject : ILandObject
  42. {
  43. #region Member Variables
  44. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  45. private static readonly string LogHeader = "[LAND OBJECT]";
  46. private readonly int landUnit = 4;
  47. private int m_lastSeqId = 0;
  48. private int m_expiryCounter = 0;
  49. protected Scene m_scene;
  50. protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
  51. protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
  52. protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
  53. protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
  54. private bool[,] m_landBitmap;
  55. public bool[,] LandBitmap
  56. {
  57. get { return m_landBitmap; }
  58. set { m_landBitmap = value; }
  59. }
  60. #endregion
  61. public int GetPrimsFree()
  62. {
  63. m_scene.EventManager.TriggerParcelPrimCountUpdate();
  64. int free = GetSimulatorMaxPrimCount() - LandData.SimwidePrims;
  65. return free;
  66. }
  67. protected LandData m_landData;
  68. public LandData LandData
  69. {
  70. get { return m_landData; }
  71. set { m_landData = value; }
  72. }
  73. public IPrimCounts PrimCounts { get; set; }
  74. public UUID RegionUUID
  75. {
  76. get { return m_scene.RegionInfo.RegionID; }
  77. }
  78. public Vector3 StartPoint
  79. {
  80. get
  81. {
  82. for (int y = 0; y < LandBitmap.GetLength(1); y++)
  83. {
  84. for (int x = 0; x < LandBitmap.GetLength(0); x++)
  85. {
  86. if (LandBitmap[x, y])
  87. return new Vector3(x * landUnit, y * landUnit, 0);
  88. }
  89. }
  90. m_log.ErrorFormat("{0} StartPoint. No start point found. bitmapSize=<{1},{2}>",
  91. LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
  92. return new Vector3(-1, -1, -1);
  93. }
  94. }
  95. public Vector3 EndPoint
  96. {
  97. get
  98. {
  99. for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--)
  100. {
  101. for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--)
  102. {
  103. if (LandBitmap[x, y])
  104. {
  105. return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0);
  106. }
  107. }
  108. }
  109. m_log.ErrorFormat("{0} EndPoint. No end point found. bitmapSize=<{1},{2}>",
  110. LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
  111. return new Vector3(-1, -1, -1);
  112. }
  113. }
  114. #region Constructors
  115. public LandObject(LandData landData, Scene scene)
  116. {
  117. LandData = landData.Copy();
  118. m_scene = scene;
  119. }
  120. public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
  121. {
  122. m_scene = scene;
  123. if (m_scene == null)
  124. LandBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit];
  125. else
  126. LandBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
  127. LandData = new LandData();
  128. LandData.OwnerID = owner_id;
  129. if (is_group_owned)
  130. LandData.GroupID = owner_id;
  131. else
  132. LandData.GroupID = UUID.Zero;
  133. LandData.IsGroupOwned = is_group_owned;
  134. m_scene.EventManager.OnFrame += OnFrame;
  135. }
  136. #endregion
  137. #region Member Functions
  138. #region General Functions
  139. /// <summary>
  140. /// Checks to see if this land object contains a point
  141. /// </summary>
  142. /// <param name="x"></param>
  143. /// <param name="y"></param>
  144. /// <returns>Returns true if the piece of land contains the specified point</returns>
  145. public bool ContainsPoint(int x, int y)
  146. {
  147. if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY)
  148. {
  149. return LandBitmap[x / landUnit, y / landUnit];
  150. }
  151. else
  152. {
  153. return false;
  154. }
  155. }
  156. public ILandObject Copy()
  157. {
  158. ILandObject newLand = new LandObject(LandData, m_scene);
  159. newLand.LandBitmap = (bool[,]) (LandBitmap.Clone());
  160. return newLand;
  161. }
  162. static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount;
  163. static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount;
  164. public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
  165. {
  166. overrideParcelMaxPrimCount = overrideDel;
  167. }
  168. public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
  169. {
  170. overrideSimulatorMaxPrimCount = overrideDel;
  171. }
  172. public int GetParcelMaxPrimCount()
  173. {
  174. if (overrideParcelMaxPrimCount != null)
  175. {
  176. return overrideParcelMaxPrimCount(this);
  177. }
  178. else
  179. {
  180. // Normal Calculations
  181. int parcelMax = (int)( (long)LandData.Area
  182. * (long)m_scene.RegionInfo.ObjectCapacity
  183. * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus
  184. / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) );
  185. //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
  186. return parcelMax;
  187. }
  188. }
  189. private int GetParcelBasePrimCount()
  190. {
  191. if (overrideParcelMaxPrimCount != null)
  192. {
  193. return overrideParcelMaxPrimCount(this);
  194. }
  195. else
  196. {
  197. // Normal Calculations
  198. int parcelMax = (int)((long)LandData.Area
  199. * (long)m_scene.RegionInfo.ObjectCapacity
  200. / 65536L);
  201. return parcelMax;
  202. }
  203. }
  204. public int GetSimulatorMaxPrimCount()
  205. {
  206. if (overrideSimulatorMaxPrimCount != null)
  207. {
  208. return overrideSimulatorMaxPrimCount(this);
  209. }
  210. else
  211. {
  212. //Normal Calculations
  213. int simMax = (int)( (long)LandData.SimwideArea
  214. * (long)m_scene.RegionInfo.ObjectCapacity
  215. / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) );
  216. // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax);
  217. return simMax;
  218. }
  219. }
  220. #endregion
  221. #region Packet Request Handling
  222. public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
  223. {
  224. if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
  225. return;
  226. IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
  227. // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
  228. uint regionFlags = (uint)(RegionFlags.PublicAllowed
  229. | RegionFlags.AllowDirectTeleport
  230. | RegionFlags.AllowParcelChanges
  231. | RegionFlags.AllowVoice );
  232. if (estateModule != null)
  233. regionFlags = estateModule.GetRegionFlags();
  234. int seq_id;
  235. if (snap_selection && (sequence_id == 0))
  236. {
  237. seq_id = m_lastSeqId;
  238. }
  239. else
  240. {
  241. seq_id = sequence_id;
  242. m_lastSeqId = seq_id;
  243. }
  244. remote_client.SendLandProperties(seq_id,
  245. snap_selection, request_result, this,
  246. (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
  247. GetParcelBasePrimCount(),
  248. GetSimulatorMaxPrimCount(), regionFlags);
  249. }
  250. public bool UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client, out bool snap_selection, out bool needOverlay)
  251. {
  252. //Needs later group support
  253. snap_selection = false;
  254. needOverlay = false;
  255. LandData newData = LandData.Copy();
  256. uint allowedDelta = 0;
  257. // These two are always blocked as no client can set them anyway
  258. // ParcelFlags.ForSaleObjects
  259. // ParcelFlags.LindenHome
  260. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, false))
  261. {
  262. allowedDelta |= (uint)(ParcelFlags.AllowLandmark |
  263. ParcelFlags.AllowTerraform |
  264. ParcelFlags.AllowDamage |
  265. ParcelFlags.CreateObjects |
  266. ParcelFlags.RestrictPushObject |
  267. ParcelFlags.AllowOtherScripts |
  268. ParcelFlags.AllowGroupScripts |
  269. ParcelFlags.CreateGroupObjects |
  270. ParcelFlags.AllowAPrimitiveEntry |
  271. ParcelFlags.AllowGroupObjectEntry |
  272. ParcelFlags.AllowFly);
  273. newData.SeeAVs = args.SeeAVs;
  274. newData.AnyAVSounds = args.AnyAVSounds;
  275. newData.GroupAVSounds = args.GroupAVSounds;
  276. }
  277. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale, true))
  278. {
  279. if (args.AuthBuyerID != newData.AuthBuyerID ||
  280. args.SalePrice != newData.SalePrice)
  281. {
  282. snap_selection = true;
  283. }
  284. newData.AuthBuyerID = args.AuthBuyerID;
  285. newData.SalePrice = args.SalePrice;
  286. if (!LandData.IsGroupOwned)
  287. {
  288. newData.GroupID = args.GroupID;
  289. allowedDelta |= (uint)(ParcelFlags.AllowDeedToGroup |
  290. ParcelFlags.ContributeWithDeed |
  291. ParcelFlags.SellParcelObjects);
  292. }
  293. allowedDelta |= (uint)ParcelFlags.ForSale;
  294. }
  295. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces, false))
  296. {
  297. newData.Category = args.Category;
  298. allowedDelta |= (uint)(ParcelFlags.ShowDirectory |
  299. ParcelFlags.AllowPublish |
  300. ParcelFlags.MaturePublish) | (uint)(1 << 23);
  301. }
  302. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity, false))
  303. {
  304. newData.Description = args.Desc;
  305. newData.Name = args.Name;
  306. newData.SnapshotID = args.SnapshotID;
  307. }
  308. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint, false))
  309. {
  310. newData.LandingType = args.LandingType;
  311. newData.UserLocation = args.UserLocation;
  312. newData.UserLookAt = args.UserLookAt;
  313. }
  314. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia, false))
  315. {
  316. newData.MediaAutoScale = args.MediaAutoScale;
  317. newData.MediaID = args.MediaID;
  318. newData.MediaURL = args.MediaURL;
  319. newData.MusicURL = args.MusicURL;
  320. newData.MediaType = args.MediaType;
  321. newData.MediaDescription = args.MediaDescription;
  322. newData.MediaWidth = args.MediaWidth;
  323. newData.MediaHeight = args.MediaHeight;
  324. newData.MediaLoop = args.MediaLoop;
  325. newData.ObscureMusic = args.ObscureMusic;
  326. newData.ObscureMedia = args.ObscureMedia;
  327. allowedDelta |= (uint)(ParcelFlags.SoundLocal |
  328. ParcelFlags.UrlWebPage |
  329. ParcelFlags.UrlRawHtml |
  330. ParcelFlags.AllowVoiceChat |
  331. ParcelFlags.UseEstateVoiceChan);
  332. }
  333. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false))
  334. {
  335. newData.PassHours = args.PassHours;
  336. newData.PassPrice = args.PassPrice;
  337. allowedDelta |= (uint)ParcelFlags.UsePassList;
  338. }
  339. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed, false))
  340. {
  341. allowedDelta |= (uint)(ParcelFlags.UseAccessGroup |
  342. ParcelFlags.UseAccessList);
  343. }
  344. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned, false))
  345. {
  346. allowedDelta |= (uint)(ParcelFlags.UseBanList |
  347. ParcelFlags.DenyAnonymous |
  348. ParcelFlags.DenyAgeUnverified);
  349. }
  350. if (allowedDelta != (uint)ParcelFlags.None)
  351. {
  352. uint preserve = LandData.Flags & ~allowedDelta;
  353. newData.Flags = preserve | (args.ParcelFlags & allowedDelta);
  354. uint curdelta = LandData.Flags ^ newData.Flags;
  355. curdelta &= (uint)(ParcelFlags.SoundLocal);
  356. if(curdelta != 0 || newData.SeeAVs != LandData.SeeAVs)
  357. needOverlay = true;
  358. m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
  359. return true;
  360. }
  361. return false;
  362. }
  363. public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
  364. {
  365. LandData newData = LandData.Copy();
  366. newData.OwnerID = avatarID;
  367. newData.GroupID = groupID;
  368. newData.IsGroupOwned = groupOwned;
  369. //newData.auctionID = AuctionID;
  370. newData.ClaimDate = Util.UnixTimeSinceEpoch();
  371. newData.ClaimPrice = claimprice;
  372. newData.SalePrice = 0;
  373. newData.AuthBuyerID = UUID.Zero;
  374. newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
  375. bool sellObjects = (LandData.Flags & (uint)(ParcelFlags.SellParcelObjects)) != 0
  376. && !LandData.IsGroupOwned && !groupOwned;
  377. UUID previousOwner = LandData.OwnerID;
  378. m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
  379. // m_scene.EventManager.TriggerParcelPrimCountUpdate();
  380. SendLandUpdateToAvatarsOverMe(true);
  381. if (sellObjects) SellLandObjects(previousOwner);
  382. }
  383. public void DeedToGroup(UUID groupID)
  384. {
  385. LandData newData = LandData.Copy();
  386. newData.OwnerID = groupID;
  387. newData.GroupID = groupID;
  388. newData.IsGroupOwned = true;
  389. // Reset show in directory flag on deed
  390. newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
  391. m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
  392. m_scene.EventManager.TriggerParcelPrimCountUpdate();
  393. SendLandUpdateToAvatarsOverMe(true);
  394. }
  395. public bool IsEitherBannedOrRestricted(UUID avatar)
  396. {
  397. if (IsBannedFromLand(avatar))
  398. {
  399. return true;
  400. }
  401. else if (IsRestrictedFromLand(avatar))
  402. {
  403. return true;
  404. }
  405. return false;
  406. }
  407. public bool CanBeOnThisLand(UUID avatar, float posHeight)
  408. {
  409. if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar))
  410. {
  411. return false;
  412. }
  413. else if (IsRestrictedFromLand(avatar))
  414. {
  415. return false;
  416. }
  417. return true;
  418. }
  419. public bool HasGroupAccess(UUID avatar)
  420. {
  421. if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
  422. {
  423. ScenePresence sp;
  424. if (!m_scene.TryGetScenePresence(avatar, out sp))
  425. {
  426. bool isMember;
  427. if (m_groupMemberCache.TryGetValue(avatar, out isMember))
  428. {
  429. m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout);
  430. return isMember;
  431. }
  432. IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
  433. if (groupsModule == null)
  434. return false;
  435. GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar);
  436. if (membership == null || membership.Length == 0)
  437. {
  438. m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
  439. return false;
  440. }
  441. foreach (GroupMembershipData d in membership)
  442. {
  443. if (d.GroupID == LandData.GroupID)
  444. {
  445. m_groupMemberCache.Add(avatar, true, m_groupMemberCacheTimeout);
  446. return true;
  447. }
  448. }
  449. m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
  450. return false;
  451. }
  452. return sp.ControllingClient.IsGroupMember(LandData.GroupID);
  453. }
  454. return false;
  455. }
  456. public bool IsBannedFromLand(UUID avatar)
  457. {
  458. ExpireAccessList();
  459. if (m_scene.Permissions.IsAdministrator(avatar))
  460. return false;
  461. if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar))
  462. return false;
  463. if (avatar == LandData.OwnerID)
  464. return false;
  465. if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0)
  466. {
  467. if (LandData.ParcelAccessList.FindIndex(
  468. delegate(LandAccessEntry e)
  469. {
  470. if (e.AgentID == avatar && e.Flags == AccessList.Ban)
  471. return true;
  472. return false;
  473. }) != -1)
  474. {
  475. return true;
  476. }
  477. }
  478. return false;
  479. }
  480. public bool IsRestrictedFromLand(UUID avatar)
  481. {
  482. if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0)
  483. return false;
  484. if (m_scene.Permissions.IsAdministrator(avatar))
  485. return false;
  486. if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar))
  487. return false;
  488. if (avatar == LandData.OwnerID)
  489. return false;
  490. if (HasGroupAccess(avatar))
  491. return false;
  492. return !IsInLandAccessList(avatar);
  493. }
  494. public bool IsInLandAccessList(UUID avatar)
  495. {
  496. ExpireAccessList();
  497. if (LandData.ParcelAccessList.FindIndex(
  498. delegate(LandAccessEntry e)
  499. {
  500. if (e.AgentID == avatar && e.Flags == AccessList.Access)
  501. return true;
  502. return false;
  503. }) == -1)
  504. {
  505. return false;
  506. }
  507. return true;
  508. }
  509. public void SendLandUpdateToClient(IClientAPI remote_client)
  510. {
  511. SendLandProperties(0, false, 0, remote_client);
  512. }
  513. public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client)
  514. {
  515. m_scene.EventManager.TriggerParcelPrimCountUpdate();
  516. SendLandProperties(0, snap_selection, 0, remote_client);
  517. }
  518. public void SendLandUpdateToAvatarsOverMe()
  519. {
  520. SendLandUpdateToAvatarsOverMe(false);
  521. }
  522. public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
  523. {
  524. m_scene.EventManager.TriggerParcelPrimCountUpdate();
  525. m_scene.ForEachRootScenePresence(delegate(ScenePresence avatar)
  526. {
  527. ILandObject over = null;
  528. try
  529. {
  530. over =
  531. m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)),
  532. Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1)));
  533. }
  534. catch (Exception)
  535. {
  536. m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " +
  537. Math.Round(avatar.AbsolutePosition.Y));
  538. }
  539. if (over != null)
  540. {
  541. if (over.LandData.LocalID == LandData.LocalID)
  542. {
  543. if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) &&
  544. m_scene.RegionInfo.RegionSettings.AllowDamage)
  545. avatar.Invulnerable = false;
  546. else
  547. avatar.Invulnerable = true;
  548. SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
  549. avatar.currentParcelUUID = LandData.GlobalID;
  550. }
  551. }
  552. });
  553. }
  554. #endregion
  555. #region AccessList Functions
  556. public List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag)
  557. {
  558. ExpireAccessList();
  559. List<LandAccessEntry> list = new List<LandAccessEntry>();
  560. foreach (LandAccessEntry entry in LandData.ParcelAccessList)
  561. {
  562. if (entry.Flags == flag)
  563. list.Add(entry);
  564. }
  565. if (list.Count == 0)
  566. {
  567. LandAccessEntry e = new LandAccessEntry();
  568. e.AgentID = UUID.Zero;
  569. e.Flags = 0;
  570. e.Expires = 0;
  571. list.Add(e);
  572. }
  573. return list;
  574. }
  575. public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID,
  576. IClientAPI remote_client)
  577. {
  578. if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both)
  579. {
  580. List<LandAccessEntry> accessEntries = CreateAccessListArrayByFlag(AccessList.Access);
  581. remote_client.SendLandAccessListData(accessEntries,(uint) AccessList.Access,LandData.LocalID);
  582. }
  583. if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both)
  584. {
  585. List<LandAccessEntry> accessEntries = CreateAccessListArrayByFlag(AccessList.Ban);
  586. remote_client.SendLandAccessListData(accessEntries, (uint)AccessList.Ban, LandData.LocalID);
  587. }
  588. }
  589. public void UpdateAccessList(uint flags, UUID transactionID,
  590. int sequenceID, int sections,
  591. List<LandAccessEntry> entries,
  592. IClientAPI remote_client)
  593. {
  594. LandData newData = LandData.Copy();
  595. if ((!m_listTransactions.ContainsKey(flags)) ||
  596. m_listTransactions[flags] != transactionID)
  597. {
  598. m_listTransactions[flags] = transactionID;
  599. List<LandAccessEntry> toRemove =
  600. new List<LandAccessEntry>();
  601. foreach (LandAccessEntry entry in newData.ParcelAccessList)
  602. {
  603. if (entry.Flags == (AccessList)flags)
  604. toRemove.Add(entry);
  605. }
  606. foreach (LandAccessEntry entry in toRemove)
  607. {
  608. newData.ParcelAccessList.Remove(entry);
  609. }
  610. // Checked here because this will always be the first
  611. // and only packet in a transaction
  612. if (entries.Count == 1 && entries[0].AgentID == UUID.Zero)
  613. {
  614. m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
  615. return;
  616. }
  617. }
  618. foreach (LandAccessEntry entry in entries)
  619. {
  620. LandAccessEntry temp =
  621. new LandAccessEntry();
  622. temp.AgentID = entry.AgentID;
  623. temp.Expires = entry.Expires;
  624. temp.Flags = (AccessList)flags;
  625. newData.ParcelAccessList.Add(temp);
  626. }
  627. m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
  628. }
  629. #endregion
  630. #region Update Functions
  631. public void UpdateLandBitmapByteArray()
  632. {
  633. LandData.Bitmap = ConvertLandBitmapToBytes();
  634. }
  635. /// <summary>
  636. /// Update all settings in land such as area, bitmap byte array, etc
  637. /// </summary>
  638. public void ForceUpdateLandInfo()
  639. {
  640. UpdateAABBAndAreaValues();
  641. UpdateLandBitmapByteArray();
  642. }
  643. public void SetLandBitmapFromByteArray()
  644. {
  645. LandBitmap = ConvertBytesToLandBitmap();
  646. }
  647. /// <summary>
  648. /// Updates the AABBMin and AABBMax values after area/shape modification of the land object
  649. /// </summary>
  650. private void UpdateAABBAndAreaValues()
  651. {
  652. int min_x = Int32.MaxValue;
  653. int min_y = Int32.MaxValue;
  654. int max_x = Int32.MinValue;
  655. int max_y = Int32.MinValue;
  656. int tempArea = 0;
  657. int x, y;
  658. for (x = 0; x < LandBitmap.GetLength(0); x++)
  659. {
  660. for (y = 0; y < LandBitmap.GetLength(1); y++)
  661. {
  662. if (LandBitmap[x, y] == true)
  663. {
  664. if (min_x > x)
  665. min_x = x;
  666. if (min_y > y)
  667. min_y = y;
  668. if (max_x < x)
  669. max_x = x;
  670. if (max_y < y)
  671. max_y = y;
  672. tempArea += landUnit * landUnit; //16sqm peice of land
  673. }
  674. }
  675. }
  676. int tx = min_x * landUnit;
  677. if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
  678. tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
  679. int htx;
  680. if (tx >= ((int)m_scene.RegionInfo.RegionSizeX))
  681. htx = (int)m_scene.RegionInfo.RegionSizeX - 1;
  682. else
  683. htx = tx;
  684. int ty = min_y * landUnit;
  685. int hty;
  686. if (ty >= ((int)m_scene.RegionInfo.RegionSizeY))
  687. hty = (int)m_scene.RegionInfo.RegionSizeY - 1;
  688. else
  689. hty = ty;
  690. LandData.AABBMin =
  691. new Vector3(
  692. (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0);
  693. max_x++;
  694. tx = max_x * landUnit;
  695. if (tx >= ((int)m_scene.RegionInfo.RegionSizeX))
  696. htx = (int)m_scene.RegionInfo.RegionSizeX - 1;
  697. else
  698. htx = tx;
  699. max_y++;
  700. ty = max_y * 4;
  701. if (ty >= ((int)m_scene.RegionInfo.RegionSizeY))
  702. hty = (int)m_scene.RegionInfo.RegionSizeY - 1;
  703. else
  704. hty = ty;
  705. LandData.AABBMax
  706. = new Vector3(
  707. (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0);
  708. LandData.Area = tempArea;
  709. }
  710. #endregion
  711. #region Land Bitmap Functions
  712. /// <summary>
  713. /// Sets the land's bitmap manually
  714. /// </summary>
  715. /// <param name="bitmap">block representing where this land is on a map mapped in a 4x4 meter grid</param>
  716. public void SetLandBitmap(bool[,] bitmap)
  717. {
  718. LandBitmap = bitmap;
  719. ForceUpdateLandInfo();
  720. }
  721. /// <summary>
  722. /// Gets the land's bitmap manually
  723. /// </summary>
  724. /// <returns></returns>
  725. public bool[,] GetLandBitmap()
  726. {
  727. return LandBitmap;
  728. }
  729. public bool[,] BasicFullRegionLandBitmap()
  730. {
  731. return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY);
  732. }
  733. public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
  734. {
  735. // Empty bitmap for the whole region
  736. bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
  737. tempBitmap.Initialize();
  738. // Fill the bitmap square area specified by state and end
  739. tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
  740. // m_log.DebugFormat("{0} GetSquareLandBitmap. tempBitmapSize=<{1},{2}>",
  741. // LogHeader, tempBitmap.GetLength(0), tempBitmap.GetLength(1));
  742. return tempBitmap;
  743. }
  744. /// <summary>
  745. /// Change a land bitmap at within a square and set those points to a specific value
  746. /// </summary>
  747. /// <param name="land_bitmap"></param>
  748. /// <param name="start_x"></param>
  749. /// <param name="start_y"></param>
  750. /// <param name="end_x"></param>
  751. /// <param name="end_y"></param>
  752. /// <param name="set_value"></param>
  753. /// <returns></returns>
  754. public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
  755. bool set_value)
  756. {
  757. int x, y;
  758. for (y = 0; y < land_bitmap.GetLength(1); y++)
  759. {
  760. for (x = 0; x < land_bitmap.GetLength(0); x++)
  761. {
  762. if (x >= start_x / landUnit && x < end_x / landUnit
  763. && y >= start_y / landUnit && y < end_y / landUnit)
  764. {
  765. land_bitmap[x, y] = set_value;
  766. }
  767. }
  768. }
  769. // m_log.DebugFormat("{0} ModifyLandBitmapSquare. startXY=<{1},{2}>, endXY=<{3},{4}>, val={5}, landBitmapSize=<{6},{7}>",
  770. // LogHeader, start_x, start_y, end_x, end_y, set_value, land_bitmap.GetLength(0), land_bitmap.GetLength(1));
  771. return land_bitmap;
  772. }
  773. /// <summary>
  774. /// Join the true values of 2 bitmaps together
  775. /// </summary>
  776. /// <param name="bitmap_base"></param>
  777. /// <param name="bitmap_add"></param>
  778. /// <returns></returns>
  779. public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
  780. {
  781. if (bitmap_base.GetLength(0) != bitmap_add.GetLength(0)
  782. || bitmap_base.GetLength(1) != bitmap_add.GetLength(1)
  783. || bitmap_add.Rank != 2
  784. || bitmap_base.Rank != 2)
  785. {
  786. throw new Exception(
  787. String.Format("{0} MergeLandBitmaps. merging maps not same size. baseSizeXY=<{1},{2}>, addSizeXY=<{3},{4}>",
  788. LogHeader, bitmap_base.GetLength(0), bitmap_base.GetLength(1), bitmap_add.GetLength(0), bitmap_add.GetLength(1))
  789. );
  790. }
  791. int x, y;
  792. for (y = 0; y < bitmap_base.GetLength(1); y++)
  793. {
  794. for (x = 0; x < bitmap_add.GetLength(0); x++)
  795. {
  796. if (bitmap_add[x, y])
  797. {
  798. bitmap_base[x, y] = true;
  799. }
  800. }
  801. }
  802. return bitmap_base;
  803. }
  804. /// <summary>
  805. /// Converts the land bitmap to a packet friendly byte array
  806. /// </summary>
  807. /// <returns></returns>
  808. private byte[] ConvertLandBitmapToBytes()
  809. {
  810. byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
  811. int tempByte = 0;
  812. int i, byteNum = 0;
  813. int mask = 1;
  814. i = 0;
  815. for (int y = 0; y < LandBitmap.GetLength(1); y++)
  816. {
  817. for (int x = 0; x < LandBitmap.GetLength(0); x++)
  818. {
  819. if (LandBitmap[x, y])
  820. tempByte |= mask;
  821. mask = mask << 1;
  822. if (mask == 0x100)
  823. {
  824. mask = 1;
  825. tempConvertArr[byteNum++] = (byte)tempByte;
  826. tempByte = 0;
  827. }
  828. }
  829. }
  830. if(tempByte != 0 && byteNum < 512)
  831. tempConvertArr[byteNum] = (byte)tempByte;
  832. /*
  833. tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
  834. if (i % 8 == 0)
  835. {
  836. tempConvertArr[byteNum] = tempByte;
  837. tempByte = (byte) 0;
  838. i = 0;
  839. byteNum++;
  840. }
  841. <<<<<<< HEAD
  842. }
  843. }
  844. // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>",
  845. // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
  846. =======
  847. */
  848. return tempConvertArr;
  849. }
  850. private bool[,] ConvertBytesToLandBitmap()
  851. {
  852. bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit];
  853. tempConvertMap.Initialize();
  854. byte tempByte = 0;
  855. // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap.
  856. int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8);
  857. int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit);
  858. if (bitmapLen == 512)
  859. {
  860. // Legacy bitmap being passed in. Use the legacy region size
  861. // and only set the lower area of the larger region.
  862. xLen = (int)(Constants.RegionSize / landUnit);
  863. }
  864. // m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen);
  865. int x = 0, y = 0;
  866. for (int i = 0; i < bitmapLen; i++)
  867. {
  868. tempByte = LandData.Bitmap[i];
  869. for (int bitNum = 0; bitNum < 8; bitNum++)
  870. {
  871. bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
  872. try
  873. {
  874. tempConvertMap[x, y] = bit;
  875. }
  876. catch (Exception)
  877. {
  878. m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y);
  879. }
  880. x++;
  881. if (x >= xLen)
  882. {
  883. x = 0;
  884. y++;
  885. }
  886. }
  887. }
  888. return tempConvertMap;
  889. }
  890. #endregion
  891. #region Object Select and Object Owner Listing
  892. public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client)
  893. {
  894. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
  895. {
  896. List<uint> resultLocalIDs = new List<uint>();
  897. try
  898. {
  899. lock (primsOverMe)
  900. {
  901. foreach (SceneObjectGroup obj in primsOverMe)
  902. {
  903. if (obj.LocalId > 0)
  904. {
  905. if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID)
  906. {
  907. resultLocalIDs.Add(obj.LocalId);
  908. }
  909. else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero)
  910. {
  911. resultLocalIDs.Add(obj.LocalId);
  912. }
  913. else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
  914. obj.OwnerID != remote_client.AgentId)
  915. {
  916. resultLocalIDs.Add(obj.LocalId);
  917. }
  918. else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID))
  919. {
  920. resultLocalIDs.Add(obj.LocalId);
  921. }
  922. }
  923. }
  924. }
  925. } catch (InvalidOperationException)
  926. {
  927. m_log.Error("[LAND]: Unable to force select the parcel objects. Arr.");
  928. }
  929. remote_client.SendForceClientSelectObjects(resultLocalIDs);
  930. }
  931. }
  932. /// <summary>
  933. /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes
  934. /// aggreagete details such as the number of prims.
  935. ///
  936. /// </summary>
  937. /// <param name="remote_client">
  938. /// A <see cref="IClientAPI"/>
  939. /// </param>
  940. public void SendLandObjectOwners(IClientAPI remote_client)
  941. {
  942. if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
  943. {
  944. Dictionary<UUID, int> primCount = new Dictionary<UUID, int>();
  945. List<UUID> groups = new List<UUID>();
  946. lock (primsOverMe)
  947. {
  948. // m_log.DebugFormat(
  949. // "[LAND OBJECT]: Request for SendLandObjectOwners() from {0} with {1} known prims on region",
  950. // remote_client.Name, primsOverMe.Count);
  951. try
  952. {
  953. foreach (SceneObjectGroup obj in primsOverMe)
  954. {
  955. try
  956. {
  957. if (!primCount.ContainsKey(obj.OwnerID))
  958. {
  959. primCount.Add(obj.OwnerID, 0);
  960. }
  961. }
  962. catch (NullReferenceException)
  963. {
  964. m_log.Error("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel");
  965. }
  966. try
  967. {
  968. primCount[obj.OwnerID] += obj.PrimCount;
  969. }
  970. catch (KeyNotFoundException)
  971. {
  972. m_log.Error("[LAND]: Unable to match a prim with it's owner.");
  973. }
  974. if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID)))
  975. groups.Add(obj.OwnerID);
  976. }
  977. }
  978. catch (InvalidOperationException)
  979. {
  980. m_log.Error("[LAND]: Unable to Enumerate Land object arr.");
  981. }
  982. }
  983. remote_client.SendLandObjectOwners(LandData, groups, primCount);
  984. }
  985. }
  986. public Dictionary<UUID, int> GetLandObjectOwners()
  987. {
  988. Dictionary<UUID, int> ownersAndCount = new Dictionary<UUID, int>();
  989. lock (primsOverMe)
  990. {
  991. try
  992. {
  993. foreach (SceneObjectGroup obj in primsOverMe)
  994. {
  995. if (!ownersAndCount.ContainsKey(obj.OwnerID))
  996. {
  997. ownersAndCount.Add(obj.OwnerID, 0);
  998. }
  999. ownersAndCount[obj.OwnerID] += obj.PrimCount;
  1000. }
  1001. }
  1002. catch (InvalidOperationException)
  1003. {
  1004. m_log.Error("[LAND]: Unable to enumerate land owners. arr.");
  1005. }
  1006. }
  1007. return ownersAndCount;
  1008. }
  1009. #endregion
  1010. #region Object Sales
  1011. public void SellLandObjects(UUID previousOwner)
  1012. {
  1013. // m_log.DebugFormat(
  1014. // "[LAND OBJECT]: Request to sell objects in {0} from {1}", LandData.Name, previousOwner);
  1015. if (LandData.IsGroupOwned)
  1016. return;
  1017. IBuySellModule m_BuySellModule = m_scene.RequestModuleInterface<IBuySellModule>();
  1018. if (m_BuySellModule == null)
  1019. {
  1020. m_log.Error("[LAND OBJECT]: BuySellModule not found");
  1021. return;
  1022. }
  1023. ScenePresence sp;
  1024. if (!m_scene.TryGetScenePresence(LandData.OwnerID, out sp))
  1025. {
  1026. m_log.Error("[LAND OBJECT]: New owner is not present in scene");
  1027. return;
  1028. }
  1029. lock (primsOverMe)
  1030. {
  1031. foreach (SceneObjectGroup obj in primsOverMe)
  1032. {
  1033. if (obj.OwnerID == previousOwner && obj.GroupID == UUID.Zero &&
  1034. (obj.GetEffectivePermissions() & (uint)(OpenSim.Framework.PermissionMask.Transfer)) != 0)
  1035. m_BuySellModule.BuyObject(sp.ControllingClient, UUID.Zero, obj.LocalId, 1, 0);
  1036. }
  1037. }
  1038. }
  1039. #endregion
  1040. #region Object Returning
  1041. public void ReturnObject(SceneObjectGroup obj)
  1042. {
  1043. SceneObjectGroup[] objs = new SceneObjectGroup[1];
  1044. objs[0] = obj;
  1045. m_scene.returnObjects(objs, obj.OwnerID);
  1046. }
  1047. public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client)
  1048. {
  1049. // m_log.DebugFormat(
  1050. // "[LAND OBJECT]: Request to return objects in {0} from {1}", LandData.Name, remote_client.Name);
  1051. Dictionary<UUID,List<SceneObjectGroup>> returns = new Dictionary<UUID,List<SceneObjectGroup>>();
  1052. lock (primsOverMe)
  1053. {
  1054. if (type == (uint)ObjectReturnType.Owner)
  1055. {
  1056. foreach (SceneObjectGroup obj in primsOverMe)
  1057. {
  1058. if (obj.OwnerID == LandData.OwnerID)
  1059. {
  1060. if (!returns.ContainsKey(obj.OwnerID))
  1061. returns[obj.OwnerID] =
  1062. new List<SceneObjectGroup>();
  1063. returns[obj.OwnerID].Add(obj);
  1064. }
  1065. }
  1066. }
  1067. else if (type == (uint)ObjectReturnType.Group && LandData.GroupID != UUID.Zero)
  1068. {
  1069. foreach (SceneObjectGroup obj in primsOverMe)
  1070. {
  1071. if (obj.GroupID == LandData.GroupID)
  1072. {
  1073. if (!returns.ContainsKey(obj.OwnerID))
  1074. returns[obj.OwnerID] =
  1075. new List<SceneObjectGroup>();
  1076. returns[obj.OwnerID].Add(obj);
  1077. }
  1078. }
  1079. }
  1080. else if (type == (uint)ObjectReturnType.Other)
  1081. {
  1082. foreach (SceneObjectGroup obj in primsOverMe)
  1083. {
  1084. if (obj.OwnerID != LandData.OwnerID &&
  1085. (obj.GroupID != LandData.GroupID ||
  1086. LandData.GroupID == UUID.Zero))
  1087. {
  1088. if (!returns.ContainsKey(obj.OwnerID))
  1089. returns[obj.OwnerID] =
  1090. new List<SceneObjectGroup>();
  1091. returns[obj.OwnerID].Add(obj);
  1092. }
  1093. }
  1094. }
  1095. else if (type == (uint)ObjectReturnType.List)
  1096. {
  1097. List<UUID> ownerlist = new List<UUID>(owners);
  1098. foreach (SceneObjectGroup obj in primsOverMe)
  1099. {
  1100. if (ownerlist.Contains(obj.OwnerID))
  1101. {
  1102. if (!returns.ContainsKey(obj.OwnerID))
  1103. returns[obj.OwnerID] =
  1104. new List<SceneObjectGroup>();
  1105. returns[obj.OwnerID].Add(obj);
  1106. }
  1107. }
  1108. }
  1109. }
  1110. foreach (List<SceneObjectGroup> ol in returns.Values)
  1111. {
  1112. if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol))
  1113. m_scene.returnObjects(ol.ToArray(), remote_client.AgentId);
  1114. }
  1115. }
  1116. #endregion
  1117. #region Object Adding/Removing from Parcel
  1118. public void ResetOverMeRecord()
  1119. {
  1120. lock (primsOverMe)
  1121. primsOverMe.Clear();
  1122. }
  1123. public void AddPrimOverMe(SceneObjectGroup obj)
  1124. {
  1125. // m_log.DebugFormat("[LAND OBJECT]: Adding scene object {0} {1} over {2}", obj.Name, obj.LocalId, LandData.Name);
  1126. lock (primsOverMe)
  1127. primsOverMe.Add(obj);
  1128. }
  1129. public void RemovePrimFromOverMe(SceneObjectGroup obj)
  1130. {
  1131. // m_log.DebugFormat("[LAND OBJECT]: Removing scene object {0} {1} from over {2}", obj.Name, obj.LocalId, LandData.Name);
  1132. lock (primsOverMe)
  1133. primsOverMe.Remove(obj);
  1134. }
  1135. #endregion
  1136. /// <summary>
  1137. /// Set the media url for this land parcel
  1138. /// </summary>
  1139. /// <param name="url"></param>
  1140. public void SetMediaUrl(string url)
  1141. {
  1142. LandData.MediaURL = url;
  1143. m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData);
  1144. SendLandUpdateToAvatarsOverMe();
  1145. }
  1146. /// <summary>
  1147. /// Set the music url for this land parcel
  1148. /// </summary>
  1149. /// <param name="url"></param>
  1150. public void SetMusicUrl(string url)
  1151. {
  1152. LandData.MusicURL = url;
  1153. m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData);
  1154. SendLandUpdateToAvatarsOverMe();
  1155. }
  1156. /// <summary>
  1157. /// Get the music url for this land parcel
  1158. /// </summary>
  1159. /// <returns>The music url.</returns>
  1160. public string GetMusicUrl()
  1161. {
  1162. return LandData.MusicURL;
  1163. }
  1164. #endregion
  1165. private void OnFrame()
  1166. {
  1167. m_expiryCounter++;
  1168. if (m_expiryCounter >= 50)
  1169. {
  1170. ExpireAccessList();
  1171. m_expiryCounter = 0;
  1172. }
  1173. }
  1174. private void ExpireAccessList()
  1175. {
  1176. List<LandAccessEntry> delete = new List<LandAccessEntry>();
  1177. foreach (LandAccessEntry entry in LandData.ParcelAccessList)
  1178. {
  1179. if (entry.Expires != 0 && entry.Expires < Util.UnixTimeSinceEpoch())
  1180. delete.Add(entry);
  1181. }
  1182. foreach (LandAccessEntry entry in delete)
  1183. {
  1184. LandData.ParcelAccessList.Remove(entry);
  1185. ScenePresence presence;
  1186. if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
  1187. {
  1188. ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
  1189. if (land.LandData.LocalID == LandData.LocalID)
  1190. {
  1191. Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
  1192. presence.TeleportWithMomentum(pos, null);
  1193. presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
  1194. }
  1195. }
  1196. m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
  1197. }
  1198. if (delete.Count > 0)
  1199. m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this);
  1200. }
  1201. }
  1202. }