aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Land
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land')
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs92
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs24
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs406
4 files changed, 497 insertions, 31 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index 9e27ef0..7d990c2 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -116,6 +116,12 @@ namespace OpenSim.Region.CoreModules.World.Land
116 116
117 return new List<ILandObject>(); 117 return new List<ILandObject>();
118 } 118 }
119
120 public void Clear(bool setupDefaultParcel)
121 {
122 if (m_landManagementModule != null)
123 m_landManagementModule.Clear(setupDefaultParcel);
124 }
119 125
120 public List<ILandObject> ParcelsNearPoint(Vector3 position) 126 public List<ILandObject> ParcelsNearPoint(Vector3 position)
121 { 127 {
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 70767f7..98ba8c3 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -298,13 +298,19 @@ namespace OpenSim.Region.CoreModules.World.Land
298 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 298 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
299 m_landIDList.Initialize(); 299 m_landIDList.Initialize();
300 } 300 }
301 301 }
302
303 /// <summary>
304 /// Create a default parcel that spans the entire region and is owned by the estate owner.
305 /// </summary>
306 /// <returns>The parcel created.</returns>
307 protected ILandObject CreateDefaultParcel()
308 {
302 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 309 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
303
304 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 310 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
305 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 311 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
306 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 312 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
307 AddLandObject(fullSimParcel); 313 return AddLandObject(fullSimParcel);
308 } 314 }
309 315
310 public List<ILandObject> AllParcels() 316 public List<ILandObject> AllParcels()
@@ -578,15 +584,6 @@ namespace OpenSim.Region.CoreModules.World.Land
578 } 584 }
579 585
580 /// <summary> 586 /// <summary>
581 /// Creates a basic Parcel object without an owner (a zeroed key)
582 /// </summary>
583 /// <returns></returns>
584 public ILandObject CreateBaseLand()
585 {
586 return new LandObject(UUID.Zero, false, m_scene);
587 }
588
589 /// <summary>
590 /// Adds a land object to the stored list and adds them to the landIDList to what they own 587 /// Adds a land object to the stored list and adds them to the landIDList to what they own
591 /// </summary> 588 /// </summary>
592 /// <param name="new_land">The land object being added</param> 589 /// <param name="new_land">The land object being added</param>
@@ -645,6 +642,28 @@ namespace OpenSim.Region.CoreModules.World.Land
645 m_landList.Remove(local_id); 642 m_landList.Remove(local_id);
646 } 643 }
647 } 644 }
645
646 /// <summary>
647 /// Clear the scene of all parcels
648 /// </summary>
649 public void Clear(bool setupDefaultParcel)
650 {
651 lock (m_landList)
652 {
653 foreach (ILandObject lo in m_landList.Values)
654 {
655 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
656 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
657 }
658
659 m_landList.Clear();
660 }
661
662 ResetSimLandObjects();
663
664 if (setupDefaultParcel)
665 CreateDefaultParcel();
666 }
648 667
649 private void performFinalLandJoin(ILandObject master, ILandObject slave) 668 private void performFinalLandJoin(ILandObject master, ILandObject slave)
650 { 669 {
@@ -690,7 +709,7 @@ namespace OpenSim.Region.CoreModules.World.Land
690 int x; 709 int x;
691 int y; 710 int y;
692 711
693 if (x_float > Constants.RegionSize || x_float <= 0 || y_float > Constants.RegionSize || y_float <= 0) 712 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0)
694 return null; 713 return null;
695 714
696 try 715 try
@@ -732,10 +751,10 @@ namespace OpenSim.Region.CoreModules.World.Land
732 { 751 {
733 try 752 try
734 { 753 {
735 if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4])) 754 //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4]))
736 return m_landList[m_landIDList[x / 4, y / 4]]; 755 return m_landList[m_landIDList[x / 4, y / 4]];
737 else 756 //else
738 return null; 757 // return null;
739 } 758 }
740 catch (IndexOutOfRangeException) 759 catch (IndexOutOfRangeException)
741 { 760 {
@@ -1311,7 +1330,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1311 } 1330 }
1312 } 1331 }
1313 1332
1314
1315 void ClientOnParcelDeedToGroup(int parcelLocalID, UUID groupID, IClientAPI remote_client) 1333 void ClientOnParcelDeedToGroup(int parcelLocalID, UUID groupID, IClientAPI remote_client)
1316 { 1334 {
1317 ILandObject land; 1335 ILandObject land;
@@ -1327,10 +1345,8 @@ namespace OpenSim.Region.CoreModules.World.Land
1327 { 1345 {
1328 land.DeedToGroup(groupID); 1346 land.DeedToGroup(groupID);
1329 } 1347 }
1330
1331 } 1348 }
1332 1349
1333
1334 #region Land Object From Storage Functions 1350 #region Land Object From Storage Functions
1335 1351
1336 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1352 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
@@ -1365,6 +1381,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1365 public void EventManagerOnNoLandDataFromStorage() 1381 public void EventManagerOnNoLandDataFromStorage()
1366 { 1382 {
1367 ResetSimLandObjects(); 1383 ResetSimLandObjects();
1384 CreateDefaultParcel();
1368 } 1385 }
1369 1386
1370 #endregion 1387 #endregion
@@ -1622,14 +1639,36 @@ namespace OpenSim.Region.CoreModules.World.Land
1622 1639
1623 protected void InstallInterfaces() 1640 protected void InstallInterfaces()
1624 { 1641 {
1625 Command showCommand = 1642 Command clearCommand
1626 new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowParcelsCommand, "Shows all parcels on the current region."); 1643 = new Command("clear", CommandIntentions.COMMAND_HAZARDOUS, ClearCommand, "Clears all the parcels from the region.");
1644 Command showCommand
1645 = new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowParcelsCommand, "Shows all parcels on the region.");
1627 1646
1647 m_commander.RegisterCommand("clear", clearCommand);
1628 m_commander.RegisterCommand("show", showCommand); 1648 m_commander.RegisterCommand("show", showCommand);
1629 1649
1630 // Add this to our scene so scripts can call these functions 1650 // Add this to our scene so scripts can call these functions
1631 m_scene.RegisterModuleCommander(m_commander); 1651 m_scene.RegisterModuleCommander(m_commander);
1632 } 1652 }
1653
1654 protected void ClearCommand(Object[] args)
1655 {
1656 string response = MainConsole.Instance.CmdPrompt(
1657 string.Format(
1658 "Are you sure that you want to clear all land parcels from {0} (y or n)",
1659 m_scene.RegionInfo.RegionName),
1660 "n");
1661
1662 if (response.ToLower() == "y")
1663 {
1664 Clear(true);
1665 MainConsole.Instance.OutputFormat("Cleared all parcels from {0}", m_scene.RegionInfo.RegionName);
1666 }
1667 else
1668 {
1669 MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.RegionInfo.RegionName);
1670 }
1671 }
1633 1672
1634 protected void ShowParcelsCommand(Object[] args) 1673 protected void ShowParcelsCommand(Object[] args)
1635 { 1674 {
@@ -1637,8 +1676,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1637 1676
1638 report.AppendFormat("Land information for {0}\n", m_scene.RegionInfo.RegionName); 1677 report.AppendFormat("Land information for {0}\n", m_scene.RegionInfo.RegionName);
1639 report.AppendFormat( 1678 report.AppendFormat(
1640 "{0,-20} {1,-9} {2,-18} {3,-18} {4,-20}\n", 1679 "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n",
1641 "Parcel Name", 1680 "Parcel Name",
1681 "Local ID",
1642 "Area", 1682 "Area",
1643 "Starts", 1683 "Starts",
1644 "Ends", 1684 "Ends",
@@ -1651,12 +1691,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1651 LandData ld = lo.LandData; 1691 LandData ld = lo.LandData;
1652 1692
1653 report.AppendFormat( 1693 report.AppendFormat(
1654 "{0,-20} {1,-9} {2,-18} {3,-18} {4,-20}\n", 1694 "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n",
1655 ld.Name, ld.Area, lo.StartPoint, lo.EndPoint, m_userManager.GetUserName(ld.OwnerID)); 1695 ld.Name, ld.LocalID, ld.Area, lo.StartPoint, lo.EndPoint, m_userManager.GetUserName(ld.OwnerID));
1656 } 1696 }
1657 } 1697 }
1658 1698
1659 MainConsole.Instance.Output(report.ToString()); 1699 MainConsole.Instance.Output(report.ToString());
1660 } 1700 }
1661 } 1701 }
1662} \ No newline at end of file 1702} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index b90e307..46c15ed 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -66,6 +66,13 @@ namespace OpenSim.Region.CoreModules.World.Land
66 66
67 #region ILandObject Members 67 #region ILandObject Members
68 68
69 public int GetPrimsFree()
70 {
71 m_scene.EventManager.TriggerParcelPrimCountUpdate();
72 int free = GetSimulatorMaxPrimCount(this) - m_landData.SimwidePrims;
73 return free;
74 }
75
69 public LandData LandData 76 public LandData LandData
70 { 77 {
71 get { return m_landData; } 78 get { return m_landData; }
@@ -141,7 +148,7 @@ namespace OpenSim.Region.CoreModules.World.Land
141 /// <returns>Returns true if the piece of land contains the specified point</returns> 148 /// <returns>Returns true if the piece of land contains the specified point</returns>
142 public bool ContainsPoint(int x, int y) 149 public bool ContainsPoint(int x, int y)
143 { 150 {
144 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) 151 if (x >= 0 && y >= 0 && x < Constants.RegionSize && y < Constants.RegionSize)
145 { 152 {
146 return (LandBitmap[x / 4, y / 4] == true); 153 return (LandBitmap[x / 4, y / 4] == true);
147 } 154 }
@@ -183,7 +190,11 @@ namespace OpenSim.Region.CoreModules.World.Land
183 else 190 else
184 { 191 {
185 // Normal Calculations 192 // Normal Calculations
186 return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 193 int parcelMax = (int)(((float)LandData.Area / 65536.0f)
194 * (float)m_scene.RegionInfo.ObjectCapacity
195 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
196 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL!
197 return parcelMax;
187 } 198 }
188 } 199 }
189 public int GetSimulatorMaxPrimCount(ILandObject thisObject) 200 public int GetSimulatorMaxPrimCount(ILandObject thisObject)
@@ -195,7 +206,9 @@ namespace OpenSim.Region.CoreModules.World.Land
195 else 206 else
196 { 207 {
197 //Normal Calculations 208 //Normal Calculations
198 return m_scene.RegionInfo.ObjectCapacity; 209 int simMax = (int)(((float)LandData.SimwideArea / 65536.0f)
210 * (float)m_scene.RegionInfo.ObjectCapacity);
211 return simMax;
199 } 212 }
200 } 213 }
201 #endregion 214 #endregion
@@ -369,7 +382,7 @@ namespace OpenSim.Region.CoreModules.World.Land
369 newData.AuthBuyerID = UUID.Zero; 382 newData.AuthBuyerID = UUID.Zero;
370 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 383 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
371 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 384 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
372 385 m_scene.EventManager.TriggerParcelPrimCountUpdate();
373 SendLandUpdateToAvatarsOverMe(true); 386 SendLandUpdateToAvatarsOverMe(true);
374 } 387 }
375 388
@@ -384,7 +397,7 @@ namespace OpenSim.Region.CoreModules.World.Land
384 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 397 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
385 398
386 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 399 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
387 400 m_scene.EventManager.TriggerParcelPrimCountUpdate();
388 SendLandUpdateToAvatarsOverMe(true); 401 SendLandUpdateToAvatarsOverMe(true);
389 } 402 }
390 403
@@ -450,6 +463,7 @@ namespace OpenSim.Region.CoreModules.World.Land
450 463
451 public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) 464 public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client)
452 { 465 {
466 m_scene.EventManager.TriggerParcelPrimCountUpdate();
453 SendLandProperties(0, snap_selection, 0, remote_client); 467 SendLandProperties(0, snap_selection, 0, remote_client);
454 } 468 }
455 469
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
new file mode 100644
index 0000000..34ef67f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -0,0 +1,406 @@
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Diagnostics;
32using System.Reflection;
33using log4net;
34using Nini.Config;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40
41namespace OpenSim.Region.CoreModules.World.Land
42{
43 public class ParcelCounts
44 {
45 public int Owner = 0;
46 public int Group = 0;
47 public int Others = 0;
48 public Dictionary <UUID, int> Users =
49 new Dictionary <UUID, int>();
50 }
51
52 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule
53 {
54 private static readonly ILog m_log =
55 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 private Scene m_Scene;
58 private Dictionary<UUID, PrimCounts> m_PrimCounts =
59 new Dictionary<UUID, PrimCounts>();
60 private Dictionary<UUID, UUID> m_OwnerMap =
61 new Dictionary<UUID, UUID>();
62 private Dictionary<UUID, int> m_SimwideCounts =
63 new Dictionary<UUID, int>();
64 private Dictionary<UUID, ParcelCounts> m_ParcelCounts =
65 new Dictionary<UUID, ParcelCounts>();
66
67 // For now, a simple simwide taint to get this up. Later parcel based
68 // taint to allow recounting a parcel if only ownership has changed
69 // without recounting the whole sim.
70 private bool m_Tainted = true;
71 private Object m_TaintLock = new Object();
72
73 public Type ReplaceableInterface
74 {
75 get { return null; }
76 }
77
78 public void Initialise(IConfigSource source)
79 {
80 }
81
82 public void AddRegion(Scene scene)
83 {
84 m_Scene = scene;
85
86 m_Scene.EventManager.OnParcelPrimCountAdd +=
87 OnParcelPrimCountAdd;
88 m_Scene.EventManager.OnObjectBeingRemovedFromScene +=
89 OnObjectBeingRemovedFromScene;
90 m_Scene.EventManager.OnParcelPrimCountTainted +=
91 OnParcelPrimCountTainted;
92 }
93
94 public void RegionLoaded(Scene scene)
95 {
96 }
97
98 public void RemoveRegion(Scene scene)
99 {
100 }
101
102 public void Close()
103 {
104 }
105
106 public string Name
107 {
108 get { return "PrimCountModule"; }
109 }
110
111 private void OnParcelPrimCountAdd(SceneObjectGroup obj)
112 {
113 // If we're tainted already, don't bother to add. The next
114 // access will cause a recount anyway
115 lock (m_TaintLock)
116 {
117 if (!m_Tainted)
118 AddObject(obj);
119 }
120 }
121
122 private void OnObjectBeingRemovedFromScene(SceneObjectGroup obj)
123 {
124 // Don't bother to update tainted counts
125 lock (m_TaintLock)
126 {
127 if (!m_Tainted)
128 RemoveObject(obj);
129 }
130 }
131
132 private void OnParcelPrimCountTainted()
133 {
134 lock (m_TaintLock)
135 m_Tainted = true;
136 }
137
138 public void TaintPrimCount(ILandObject land)
139 {
140 lock (m_TaintLock)
141 m_Tainted = true;
142 }
143
144 public void TaintPrimCount(int x, int y)
145 {
146 lock (m_TaintLock)
147 m_Tainted = true;
148 }
149
150 public void TaintPrimCount()
151 {
152 lock (m_TaintLock)
153 m_Tainted = true;
154 }
155
156 // NOTE: Call under Taint Lock
157 private void AddObject(SceneObjectGroup obj)
158 {
159 if (obj.IsAttachment)
160 return;
161 if (((obj.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0))
162 return;
163
164 Vector3 pos = obj.AbsolutePosition;
165 ILandObject landObject = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
166 LandData landData = landObject.LandData;
167
168 ParcelCounts parcelCounts;
169 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
170 {
171 UUID landOwner = landData.OwnerID;
172 int partCount = obj.Parts.Length;
173
174 m_SimwideCounts[landOwner] += partCount;
175 if (parcelCounts.Users.ContainsKey(obj.OwnerID))
176 parcelCounts.Users[obj.OwnerID] += partCount;
177 else
178 parcelCounts.Users[obj.OwnerID] = partCount;
179
180 if (landData.IsGroupOwned)
181 {
182 if (obj.OwnerID == landData.GroupID)
183 parcelCounts.Owner += partCount;
184 else if (obj.GroupID == landData.GroupID)
185 parcelCounts.Group += partCount;
186 else
187 parcelCounts.Others += partCount;
188 }
189 else
190 {
191 if (obj.OwnerID == landData.OwnerID)
192 parcelCounts.Owner += partCount;
193 else if (obj.GroupID == landData.GroupID)
194 parcelCounts.Group += partCount;
195 else
196 parcelCounts.Others += partCount;
197 }
198 }
199 }
200
201 // NOTE: Call under Taint Lock
202 private void RemoveObject(SceneObjectGroup obj)
203 {
204 }
205
206 public IPrimCounts GetPrimCounts(UUID parcelID)
207 {
208 PrimCounts primCounts;
209
210 lock (m_PrimCounts)
211 {
212 if (m_PrimCounts.TryGetValue(parcelID, out primCounts))
213 return primCounts;
214
215 primCounts = new PrimCounts(parcelID, this);
216 m_PrimCounts[parcelID] = primCounts;
217 }
218 return primCounts;
219 }
220
221 public int GetOwnerCount(UUID parcelID)
222 {
223 lock (m_TaintLock)
224 {
225 if (m_Tainted)
226 Recount();
227
228 ParcelCounts counts;
229 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
230 return counts.Owner;
231 }
232 return 0;
233 }
234
235 public int GetGroupCount(UUID parcelID)
236 {
237 lock (m_TaintLock)
238 {
239 if (m_Tainted)
240 Recount();
241
242 ParcelCounts counts;
243 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
244 return counts.Group;
245 }
246 return 0;
247 }
248
249 public int GetOthersCount(UUID parcelID)
250 {
251 lock (m_TaintLock)
252 {
253 if (m_Tainted)
254 Recount();
255
256 ParcelCounts counts;
257 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
258 return counts.Others;
259 }
260 return 0;
261 }
262
263 public int GetSimulatorCount(UUID parcelID)
264 {
265 lock (m_TaintLock)
266 {
267 if (m_Tainted)
268 Recount();
269
270 UUID owner;
271 if (m_OwnerMap.TryGetValue(parcelID, out owner))
272 {
273 int val;
274 if (m_SimwideCounts.TryGetValue(owner, out val))
275 return val;
276 }
277 }
278 return 0;
279 }
280
281 public int GetUserCount(UUID parcelID, UUID userID)
282 {
283 lock (m_TaintLock)
284 {
285 if (m_Tainted)
286 Recount();
287
288 ParcelCounts counts;
289 if (m_ParcelCounts.TryGetValue(parcelID, out counts))
290 {
291 int val;
292 if (counts.Users.TryGetValue(userID, out val))
293 return val;
294 }
295 }
296 return 0;
297 }
298
299 // NOTE: This method MUST be called while holding the taint lock!
300 private void Recount()
301 {
302 m_OwnerMap.Clear();
303 m_SimwideCounts.Clear();
304 m_ParcelCounts.Clear();
305
306 List<ILandObject> land = m_Scene.LandChannel.AllParcels();
307
308 foreach (ILandObject l in land)
309 {
310 LandData landData = l.LandData;
311
312 m_OwnerMap[landData.GlobalID] = landData.OwnerID;
313 m_SimwideCounts[landData.OwnerID] = 0;
314 m_ParcelCounts[landData.GlobalID] = new ParcelCounts();
315 }
316
317 m_Scene.ForEachSOG(AddObject);
318
319 List<UUID> primcountKeys = new List<UUID>(m_PrimCounts.Keys);
320 foreach (UUID k in primcountKeys)
321 {
322 if (!m_OwnerMap.ContainsKey(k))
323 m_PrimCounts.Remove(k);
324 }
325 m_Tainted = false;
326 }
327 }
328
329 public class PrimCounts : IPrimCounts
330 {
331 private PrimCountModule m_Parent;
332 private UUID m_ParcelID;
333 private UserPrimCounts m_UserPrimCounts;
334
335 public PrimCounts (UUID parcelID, PrimCountModule parent)
336 {
337 m_ParcelID = parcelID;
338 m_Parent = parent;
339
340 m_UserPrimCounts = new UserPrimCounts(this);
341 }
342
343 public int Owner
344 {
345 get
346 {
347 return m_Parent.GetOwnerCount(m_ParcelID);
348 }
349 }
350
351 public int Group
352 {
353 get
354 {
355 return m_Parent.GetGroupCount(m_ParcelID);
356 }
357 }
358
359 public int Others
360 {
361 get
362 {
363 return m_Parent.GetOthersCount(m_ParcelID);
364 }
365 }
366
367 public int Simulator
368 {
369 get
370 {
371 return m_Parent.GetSimulatorCount(m_ParcelID);
372 }
373 }
374
375 public IUserPrimCounts Users
376 {
377 get
378 {
379 return m_UserPrimCounts;
380 }
381 }
382
383 public int GetUserCount(UUID userID)
384 {
385 return m_Parent.GetUserCount(m_ParcelID, userID);
386 }
387 }
388
389 public class UserPrimCounts : IUserPrimCounts
390 {
391 private PrimCounts m_Parent;
392
393 public UserPrimCounts(PrimCounts parent)
394 {
395 m_Parent = parent;
396 }
397
398 public int this[UUID userID]
399 {
400 get
401 {
402 return m_Parent.GetUserCount(userID);
403 }
404 }
405 }
406}