aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Land/LandObject.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandObject.cs930
1 files changed, 0 insertions, 930 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs b/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs
deleted file mode 100644
index b5f7225..0000000
--- a/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs
+++ /dev/null
@@ -1,930 +0,0 @@
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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using OpenMetaverse;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36
37namespace OpenSim.Region.Environment.Modules.World.Land
38{
39 /// <summary>
40 /// Keeps track of a specific piece of land's information
41 /// </summary>
42 public class LandObject : ILandObject
43 {
44 #region Member Variables
45
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 private bool[,] m_landBitmap = new bool[64,64];
48
49 protected LandData m_landData = new LandData();
50 protected Scene m_scene;
51 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
52
53 public bool[,] landBitmap
54 {
55 get { return m_landBitmap; }
56 set { m_landBitmap = value; }
57 }
58
59 #endregion
60
61 #region ILandObject Members
62
63 public LandData landData
64 {
65 get { return m_landData; }
66
67 set { m_landData = value; }
68 }
69
70 public UUID regionUUID
71 {
72 get { return m_scene.RegionInfo.RegionID; }
73 }
74
75 #region Constructors
76
77 public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
78 {
79 m_scene = scene;
80 landData.OwnerID = owner_id;
81 landData.IsGroupOwned = is_group_owned;
82 }
83
84 #endregion
85
86 #region Member Functions
87
88 #region General Functions
89
90 /// <summary>
91 /// Checks to see if this land object contains a point
92 /// </summary>
93 /// <param name="x"></param>
94 /// <param name="y"></param>
95 /// <returns>Returns true if the piece of land contains the specified point</returns>
96 public bool containsPoint(int x, int y)
97 {
98 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize)
99 {
100 return (landBitmap[x / 4, y / 4] == true);
101 }
102 else
103 {
104 return false;
105 }
106 }
107
108 public ILandObject Copy()
109 {
110 ILandObject newLand = new LandObject(landData.OwnerID, landData.IsGroupOwned, m_scene);
111
112 //Place all new variables here!
113 newLand.landBitmap = (bool[,]) (landBitmap.Clone());
114 newLand.landData = landData.Copy();
115
116 return newLand;
117 }
118
119
120 static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount;
121 static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount;
122
123 public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
124 {
125 overrideParcelMaxPrimCount = overrideDel;
126 }
127 public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
128 {
129 overrideSimulatorMaxPrimCount = overrideDel;
130 }
131
132 public int getParcelMaxPrimCount(ILandObject thisObject)
133 {
134 if (overrideParcelMaxPrimCount != null)
135 {
136 return overrideParcelMaxPrimCount(thisObject);
137 }
138 else
139 {
140 //Normal Calculations
141 return Convert.ToInt32(
142 Math.Round((Convert.ToDecimal(landData.Area) / Convert.ToDecimal(65536)) * m_scene.objectCapacity *
143 Convert.ToDecimal(m_scene.RegionInfo.RegionSettings.ObjectBonus))); ;
144 }
145 }
146 public int getSimulatorMaxPrimCount(ILandObject thisObject)
147 {
148 if (overrideSimulatorMaxPrimCount != null)
149 {
150 return overrideSimulatorMaxPrimCount(thisObject);
151 }
152 else
153 {
154 //Normal Calculations
155 return m_scene.objectCapacity;
156 }
157 }
158 #endregion
159
160 #region Packet Request Handling
161
162 public void sendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
163 {
164 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
165 uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
166 if (estateModule != null)
167 regionFlags = estateModule.GetRegionFlags();
168
169 // In a perfect world, this would have worked.
170 //
171// if ((landData.Flags & (uint)Parcel.ParcelFlags.AllowLandmark) != 0)
172// regionFlags |= (uint)RegionFlags.AllowLandmark;
173// if (landData.OwnerID == remote_client.AgentId)
174// regionFlags |= (uint)RegionFlags.AllowSetHome;
175 remote_client.SendLandProperties(sequence_id,
176 snap_selection, request_result, landData,
177 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
178 getParcelMaxPrimCount(this),
179 getSimulatorMaxPrimCount(this), regionFlags);
180 }
181
182 public void updateLandProperties(LandUpdateArgs args, IClientAPI remote_client)
183 {
184 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this))
185 {
186 //Needs later group support
187 LandData newData = landData.Copy();
188
189 if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice)
190 {
191 if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this))
192 {
193 newData.AuthBuyerID = args.AuthBuyerID;
194 newData.SalePrice = args.SalePrice;
195 }
196 }
197 newData.Category = args.Category;
198 newData.Description = args.Desc;
199 newData.GroupID = args.GroupID;
200 newData.LandingType = args.LandingType;
201 newData.MediaAutoScale = args.MediaAutoScale;
202 newData.MediaID = args.MediaID;
203 newData.MediaURL = args.MediaURL;
204 newData.MusicURL = args.MusicURL;
205 newData.Name = args.Name;
206 newData.Flags = args.ParcelFlags;
207 newData.PassHours = args.PassHours;
208 newData.PassPrice = args.PassPrice;
209 newData.SnapshotID = args.SnapshotID;
210 newData.UserLocation = args.UserLocation;
211 newData.UserLookAt = args.UserLookAt;
212
213 m_scene.LandChannel.UpdateLandObject(landData.LocalID, newData);
214
215 sendLandUpdateToAvatarsOverMe();
216 }
217 }
218
219 public void updateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
220 {
221 LandData newData = landData.Copy();
222 newData.OwnerID = avatarID;
223 newData.GroupID = groupID;
224 newData.IsGroupOwned = groupOwned;
225 //newData.auctionID = AuctionID;
226 newData.ClaimDate = Util.UnixTimeSinceEpoch();
227 newData.ClaimPrice = claimprice;
228 newData.SalePrice = 0;
229 newData.AuthBuyerID = UUID.Zero;
230 newData.Flags &= ~(uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects);
231 m_scene.LandChannel.UpdateLandObject(landData.LocalID, newData);
232
233 sendLandUpdateToAvatarsOverMe();
234 }
235
236 public bool isEitherBannedOrRestricted(UUID avatar)
237 {
238 if (isBannedFromLand(avatar))
239 {
240 return true;
241 }
242 else if (isRestrictedFromLand(avatar))
243 {
244 return true;
245 }
246 return false;
247 }
248
249 public bool isBannedFromLand(UUID avatar)
250 {
251 if ((landData.Flags & (uint) Parcel.ParcelFlags.UseBanList) > 0)
252 {
253 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
254 entry.AgentID = avatar;
255 entry.Flags = AccessList.Ban;
256 entry.Time = new DateTime();
257 if (landData.ParcelAccessList.Contains(entry))
258 {
259 //They are banned, so lets send them a notice about this parcel
260 return true;
261 }
262 }
263 return false;
264 }
265
266 public bool isRestrictedFromLand(UUID avatar)
267 {
268 if ((landData.Flags & (uint) Parcel.ParcelFlags.UseAccessList) > 0)
269 {
270 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
271 entry.AgentID = avatar;
272 entry.Flags = AccessList.Access;
273 entry.Time = new DateTime();
274 if (!landData.ParcelAccessList.Contains(entry))
275 {
276 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
277 return true;
278 }
279 }
280 return false;
281 }
282
283 public void sendLandUpdateToClient(IClientAPI remote_client)
284 {
285 sendLandProperties(0, false, 0, remote_client);
286 }
287
288 public void sendLandUpdateToAvatarsOverMe()
289 {
290 List<ScenePresence> avatars = m_scene.GetAvatars();
291 ILandObject over = null;
292 for (int i = 0; i < avatars.Count; i++)
293 {
294 try
295 {
296 over =
297 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatars[i].AbsolutePosition.X), 0, 255),
298 Util.Clamp<int>((int)Math.Round(avatars[i].AbsolutePosition.Y), 0, 255));
299 }
300 catch (Exception)
301 {
302 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " +
303 Math.Round(avatars[i].AbsolutePosition.Y));
304 }
305
306 if (over != null)
307 {
308 if (over.landData.LocalID == landData.LocalID)
309 {
310 if (((over.landData.Flags & (uint)Parcel.ParcelFlags.AllowDamage) != 0) && m_scene.RegionInfo.RegionSettings.AllowDamage)
311 avatars[i].Invulnerable = false;
312 else
313 avatars[i].Invulnerable = true;
314
315 sendLandUpdateToClient(avatars[i].ControllingClient);
316 }
317 }
318 }
319 }
320
321 #endregion
322
323 #region AccessList Functions
324
325 public List<UUID> createAccessListArrayByFlag(AccessList flag)
326 {
327 List<UUID> list = new List<UUID>();
328 foreach (ParcelManager.ParcelAccessEntry entry in landData.ParcelAccessList)
329 {
330 if (entry.Flags == flag)
331 {
332 list.Add(entry.AgentID);
333 }
334 }
335 if (list.Count == 0)
336 {
337 list.Add(UUID.Zero);
338 }
339
340 return list;
341 }
342
343 public void sendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID,
344 IClientAPI remote_client)
345 {
346
347 if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both)
348 {
349 List<UUID> avatars = createAccessListArrayByFlag(AccessList.Access);
350 remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,landData.LocalID);
351 }
352
353 if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both)
354 {
355 List<UUID> avatars = createAccessListArrayByFlag(AccessList.Ban);
356 remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, landData.LocalID);
357 }
358 }
359
360 public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client)
361 {
362 LandData newData = landData.Copy();
363
364 if (entries.Count == 1 && entries[0].AgentID == UUID.Zero)
365 {
366 entries.Clear();
367 }
368
369 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>();
370 foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList)
371 {
372 if (entry.Flags == (AccessList)flags)
373 {
374 toRemove.Add(entry);
375 }
376 }
377
378 foreach (ParcelManager.ParcelAccessEntry entry in toRemove)
379 {
380 newData.ParcelAccessList.Remove(entry);
381 }
382 foreach (ParcelManager.ParcelAccessEntry entry in entries)
383 {
384 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry();
385 temp.AgentID = entry.AgentID;
386 temp.Time = new DateTime(); //Pointless? Yes.
387 temp.Flags = (AccessList)flags;
388
389 if (!newData.ParcelAccessList.Contains(temp))
390 {
391 newData.ParcelAccessList.Add(temp);
392 }
393 }
394
395 m_scene.LandChannel.UpdateLandObject(landData.LocalID, newData);
396 }
397
398 #endregion
399
400 #region Update Functions
401
402 public void updateLandBitmapByteArray()
403 {
404 landData.Bitmap = convertLandBitmapToBytes();
405 }
406
407 /// <summary>
408 /// Update all settings in land such as area, bitmap byte array, etc
409 /// </summary>
410 public void forceUpdateLandInfo()
411 {
412 updateAABBAndAreaValues();
413 updateLandBitmapByteArray();
414 }
415
416 public void setLandBitmapFromByteArray()
417 {
418 landBitmap = convertBytesToLandBitmap();
419 }
420
421 /// <summary>
422 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object
423 /// </summary>
424 private void updateAABBAndAreaValues()
425 {
426 int min_x = 64;
427 int min_y = 64;
428 int max_x = 0;
429 int max_y = 0;
430 int tempArea = 0;
431 int x, y;
432 for (x = 0; x < 64; x++)
433 {
434 for (y = 0; y < 64; y++)
435 {
436 if (landBitmap[x, y] == true)
437 {
438 if (min_x > x) min_x = x;
439 if (min_y > y) min_y = y;
440 if (max_x < x) max_x = x;
441 if (max_y < y) max_y = y;
442 tempArea += 16; //16sqm peice of land
443 }
444 }
445 }
446 int tx = min_x * 4;
447 if (tx > 255)
448 tx = 255;
449 int ty = min_y * 4;
450 if (ty > 255)
451 ty = 255;
452 landData.AABBMin =
453 new Vector3((float) (min_x * 4), (float) (min_y * 4),
454 (float) m_scene.Heightmap[tx, ty]);
455
456 tx = max_x * 4;
457 if (tx > 255)
458 tx = 255;
459 ty = max_y * 4;
460 if (ty > 255)
461 ty = 255;
462 landData.AABBMax =
463 new Vector3((float) (max_x * 4), (float) (max_y * 4),
464 (float) m_scene.Heightmap[tx, ty]);
465 landData.Area = tempArea;
466 }
467
468 #endregion
469
470 #region Land Bitmap Functions
471
472 /// <summary>
473 /// Sets the land's bitmap manually
474 /// </summary>
475 /// <param name="bitmap">64x64 block representing where this land is on a map</param>
476 public void setLandBitmap(bool[,] bitmap)
477 {
478 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
479 {
480 //Throw an exception - The bitmap is not 64x64
481 //throw new Exception("Error: Invalid Parcel Bitmap");
482 }
483 else
484 {
485 //Valid: Lets set it
486 landBitmap = bitmap;
487 forceUpdateLandInfo();
488 }
489 }
490
491 /// <summary>
492 /// Gets the land's bitmap manually
493 /// </summary>
494 /// <returns></returns>
495 public bool[,] getLandBitmap()
496 {
497 return landBitmap;
498 }
499
500 /// <summary>
501 /// Full sim land object creation
502 /// </summary>
503 /// <returns></returns>
504 public bool[,] basicFullRegionLandBitmap()
505 {
506 return getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize);
507 }
508
509 /// <summary>
510 /// Used to modify the bitmap between the x and y points. Points use 64 scale
511 /// </summary>
512 /// <param name="start_x"></param>
513 /// <param name="start_y"></param>
514 /// <param name="end_x"></param>
515 /// <param name="end_y"></param>
516 /// <returns></returns>
517 public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
518 {
519 bool[,] tempBitmap = new bool[64,64];
520 tempBitmap.Initialize();
521
522 tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
523 return tempBitmap;
524 }
525
526 /// <summary>
527 /// Change a land bitmap at within a square and set those points to a specific value
528 /// </summary>
529 /// <param name="land_bitmap"></param>
530 /// <param name="start_x"></param>
531 /// <param name="start_y"></param>
532 /// <param name="end_x"></param>
533 /// <param name="end_y"></param>
534 /// <param name="set_value"></param>
535 /// <returns></returns>
536 public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
537 bool set_value)
538 {
539 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
540 {
541 //Throw an exception - The bitmap is not 64x64
542 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
543 }
544
545 int x, y;
546 for (y = 0; y < 64; y++)
547 {
548 for (x = 0; x < 64; x++)
549 {
550 if (x >= start_x / 4 && x < end_x / 4
551 && y >= start_y / 4 && y < end_y / 4)
552 {
553 land_bitmap[x, y] = set_value;
554 }
555 }
556 }
557 return land_bitmap;
558 }
559
560 /// <summary>
561 /// Join the true values of 2 bitmaps together
562 /// </summary>
563 /// <param name="bitmap_base"></param>
564 /// <param name="bitmap_add"></param>
565 /// <returns></returns>
566 public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
567 {
568 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
569 {
570 //Throw an exception - The bitmap is not 64x64
571 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
572 }
573 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
574 {
575 //Throw an exception - The bitmap is not 64x64
576 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
577 }
578
579 int x, y;
580 for (y = 0; y < 64; y++)
581 {
582 for (x = 0; x < 64; x++)
583 {
584 if (bitmap_add[x, y])
585 {
586 bitmap_base[x, y] = true;
587 }
588 }
589 }
590 return bitmap_base;
591 }
592
593 /// <summary>
594 /// Converts the land bitmap to a packet friendly byte array
595 /// </summary>
596 /// <returns></returns>
597 private byte[] convertLandBitmapToBytes()
598 {
599 byte[] tempConvertArr = new byte[512];
600 byte tempByte = 0;
601 int x, y, i, byteNum = 0;
602 i = 0;
603 for (y = 0; y < 64; y++)
604 {
605 for (x = 0; x < 64; x++)
606 {
607 tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++ % 8));
608 if (i % 8 == 0)
609 {
610 tempConvertArr[byteNum] = tempByte;
611 tempByte = (byte) 0;
612 i = 0;
613 byteNum++;
614 }
615 }
616 }
617 return tempConvertArr;
618 }
619
620 private bool[,] convertBytesToLandBitmap()
621 {
622 bool[,] tempConvertMap = new bool[64,64];
623 tempConvertMap.Initialize();
624 byte tempByte = 0;
625 int x = 0, y = 0, i = 0, bitNum = 0;
626 for (i = 0; i < 512; i++)
627 {
628 tempByte = landData.Bitmap[i];
629 for (bitNum = 0; bitNum < 8; bitNum++)
630 {
631 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
632 tempConvertMap[x, y] = bit;
633 x++;
634 if (x > 63)
635 {
636 x = 0;
637 y++;
638 }
639 }
640 }
641 return tempConvertMap;
642 }
643
644 #endregion
645
646 #region Object Select and Object Owner Listing
647
648 public void sendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client)
649 {
650 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this))
651 {
652 List<uint> resultLocalIDs = new List<uint>();
653 try
654 {
655 lock (primsOverMe)
656 {
657 foreach (SceneObjectGroup obj in primsOverMe)
658 {
659 if (obj.LocalId > 0)
660 {
661 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.OwnerID)
662 {
663 resultLocalIDs.Add(obj.LocalId);
664 }
665 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == landData.GroupID && landData.GroupID != UUID.Zero)
666 {
667 resultLocalIDs.Add(obj.LocalId);
668 }
669 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
670 obj.OwnerID != remote_client.AgentId)
671 {
672 resultLocalIDs.Add(obj.LocalId);
673 }
674 else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID))
675 {
676 resultLocalIDs.Add(obj.LocalId);
677 }
678 }
679 }
680 }
681 } catch (InvalidOperationException)
682 {
683 m_log.Error("[LAND]: Unable to force select the parcel objects. Arr.");
684 }
685
686 remote_client.SendForceClientSelectObjects(resultLocalIDs);
687 }
688 }
689
690 /// <summary>
691 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes
692 /// aggreagete details such as the number of prims.
693 ///
694 /// </summary>
695 /// <param name="remote_client">
696 /// A <see cref="IClientAPI"/>
697 /// </param>
698 public void sendLandObjectOwners(IClientAPI remote_client)
699 {
700 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this))
701 {
702 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>();
703
704 lock (primsOverMe)
705 {
706 try
707 {
708
709 foreach (SceneObjectGroup obj in primsOverMe)
710 {
711 try
712 {
713 if (!primCount.ContainsKey(obj.OwnerID))
714 {
715 primCount.Add(obj.OwnerID, 0);
716 }
717 }
718 catch (NullReferenceException)
719 {
720 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel");
721 }
722 try
723 {
724 primCount[obj.OwnerID] += obj.PrimCount;
725 }
726 catch (KeyNotFoundException)
727 {
728 m_log.Error("[LAND]: Unable to match a prim with it's owner.");
729 }
730 }
731 }
732 catch (InvalidOperationException)
733 {
734 m_log.Error("[LAND]: Unable to Enumerate Land object arr.");
735 }
736 }
737
738 remote_client.SendLandObjectOwners(primCount);
739 }
740 }
741
742 public Dictionary<UUID, int> getLandObjectOwners()
743 {
744 Dictionary<UUID, int> ownersAndCount = new Dictionary<UUID, int>();
745 lock (primsOverMe)
746 {
747 try
748 {
749
750 foreach (SceneObjectGroup obj in primsOverMe)
751 {
752 if (!ownersAndCount.ContainsKey(obj.OwnerID))
753 {
754 ownersAndCount.Add(obj.OwnerID, 0);
755 }
756 ownersAndCount[obj.OwnerID] += obj.PrimCount;
757 }
758 }
759 catch (InvalidOperationException)
760 {
761 m_log.Error("[LAND]: Unable to enumerate land owners. arr.");
762 }
763
764 }
765 return ownersAndCount;
766 }
767
768 #endregion
769
770 #region Object Returning
771
772 public void returnObject(SceneObjectGroup obj)
773 {
774 SceneObjectGroup[] objs = new SceneObjectGroup[1];
775 objs[0] = obj;
776 m_scene.returnObjects(objs, obj.OwnerID);
777 }
778
779 public void returnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client)
780 {
781 Dictionary<UUID,List<SceneObjectGroup>> returns =
782 new Dictionary<UUID,List<SceneObjectGroup>>();
783
784 lock (primsOverMe)
785 {
786 if (type == (uint)ObjectReturnType.Owner)
787 {
788 foreach (SceneObjectGroup obj in primsOverMe)
789 {
790 if (obj.OwnerID == m_landData.OwnerID)
791 {
792 if (!returns.ContainsKey(obj.OwnerID))
793 returns[obj.OwnerID] =
794 new List<SceneObjectGroup>();
795 returns[obj.OwnerID].Add(obj);
796 }
797 }
798 }
799 else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero)
800 {
801 foreach (SceneObjectGroup obj in primsOverMe)
802 {
803 if (obj.GroupID == m_landData.GroupID)
804 {
805 if (!returns.ContainsKey(obj.OwnerID))
806 returns[obj.OwnerID] =
807 new List<SceneObjectGroup>();
808 returns[obj.OwnerID].Add(obj);
809 }
810 }
811 }
812 else if (type == (uint)ObjectReturnType.Other)
813 {
814 foreach (SceneObjectGroup obj in primsOverMe)
815 {
816 if (obj.OwnerID != m_landData.OwnerID &&
817 (obj.GroupID != m_landData.GroupID ||
818 m_landData.GroupID == UUID.Zero))
819 {
820 if (!returns.ContainsKey(obj.OwnerID))
821 returns[obj.OwnerID] =
822 new List<SceneObjectGroup>();
823 returns[obj.OwnerID].Add(obj);
824 }
825 }
826 }
827 else if (type == (uint)ObjectReturnType.List)
828 {
829 List<UUID> ownerlist = new List<UUID>(owners);
830
831 foreach (SceneObjectGroup obj in primsOverMe)
832 {
833 if (ownerlist.Contains(obj.OwnerID))
834 {
835 if (!returns.ContainsKey(obj.OwnerID))
836 returns[obj.OwnerID] =
837 new List<SceneObjectGroup>();
838 returns[obj.OwnerID].Add(obj);
839 }
840 }
841 }
842 }
843
844 foreach (List<SceneObjectGroup> ol in returns.Values)
845 m_scene.returnObjects(ol.ToArray(), remote_client.AgentId);
846 }
847
848 #endregion
849
850 #region Object Adding/Removing from Parcel
851
852 public void resetLandPrimCounts()
853 {
854 landData.GroupPrims = 0;
855 landData.OwnerPrims = 0;
856 landData.OtherPrims = 0;
857 landData.SelectedPrims = 0;
858
859
860 lock (primsOverMe)
861 primsOverMe.Clear();
862 }
863
864 public void addPrimToCount(SceneObjectGroup obj)
865 {
866
867 UUID prim_owner = obj.OwnerID;
868 int prim_count = obj.PrimCount;
869
870 if (obj.IsSelected)
871 {
872 landData.SelectedPrims += prim_count;
873 }
874 else
875 {
876 if (prim_owner == landData.OwnerID)
877 {
878 landData.OwnerPrims += prim_count;
879 }
880 else if ((obj.GroupID == landData.GroupID ||
881 prim_owner == landData.GroupID) &&
882 landData.GroupID != UUID.Zero)
883 {
884 landData.GroupPrims += prim_count;
885 }
886 else
887 {
888 landData.OtherPrims += prim_count;
889 }
890 }
891
892 lock (primsOverMe)
893 primsOverMe.Add(obj);
894 }
895
896 public void removePrimFromCount(SceneObjectGroup obj)
897 {
898 lock (primsOverMe)
899 {
900 if (primsOverMe.Contains(obj))
901 {
902 UUID prim_owner = obj.OwnerID;
903 int prim_count = obj.PrimCount;
904
905 if (prim_owner == landData.OwnerID)
906 {
907 landData.OwnerPrims -= prim_count;
908 }
909 else if (obj.GroupID == landData.GroupID ||
910 prim_owner == landData.GroupID)
911 {
912 landData.GroupPrims -= prim_count;
913 }
914 else
915 {
916 landData.OtherPrims -= prim_count;
917 }
918
919 primsOverMe.Remove(obj);
920 }
921 }
922 }
923
924 #endregion
925
926 #endregion
927
928 #endregion
929 }
930}