diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land')
7 files changed, 1205 insertions, 362 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs index bd22155..70c6028 100644 --- a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs | |||
@@ -45,17 +45,19 @@ using OpenSim.Framework.Servers.HttpServer; | |||
45 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; | 45 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; |
46 | using OpenSim.Region.Framework.Interfaces; | 46 | using OpenSim.Region.Framework.Interfaces; |
47 | using OpenSim.Region.Framework.Scenes; | 47 | using OpenSim.Region.Framework.Scenes; |
48 | using OpenSim.Region.Physics.Manager; | 48 | using OpenSim.Region.PhysicsModules.SharedBase; |
49 | using OpenSim.Services.Interfaces; | 49 | using OpenSim.Services.Interfaces; |
50 | using Caps = OpenSim.Framework.Capabilities.Caps; | 50 | using Caps = OpenSim.Framework.Capabilities.Caps; |
51 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 51 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
52 | 52 | ||
53 | namespace OpenSim.Region.CoreModules.World.Land | 53 | namespace OpenSim.Region.CoreModules.World.Land |
54 | { | 54 | { |
55 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DwellModule")] | 55 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DefaultDwellModule")] |
56 | public class DwellModule : IDwellModule, INonSharedRegionModule | 56 | public class DefaultDwellModule : IDwellModule, INonSharedRegionModule |
57 | { | 57 | { |
58 | private Scene m_scene; | 58 | private Scene m_scene; |
59 | private IConfigSource m_Config; | ||
60 | private bool m_Enabled = false; | ||
59 | 61 | ||
60 | public Type ReplaceableInterface | 62 | public Type ReplaceableInterface |
61 | { | 63 | { |
@@ -64,15 +66,27 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
64 | 66 | ||
65 | public string Name | 67 | public string Name |
66 | { | 68 | { |
67 | get { return "DwellModule"; } | 69 | get { return "DefaultDwellModule"; } |
68 | } | 70 | } |
69 | 71 | ||
70 | public void Initialise(IConfigSource source) | 72 | public void Initialise(IConfigSource source) |
71 | { | 73 | { |
74 | m_Config = source; | ||
75 | |||
76 | IConfig DwellConfig = m_Config.Configs ["Dwell"]; | ||
77 | |||
78 | if (DwellConfig == null) { | ||
79 | m_Enabled = false; | ||
80 | return; | ||
81 | } | ||
82 | m_Enabled = (DwellConfig.GetString ("DwellModule", "DefaultDwellModule") == "DefaultDwellModule"); | ||
72 | } | 83 | } |
73 | 84 | ||
74 | public void AddRegion(Scene scene) | 85 | public void AddRegion(Scene scene) |
75 | { | 86 | { |
87 | if (!m_Enabled) | ||
88 | return; | ||
89 | |||
76 | m_scene = scene; | 90 | m_scene = scene; |
77 | 91 | ||
78 | m_scene.EventManager.OnNewClient += OnNewClient; | 92 | m_scene.EventManager.OnNewClient += OnNewClient; |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs index 7fc358d..73c592d 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs | |||
@@ -95,6 +95,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
95 | return null; | 95 | return null; |
96 | } | 96 | } |
97 | 97 | ||
98 | public ILandObject GetLandObject(Vector3 position) | ||
99 | { | ||
100 | return GetLandObject(position.X, position.Y); | ||
101 | } | ||
102 | |||
98 | public ILandObject GetLandObject(int x, int y) | 103 | public ILandObject GetLandObject(int x, int y) |
99 | { | 104 | { |
100 | if (m_landManagementModule != null) | 105 | if (m_landManagementModule != null) |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index bad7205..92f6c1b 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -42,10 +42,9 @@ using OpenSim.Framework.Capabilities; | |||
42 | using OpenSim.Framework.Console; | 42 | using OpenSim.Framework.Console; |
43 | using OpenSim.Framework.Servers; | 43 | using OpenSim.Framework.Servers; |
44 | using OpenSim.Framework.Servers.HttpServer; | 44 | using OpenSim.Framework.Servers.HttpServer; |
45 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; | ||
46 | using OpenSim.Region.Framework.Interfaces; | 45 | using OpenSim.Region.Framework.Interfaces; |
47 | using OpenSim.Region.Framework.Scenes; | 46 | using OpenSim.Region.Framework.Scenes; |
48 | using OpenSim.Region.Physics.Manager; | 47 | using OpenSim.Region.PhysicsModules.SharedBase; |
49 | using OpenSim.Services.Interfaces; | 48 | using OpenSim.Services.Interfaces; |
50 | using Caps = OpenSim.Framework.Capabilities.Caps; | 49 | using Caps = OpenSim.Framework.Capabilities.Caps; |
51 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 50 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
@@ -65,25 +64,27 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
65 | public class LandManagementModule : INonSharedRegionModule | 64 | public class LandManagementModule : INonSharedRegionModule |
66 | { | 65 | { |
67 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 66 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
67 | private static readonly string LogHeader = "[LAND MANAGEMENT MODULE]"; | ||
68 | |||
69 | /// <summary> | ||
70 | /// Minimum land unit size in region co-ordinates. | ||
71 | /// </summary> | ||
72 | public const int LandUnit = 4; | ||
68 | 73 | ||
69 | private static readonly string remoteParcelRequestPath = "0009/"; | 74 | private static readonly string remoteParcelRequestPath = "0009/"; |
70 | 75 | ||
71 | private LandChannel landChannel; | 76 | private LandChannel landChannel; |
72 | private Scene m_scene; | 77 | private Scene m_scene; |
73 | protected Commander m_commander = new Commander("land"); | 78 | |
74 | 79 | protected IGroupsModule m_groupManager; | |
75 | protected IUserManagement m_userManager; | 80 | protected IUserManagement m_userManager; |
76 | protected IPrimCountModule m_primCountModule; | 81 | protected IPrimCountModule m_primCountModule; |
77 | 82 | protected IDialogModule m_Dialog; | |
78 | // Minimum for parcels to work is 64m even if we don't actually use them. | ||
79 | #pragma warning disable 0429 | ||
80 | private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; | ||
81 | #pragma warning restore 0429 | ||
82 | 83 | ||
83 | /// <value> | 84 | /// <value> |
84 | /// Local land ids at specified region co-ordinates (region size / 4) | 85 | /// Local land ids at specified region co-ordinates (region size / 4) |
85 | /// </value> | 86 | /// </value> |
86 | private readonly int[,] m_landIDList = new int[landArrayMax, landArrayMax]; | 87 | private int[,] m_landIDList; |
87 | 88 | ||
88 | /// <value> | 89 | /// <value> |
89 | /// Land objects keyed by local id | 90 | /// Land objects keyed by local id |
@@ -97,11 +98,17 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
97 | // caches ExtendedLandData | 98 | // caches ExtendedLandData |
98 | private Cache parcelInfoCache; | 99 | private Cache parcelInfoCache; |
99 | 100 | ||
101 | |||
100 | /// <summary> | 102 | /// <summary> |
101 | /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. | 103 | /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. |
102 | /// </summary> | 104 | /// </summary> |
103 | private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); | 105 | private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); |
104 | 106 | ||
107 | // Enables limiting parcel layer info transmission when doing simple updates | ||
108 | private bool shouldLimitParcelLayerInfoToViewDistance { get; set; } | ||
109 | // "View distance" for sending parcel layer info if asked for from a view point in the region | ||
110 | private int parcelLayerViewDistance { get; set; } | ||
111 | |||
105 | #region INonSharedRegionModule Members | 112 | #region INonSharedRegionModule Members |
106 | 113 | ||
107 | public Type ReplaceableInterface | 114 | public Type ReplaceableInterface |
@@ -111,12 +118,20 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
111 | 118 | ||
112 | public void Initialise(IConfigSource source) | 119 | public void Initialise(IConfigSource source) |
113 | { | 120 | { |
121 | shouldLimitParcelLayerInfoToViewDistance = true; | ||
122 | parcelLayerViewDistance = 128; | ||
123 | IConfig landManagementConfig = source.Configs["LandManagement"]; | ||
124 | if (landManagementConfig != null) | ||
125 | { | ||
126 | shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance); | ||
127 | parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance); | ||
128 | } | ||
114 | } | 129 | } |
115 | 130 | ||
116 | public void AddRegion(Scene scene) | 131 | public void AddRegion(Scene scene) |
117 | { | 132 | { |
118 | m_scene = scene; | 133 | m_scene = scene; |
119 | m_landIDList.Initialize(); | 134 | m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; |
120 | landChannel = new LandChannel(scene, this); | 135 | landChannel = new LandChannel(scene, this); |
121 | 136 | ||
122 | parcelInfoCache = new Cache(); | 137 | parcelInfoCache = new Cache(); |
@@ -139,28 +154,26 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
139 | m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; | 154 | m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; |
140 | m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan; | 155 | m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan; |
141 | m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps; | 156 | m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps; |
142 | m_scene.EventManager.OnPluginConsole += EventManagerOnPluginConsole; | ||
143 | 157 | ||
144 | lock (m_scene) | 158 | lock (m_scene) |
145 | { | 159 | { |
146 | m_scene.LandChannel = (ILandChannel)landChannel; | 160 | m_scene.LandChannel = (ILandChannel)landChannel; |
147 | } | 161 | } |
148 | 162 | ||
149 | InstallInterfaces(); | 163 | RegisterCommands(); |
150 | } | 164 | } |
151 | 165 | ||
152 | public void RegionLoaded(Scene scene) | 166 | public void RegionLoaded(Scene scene) |
153 | { | 167 | { |
154 | m_userManager = m_scene.RequestModuleInterface<IUserManagement>(); | 168 | m_userManager = m_scene.RequestModuleInterface<IUserManagement>(); |
155 | m_primCountModule = m_scene.RequestModuleInterface<IPrimCountModule>(); | 169 | m_groupManager = m_scene.RequestModuleInterface<IGroupsModule>(); |
170 | m_primCountModule = m_scene.RequestModuleInterface<IPrimCountModule>(); | ||
171 | m_Dialog = m_scene.RequestModuleInterface<IDialogModule>(); | ||
156 | } | 172 | } |
157 | 173 | ||
158 | public void RemoveRegion(Scene scene) | 174 | public void RemoveRegion(Scene scene) |
159 | { | 175 | { |
160 | // TODO: Also release other event manager listeners here | 176 | // TODO: Release event manager listeners here |
161 | |||
162 | m_scene.EventManager.OnPluginConsole -= EventManagerOnPluginConsole; | ||
163 | m_scene.UnregisterModuleCommander(m_commander.Name); | ||
164 | } | 177 | } |
165 | 178 | ||
166 | // private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason) | 179 | // private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason) |
@@ -168,30 +181,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
168 | // ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y); | 181 | // ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y); |
169 | // reason = "You are not allowed to enter this sim."; | 182 | // reason = "You are not allowed to enter this sim."; |
170 | // return nearestParcel != null; | 183 | // return nearestParcel != null; |
171 | // } | 184 | // } |
172 | |||
173 | /// <summary> | ||
174 | /// Processes commandline input. Do not call directly. | ||
175 | /// </summary> | ||
176 | /// <param name="args">Commandline arguments</param> | ||
177 | protected void EventManagerOnPluginConsole(string[] args) | ||
178 | { | ||
179 | if (args[0] == "land") | ||
180 | { | ||
181 | if (args.Length == 1) | ||
182 | { | ||
183 | m_commander.ProcessConsoleCommand("help", new string[0]); | ||
184 | return; | ||
185 | } | ||
186 | |||
187 | string[] tmpArgs = new string[args.Length - 2]; | ||
188 | int i; | ||
189 | for (i = 2; i < args.Length; i++) | ||
190 | tmpArgs[i - 2] = args[i]; | ||
191 | |||
192 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); | ||
193 | } | ||
194 | } | ||
195 | 185 | ||
196 | void EventManagerOnNewClient(IClientAPI client) | 186 | void EventManagerOnNewClient(IClientAPI client) |
197 | { | 187 | { |
@@ -210,6 +200,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
210 | client.OnParcelInfoRequest += ClientOnParcelInfoRequest; | 200 | client.OnParcelInfoRequest += ClientOnParcelInfoRequest; |
211 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; | 201 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; |
212 | client.OnPreAgentUpdate += ClientOnPreAgentUpdate; | 202 | client.OnPreAgentUpdate += ClientOnPreAgentUpdate; |
203 | client.OnParcelEjectUser += ClientOnParcelEjectUser; | ||
204 | client.OnParcelFreezeUser += ClientOnParcelFreezeUser; | ||
205 | client.OnSetStartLocationRequest += ClientOnSetHome; | ||
206 | |||
213 | 207 | ||
214 | EntityBase presenceEntity; | 208 | EntityBase presenceEntity; |
215 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) | 209 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) |
@@ -293,14 +287,15 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
293 | LandData newData = data.Copy(); | 287 | LandData newData = data.Copy(); |
294 | newData.LocalID = local_id; | 288 | newData.LocalID = local_id; |
295 | 289 | ||
290 | ILandObject land; | ||
296 | lock (m_landList) | 291 | lock (m_landList) |
297 | { | 292 | { |
298 | if (m_landList.ContainsKey(local_id)) | 293 | if (m_landList.TryGetValue(local_id, out land)) |
299 | { | 294 | land.LandData = newData; |
300 | m_landList[local_id].LandData = newData; | ||
301 | m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); | ||
302 | } | ||
303 | } | 295 | } |
296 | |||
297 | if (land != null) | ||
298 | m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, land); | ||
304 | } | 299 | } |
305 | 300 | ||
306 | public bool AllowedForcefulBans | 301 | public bool AllowedForcefulBans |
@@ -319,7 +314,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
319 | { | 314 | { |
320 | m_landList.Clear(); | 315 | m_landList.Clear(); |
321 | m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; | 316 | m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; |
322 | m_landIDList.Initialize(); | 317 | m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; |
323 | } | 318 | } |
324 | } | 319 | } |
325 | 320 | ||
@@ -333,7 +328,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
333 | "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); | 328 | "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); |
334 | 329 | ||
335 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); | 330 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); |
336 | fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); | 331 | fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, |
332 | (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY)); | ||
337 | fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 333 | fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
338 | fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | 334 | fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); |
339 | 335 | ||
@@ -460,8 +456,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
460 | 456 | ||
461 | public void SendLandUpdate(ScenePresence avatar, bool force) | 457 | public void SendLandUpdate(ScenePresence avatar, bool force) |
462 | { | 458 | { |
463 | ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), | 459 | ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), |
464 | (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); | 460 | (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); |
465 | 461 | ||
466 | if (over != null) | 462 | if (over != null) |
467 | { | 463 | { |
@@ -543,16 +539,13 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
543 | /// </summary> | 539 | /// </summary> |
544 | /// <param name="avatar"></param> | 540 | /// <param name="avatar"></param> |
545 | public void EventManagerOnClientMovement(ScenePresence avatar) | 541 | public void EventManagerOnClientMovement(ScenePresence avatar) |
546 | // | ||
547 | { | 542 | { |
548 | ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 543 | Vector3 pos = avatar.AbsolutePosition; |
544 | ILandObject over = GetLandObject(pos.X, pos.Y); | ||
549 | if (over != null) | 545 | if (over != null) |
550 | { | 546 | { |
551 | if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT)) | 547 | if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || pos.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT)) |
552 | { | 548 | avatar.lastKnownAllowedPosition = pos; |
553 | avatar.lastKnownAllowedPosition = | ||
554 | new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); | ||
555 | } | ||
556 | } | 549 | } |
557 | } | 550 | } |
558 | 551 | ||
@@ -611,7 +604,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
611 | /// <summary> | 604 | /// <summary> |
612 | /// Adds a land object to the stored list and adds them to the landIDList to what they own | 605 | /// Adds a land object to the stored list and adds them to the landIDList to what they own |
613 | /// </summary> | 606 | /// </summary> |
614 | /// <param name="new_land">The land object being added</param> | 607 | /// <param name="new_land"> |
608 | /// The land object being added. | ||
609 | /// Will return null if this overlaps with an existing parcel that has not had its bitmap adjusted. | ||
610 | /// </param> | ||
615 | public ILandObject AddLandObject(ILandObject land) | 611 | public ILandObject AddLandObject(ILandObject land) |
616 | { | 612 | { |
617 | ILandObject new_land = land.Copy(); | 613 | ILandObject new_land = land.Copy(); |
@@ -619,34 +615,76 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
619 | // Only now can we add the prim counts to the land object - we rely on the global ID which is generated | 615 | // Only now can we add the prim counts to the land object - we rely on the global ID which is generated |
620 | // as a random UUID inside LandData initialization | 616 | // as a random UUID inside LandData initialization |
621 | if (m_primCountModule != null) | 617 | if (m_primCountModule != null) |
622 | new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID); | 618 | new_land.PrimCounts = m_primCountModule.GetPrimCounts(new_land.LandData.GlobalID); |
623 | 619 | ||
624 | lock (m_landList) | 620 | lock (m_landList) |
625 | { | 621 | { |
626 | int newLandLocalID = ++m_lastLandLocalID; | 622 | int newLandLocalID = m_lastLandLocalID + 1; |
627 | new_land.LandData.LocalID = newLandLocalID; | 623 | new_land.LandData.LocalID = newLandLocalID; |
628 | 624 | ||
629 | bool[,] landBitmap = new_land.GetLandBitmap(); | 625 | bool[,] landBitmap = new_land.GetLandBitmap(); |
630 | for (int x = 0; x < landArrayMax; x++) | 626 | // m_log.DebugFormat("{0} AddLandObject. new_land.bitmapSize=({1},{2}). newLocalID={3}", |
627 | // LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), newLandLocalID); | ||
628 | |||
629 | if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1)) | ||
630 | { | ||
631 | // Going to variable sized regions can cause mismatches | ||
632 | m_log.ErrorFormat("{0} AddLandObject. Added land bitmap different size than region ID map. bitmapSize=({1},{2}), landIDSize=({3},{4})", | ||
633 | LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1) ); | ||
634 | } | ||
635 | else | ||
631 | { | 636 | { |
632 | for (int y = 0; y < landArrayMax; y++) | 637 | // If other land objects still believe that they occupy any parts of the same space, |
638 | // then do not allow the add to proceed. | ||
639 | for (int x = 0; x < landBitmap.GetLength(0); x++) | ||
633 | { | 640 | { |
634 | if (landBitmap[x, y]) | 641 | for (int y = 0; y < landBitmap.GetLength(1); y++) |
635 | { | 642 | { |
636 | // m_log.DebugFormat( | 643 | if (landBitmap[x, y]) |
637 | // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", | 644 | { |
638 | // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); | 645 | int lastRecordedLandId = m_landIDList[x, y]; |
639 | 646 | ||
640 | m_landIDList[x, y] = newLandLocalID; | 647 | if (lastRecordedLandId > 0) |
648 | { | ||
649 | ILandObject lastRecordedLo = m_landList[lastRecordedLandId]; | ||
650 | |||
651 | if (lastRecordedLo.LandBitmap[x, y]) | ||
652 | { | ||
653 | m_log.ErrorFormat( | ||
654 | "{0}: Cannot add parcel \"{1}\", local ID {2} at tile {3},{4} because this is still occupied by parcel \"{5}\", local ID {6} in {7}", | ||
655 | LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y, | ||
656 | lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name); | ||
657 | |||
658 | return null; | ||
659 | } | ||
660 | } | ||
661 | } | ||
662 | } | ||
663 | } | ||
664 | |||
665 | for (int x = 0; x < landBitmap.GetLength(0); x++) | ||
666 | { | ||
667 | for (int y = 0; y < landBitmap.GetLength(1); y++) | ||
668 | { | ||
669 | if (landBitmap[x, y]) | ||
670 | { | ||
671 | // m_log.DebugFormat( | ||
672 | // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", | ||
673 | // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName); | ||
674 | |||
675 | m_landIDList[x, y] = newLandLocalID; | ||
676 | } | ||
641 | } | 677 | } |
642 | } | 678 | } |
643 | } | 679 | } |
644 | 680 | ||
645 | m_landList.Add(newLandLocalID, new_land); | 681 | m_landList.Add(newLandLocalID, new_land); |
682 | m_lastLandLocalID++; | ||
646 | } | 683 | } |
647 | 684 | ||
648 | new_land.ForceUpdateLandInfo(); | 685 | new_land.ForceUpdateLandInfo(); |
649 | m_scene.EventManager.TriggerLandObjectAdded(new_land); | 686 | m_scene.EventManager.TriggerLandObjectAdded(new_land); |
687 | |||
650 | return new_land; | 688 | return new_land; |
651 | } | 689 | } |
652 | 690 | ||
@@ -656,11 +694,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
656 | /// <param name="local_id">Land.localID of the peice of land to remove.</param> | 694 | /// <param name="local_id">Land.localID of the peice of land to remove.</param> |
657 | public void removeLandObject(int local_id) | 695 | public void removeLandObject(int local_id) |
658 | { | 696 | { |
697 | ILandObject land; | ||
659 | lock (m_landList) | 698 | lock (m_landList) |
660 | { | 699 | { |
661 | for (int x = 0; x < 64; x++) | 700 | for (int x = 0; x < m_landIDList.GetLength(0); x++) |
662 | { | 701 | { |
663 | for (int y = 0; y < 64; y++) | 702 | for (int y = 0; y < m_landIDList.GetLength(1); y++) |
664 | { | 703 | { |
665 | if (m_landIDList[x, y] == local_id) | 704 | if (m_landIDList[x, y] == local_id) |
666 | { | 705 | { |
@@ -672,9 +711,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
672 | } | 711 | } |
673 | } | 712 | } |
674 | 713 | ||
675 | m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].LandData.GlobalID); | 714 | land = m_landList[local_id]; |
676 | m_landList.Remove(local_id); | 715 | m_landList.Remove(local_id); |
677 | } | 716 | } |
717 | |||
718 | m_scene.EventManager.TriggerLandObjectRemoved(land.LandData.GlobalID); | ||
678 | } | 719 | } |
679 | 720 | ||
680 | /// <summary> | 721 | /// <summary> |
@@ -682,21 +723,27 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
682 | /// </summary> | 723 | /// </summary> |
683 | public void Clear(bool setupDefaultParcel) | 724 | public void Clear(bool setupDefaultParcel) |
684 | { | 725 | { |
726 | List<ILandObject> parcels; | ||
685 | lock (m_landList) | 727 | lock (m_landList) |
686 | { | 728 | { |
687 | foreach (ILandObject lo in m_landList.Values) | 729 | parcels = new List<ILandObject>(m_landList.Values); |
688 | { | 730 | } |
689 | //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); | 731 | |
690 | m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); | 732 | foreach (ILandObject lo in parcels) |
691 | } | 733 | { |
734 | //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); | ||
735 | m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); | ||
736 | } | ||
692 | 737 | ||
738 | lock (m_landList) | ||
739 | { | ||
693 | m_landList.Clear(); | 740 | m_landList.Clear(); |
694 | 741 | ||
695 | ResetSimLandObjects(); | 742 | ResetSimLandObjects(); |
696 | |||
697 | if (setupDefaultParcel) | ||
698 | CreateDefaultParcel(); | ||
699 | } | 743 | } |
744 | |||
745 | if (setupDefaultParcel) | ||
746 | CreateDefaultParcel(); | ||
700 | } | 747 | } |
701 | 748 | ||
702 | private void performFinalLandJoin(ILandObject master, ILandObject slave) | 749 | private void performFinalLandJoin(ILandObject master, ILandObject slave) |
@@ -704,9 +751,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
704 | bool[,] landBitmapSlave = slave.GetLandBitmap(); | 751 | bool[,] landBitmapSlave = slave.GetLandBitmap(); |
705 | lock (m_landList) | 752 | lock (m_landList) |
706 | { | 753 | { |
707 | for (int x = 0; x < 64; x++) | 754 | for (int x = 0; x < landBitmapSlave.GetLength(0); x++) |
708 | { | 755 | { |
709 | for (int y = 0; y < 64; y++) | 756 | for (int y = 0; y < landBitmapSlave.GetLength(1); y++) |
710 | { | 757 | { |
711 | if (landBitmapSlave[x, y]) | 758 | if (landBitmapSlave[x, y]) |
712 | { | 759 | { |
@@ -740,23 +787,28 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
740 | /// <returns>Land object at the point supplied</returns> | 787 | /// <returns>Land object at the point supplied</returns> |
741 | public ILandObject GetLandObject(float x_float, float y_float) | 788 | public ILandObject GetLandObject(float x_float, float y_float) |
742 | { | 789 | { |
790 | return GetLandObject((int)x_float, (int)y_float, true /* returnNullIfLandObjectNotFound */); | ||
791 | /* | ||
743 | int x; | 792 | int x; |
744 | int y; | 793 | int y; |
745 | 794 | ||
746 | if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) | 795 | if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0) |
747 | return null; | 796 | return null; |
748 | 797 | ||
749 | try | 798 | try |
750 | { | 799 | { |
751 | x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / 4.0)); | 800 | x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit)); |
752 | y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / 4.0)); | 801 | y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit)); |
753 | } | 802 | } |
754 | catch (OverflowException) | 803 | catch (OverflowException) |
755 | { | 804 | { |
756 | return null; | 805 | return null; |
757 | } | 806 | } |
758 | 807 | ||
759 | if (x >= 64 || y >= 64 || x < 0 || y < 0) | 808 | if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit) |
809 | || y >= (m_scene.RegionInfo.RegionSizeY / landUnit) | ||
810 | || x < 0 | ||
811 | || y < 0) | ||
760 | { | 812 | { |
761 | return null; | 813 | return null; |
762 | } | 814 | } |
@@ -772,38 +824,70 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
772 | // m_log.DebugFormat( | 824 | // m_log.DebugFormat( |
773 | // "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}", | 825 | // "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}", |
774 | // x, y, m_scene.RegionInfo.RegionName); | 826 | // x, y, m_scene.RegionInfo.RegionName); |
775 | 827 | ||
776 | if (m_landList.ContainsKey(m_landIDList[x, y])) | 828 | try |
777 | return m_landList[m_landIDList[x, y]]; | 829 | { |
830 | if (m_landList.ContainsKey(m_landIDList[x, y])) | ||
831 | return m_landList[m_landIDList[x, y]]; | ||
832 | } | ||
833 | catch (Exception e) | ||
834 | { | ||
835 | m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})", | ||
836 | LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1)); | ||
837 | } | ||
778 | 838 | ||
779 | return null; | 839 | return null; |
780 | } | 840 | } |
841 | */ | ||
781 | } | 842 | } |
782 | 843 | ||
844 | // Public entry. | ||
845 | // Throws exception if land object is not found | ||
783 | public ILandObject GetLandObject(int x, int y) | 846 | public ILandObject GetLandObject(int x, int y) |
784 | { | 847 | { |
785 | if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) | 848 | return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */); |
849 | } | ||
850 | |||
851 | /// <summary> | ||
852 | /// Given a region position, return the parcel land object for that location | ||
853 | /// </summary> | ||
854 | /// <returns> | ||
855 | /// The land object. | ||
856 | /// </returns> | ||
857 | /// <param name='x'></param> | ||
858 | /// <param name='y'></param> | ||
859 | /// <param name='returnNullIfLandObjectNotFound'> | ||
860 | /// Return null if the land object requested is not within the region's bounds. | ||
861 | /// </param> | ||
862 | private ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds) | ||
863 | { | ||
864 | if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0) | ||
786 | { | 865 | { |
787 | // These exceptions here will cause a lot of complaints from the users specifically because | 866 | // These exceptions here will cause a lot of complaints from the users specifically because |
788 | // they happen every time at border crossings | 867 | // they happen every time at border crossings |
789 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); | 868 | if (returnNullIfLandObjectOutsideBounds) |
790 | } | ||
791 | |||
792 | lock (m_landIDList) | ||
793 | { | ||
794 | try | ||
795 | { | ||
796 | return m_landList[m_landIDList[x / 4, y / 4]]; | ||
797 | } | ||
798 | catch (IndexOutOfRangeException) | ||
799 | { | ||
800 | // m_log.WarnFormat( | ||
801 | // "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}", | ||
802 | // x, y, m_scene.RegionInfo.RegionName); | ||
803 | |||
804 | return null; | 869 | return null; |
805 | } | 870 | else |
871 | throw new Exception( | ||
872 | String.Format("{0} GetLandObject for non-existent position. Region={1}, pos=<{2},{3}", | ||
873 | LogHeader, m_scene.RegionInfo.RegionName, x, y) | ||
874 | ); | ||
806 | } | 875 | } |
876 | |||
877 | return m_landList[m_landIDList[x / 4, y / 4]]; | ||
878 | } | ||
879 | |||
880 | // Create a 'parcel is here' bitmap for the parcel identified by the passed landID | ||
881 | private bool[,] CreateBitmapForID(int landID) | ||
882 | { | ||
883 | bool[,] ret = new bool[m_landIDList.GetLength(0), m_landIDList.GetLength(1)]; | ||
884 | |||
885 | for (int xx = 0; xx < m_landIDList.GetLength(0); xx++) | ||
886 | for (int yy = 0; yy < m_landIDList.GetLength(0); yy++) | ||
887 | if (m_landIDList[xx, yy] == landID) | ||
888 | ret[xx, yy] = true; | ||
889 | |||
890 | return ret; | ||
807 | } | 891 | } |
808 | 892 | ||
809 | #endregion | 893 | #endregion |
@@ -973,8 +1057,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
973 | 1057 | ||
974 | //Now add the new land object | 1058 | //Now add the new land object |
975 | ILandObject result = AddLandObject(newLand); | 1059 | ILandObject result = AddLandObject(newLand); |
976 | UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); | 1060 | |
977 | result.SendLandUpdateToAvatarsOverMe(); | 1061 | if (result != null) |
1062 | { | ||
1063 | UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); | ||
1064 | result.SendLandUpdateToAvatarsOverMe(); | ||
1065 | } | ||
978 | } | 1066 | } |
979 | 1067 | ||
980 | /// <summary> | 1068 | /// <summary> |
@@ -1055,96 +1143,164 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1055 | 1143 | ||
1056 | #region Parcel Updating | 1144 | #region Parcel Updating |
1057 | 1145 | ||
1146 | // Send parcel layer info for the whole region | ||
1147 | public void SendParcelOverlay(IClientAPI remote_client) | ||
1148 | { | ||
1149 | SendParcelOverlay(remote_client, 0, 0, (int)Constants.MaximumRegionSize); | ||
1150 | } | ||
1151 | |||
1058 | /// <summary> | 1152 | /// <summary> |
1059 | /// Where we send the ParcelOverlay packet to the client | 1153 | /// Send the parcel overlay blocks to the client. We send the overlay packets |
1154 | /// around a location and limited by the 'parcelLayerViewDistance'. This number | ||
1155 | /// is usually 128 and the code is arranged so it sends all the parcel overlay | ||
1156 | /// information for a whole region if the region is legacy sized (256x256). If | ||
1157 | /// the region is larger, only the parcel layer information is sent around | ||
1158 | /// the point specified. This reduces the problem of parcel layer information | ||
1159 | /// blocks increasing exponentially as region size increases. | ||
1060 | /// </summary> | 1160 | /// </summary> |
1061 | /// <param name="remote_client">The object representing the client</param> | 1161 | /// <param name="remote_client">The object representing the client</param> |
1062 | public void SendParcelOverlay(IClientAPI remote_client) | 1162 | /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param> |
1163 | /// <param name="yPlace">y position in the region to send surrounding parcel layer info</param> | ||
1164 | /// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param> | ||
1165 | private void SendParcelOverlay(IClientAPI remote_client, int xPlace, int yPlace, int layerViewDistance) | ||
1063 | { | 1166 | { |
1064 | const int LAND_BLOCKS_PER_PACKET = 1024; | 1167 | const int LAND_BLOCKS_PER_PACKET = 1024; |
1065 | 1168 | ||
1066 | byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | 1169 | byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; |
1067 | int byteArrayCount = 0; | 1170 | int byteArrayCount = 0; |
1068 | int sequenceID = 0; | 1171 | int sequenceID = 0; |
1069 | int blockmeters = 4 * (int) Constants.RegionSize/(int)Constants.TerrainPatchSize; | ||
1070 | 1172 | ||
1173 | int xLow = 0; | ||
1174 | int xHigh = (int)m_scene.RegionInfo.RegionSizeX; | ||
1175 | int yLow = 0; | ||
1176 | int yHigh = (int)m_scene.RegionInfo.RegionSizeY; | ||
1071 | 1177 | ||
1072 | for (int y = 0; y < blockmeters; y++) | 1178 | if (shouldLimitParcelLayerInfoToViewDistance) |
1073 | { | 1179 | { |
1074 | for (int x = 0; x < blockmeters; x++) | 1180 | // Compute view distance around the given point |
1181 | int txLow = xPlace - layerViewDistance; | ||
1182 | int txHigh = xPlace + layerViewDistance; | ||
1183 | // If the distance is outside the region area, move the view distance to ba all in the region | ||
1184 | if (txLow < xLow) | ||
1185 | { | ||
1186 | txLow = xLow; | ||
1187 | txHigh = Math.Min(yLow + (layerViewDistance * 2), xHigh); | ||
1188 | } | ||
1189 | if (txHigh > xHigh) | ||
1075 | { | 1190 | { |
1076 | byte tempByte = 0; //This represents the byte for the current 4x4 | 1191 | txLow = Math.Max(xLow, xHigh - (layerViewDistance * 2)); |
1192 | txHigh = xHigh; | ||
1193 | } | ||
1194 | xLow = txLow; | ||
1195 | xHigh = txHigh; | ||
1077 | 1196 | ||
1078 | ILandObject currentParcelBlock = GetLandObject(x * 4, y * 4); | 1197 | int tyLow = yPlace - layerViewDistance; |
1198 | int tyHigh = yPlace + layerViewDistance; | ||
1199 | if (tyLow < yLow) | ||
1200 | { | ||
1201 | tyLow = yLow; | ||
1202 | tyHigh = Math.Min(yLow + (layerViewDistance * 2), yHigh); | ||
1203 | } | ||
1204 | if (tyHigh > yHigh) | ||
1205 | { | ||
1206 | tyLow = Math.Max(yLow, yHigh - (layerViewDistance * 2)); | ||
1207 | tyHigh = yHigh; | ||
1208 | } | ||
1209 | yLow = tyLow; | ||
1210 | yHigh = tyHigh; | ||
1211 | } | ||
1212 | // m_log.DebugFormat("{0} SendParcelOverlay: place=<{1},{2}>, vDist={3}, xLH=<{4},{5}, yLH=<{6},{7}>", | ||
1213 | // LogHeader, xPlace, yPlace, layerViewDistance, xLow, xHigh, yLow, yHigh); | ||
1079 | 1214 | ||
1080 | if (currentParcelBlock != null) | 1215 | // Layer data is in landUnit (4m) chunks |
1216 | for (int y = yLow; y < yHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) | ||
1217 | { | ||
1218 | for (int x = xLow; x < xHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) | ||
1219 | { | ||
1220 | byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * LandUnit, y * LandUnit), x, y, remote_client); | ||
1221 | byteArrayCount++; | ||
1222 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) | ||
1081 | { | 1223 | { |
1082 | if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) | 1224 | // m_log.DebugFormat("{0} SendParcelOverlay, sending packet, bytes={1}", LogHeader, byteArray.Length); |
1083 | { | 1225 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); |
1084 | //Owner Flag | 1226 | byteArrayCount = 0; |
1085 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); | 1227 | sequenceID++; |
1086 | } | 1228 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; |
1087 | else if (currentParcelBlock.LandData.SalePrice > 0 && | 1229 | } |
1088 | (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || | ||
1089 | currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) | ||
1090 | { | ||
1091 | //Sale Flag | ||
1092 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE); | ||
1093 | } | ||
1094 | else if (currentParcelBlock.LandData.OwnerID == UUID.Zero) | ||
1095 | { | ||
1096 | //Public Flag | ||
1097 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC); | ||
1098 | } | ||
1099 | else | ||
1100 | { | ||
1101 | //Other Flag | ||
1102 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER); | ||
1103 | } | ||
1104 | 1230 | ||
1105 | //Now for border control | 1231 | } |
1232 | } | ||
1106 | 1233 | ||
1107 | ILandObject westParcel = null; | 1234 | if (byteArrayCount != 0) |
1108 | ILandObject southParcel = null; | 1235 | { |
1109 | if (x > 0) | 1236 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); |
1110 | { | 1237 | // m_log.DebugFormat("{0} SendParcelOverlay, complete sending packet, bytes={1}", LogHeader, byteArray.Length); |
1111 | westParcel = GetLandObject((x - 1) * 4, y * 4); | 1238 | } |
1112 | } | 1239 | } |
1113 | if (y > 0) | ||
1114 | { | ||
1115 | southParcel = GetLandObject(x * 4, (y - 1) * 4); | ||
1116 | } | ||
1117 | 1240 | ||
1118 | if (x == 0) | 1241 | private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client) |
1119 | { | 1242 | { |
1120 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); | 1243 | byte tempByte = 0; //This represents the byte for the current 4x4 |
1121 | } | ||
1122 | else if (westParcel != null && westParcel != currentParcelBlock) | ||
1123 | { | ||
1124 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); | ||
1125 | } | ||
1126 | 1244 | ||
1127 | if (y == 0) | 1245 | if (currentParcelBlock != null) |
1128 | { | 1246 | { |
1129 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); | 1247 | if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) |
1130 | } | 1248 | { |
1131 | else if (southParcel != null && southParcel != currentParcelBlock) | 1249 | //Owner Flag |
1132 | { | 1250 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); |
1133 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); | 1251 | } |
1134 | } | 1252 | else if (currentParcelBlock.LandData.SalePrice > 0 && |
1253 | (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || | ||
1254 | currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) | ||
1255 | { | ||
1256 | //Sale Flag | ||
1257 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_IS_FOR_SALE); | ||
1258 | } | ||
1259 | else if (currentParcelBlock.LandData.OwnerID == UUID.Zero) | ||
1260 | { | ||
1261 | //Public Flag | ||
1262 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_PUBLIC); | ||
1263 | } | ||
1264 | else | ||
1265 | { | ||
1266 | //Other Flag | ||
1267 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_OTHER); | ||
1268 | } | ||
1135 | 1269 | ||
1136 | byteArray[byteArrayCount] = tempByte; | 1270 | //Now for border control |
1137 | byteArrayCount++; | 1271 | |
1138 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) | 1272 | ILandObject westParcel = null; |
1139 | { | 1273 | ILandObject southParcel = null; |
1140 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); | 1274 | if (x > 0) |
1141 | byteArrayCount = 0; | 1275 | { |
1142 | sequenceID++; | 1276 | westParcel = GetLandObject((x - 1) * LandUnit, y * LandUnit); |
1143 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | 1277 | } |
1144 | } | 1278 | if (y > 0) |
1145 | } | 1279 | { |
1280 | southParcel = GetLandObject(x * LandUnit, (y - 1) * LandUnit); | ||
1281 | } | ||
1282 | |||
1283 | if (x == 0) | ||
1284 | { | ||
1285 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); | ||
1286 | } | ||
1287 | else if (westParcel != null && westParcel != currentParcelBlock) | ||
1288 | { | ||
1289 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST); | ||
1146 | } | 1290 | } |
1291 | |||
1292 | if (y == 0) | ||
1293 | { | ||
1294 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); | ||
1295 | } | ||
1296 | else if (southParcel != null && southParcel != currentParcelBlock) | ||
1297 | { | ||
1298 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); | ||
1299 | } | ||
1300 | |||
1147 | } | 1301 | } |
1302 | |||
1303 | return tempByte; | ||
1148 | } | 1304 | } |
1149 | 1305 | ||
1150 | public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, | 1306 | public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, |
@@ -1182,7 +1338,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1182 | temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client); | 1338 | temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client); |
1183 | } | 1339 | } |
1184 | 1340 | ||
1185 | SendParcelOverlay(remote_client); | 1341 | // Also send the layer data around the point of interest |
1342 | SendParcelOverlay(remote_client, (start_x + end_x) / 2, (start_y + end_y) / 2, parcelLayerViewDistance); | ||
1186 | } | 1343 | } |
1187 | 1344 | ||
1188 | public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) | 1345 | public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) |
@@ -1254,6 +1411,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1254 | 1411 | ||
1255 | m_scene.ForEachClient(SendParcelOverlay); | 1412 | m_scene.ForEachClient(SendParcelOverlay); |
1256 | land.SendLandUpdateToClient(true, remote_client); | 1413 | land.SendLandUpdateToClient(true, remote_client); |
1414 | UpdateLandObject(land.LandData.LocalID, land.LandData); | ||
1257 | } | 1415 | } |
1258 | } | 1416 | } |
1259 | } | 1417 | } |
@@ -1274,8 +1432,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1274 | land.LandData.GroupID = UUID.Zero; | 1432 | land.LandData.GroupID = UUID.Zero; |
1275 | land.LandData.IsGroupOwned = false; | 1433 | land.LandData.IsGroupOwned = false; |
1276 | land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); | 1434 | land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); |
1435 | |||
1277 | m_scene.ForEachClient(SendParcelOverlay); | 1436 | m_scene.ForEachClient(SendParcelOverlay); |
1278 | land.SendLandUpdateToClient(true, remote_client); | 1437 | land.SendLandUpdateToClient(true, remote_client); |
1438 | UpdateLandObject(land.LandData.LocalID, land.LandData); | ||
1279 | } | 1439 | } |
1280 | } | 1440 | } |
1281 | } | 1441 | } |
@@ -1302,6 +1462,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1302 | 1462 | ||
1303 | m_scene.ForEachClient(SendParcelOverlay); | 1463 | m_scene.ForEachClient(SendParcelOverlay); |
1304 | land.SendLandUpdateToClient(true, remote_client); | 1464 | land.SendLandUpdateToClient(true, remote_client); |
1465 | UpdateLandObject(land.LandData.LocalID, land.LandData); | ||
1305 | } | 1466 | } |
1306 | } | 1467 | } |
1307 | } | 1468 | } |
@@ -1382,19 +1543,78 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1382 | 1543 | ||
1383 | #region Land Object From Storage Functions | 1544 | #region Land Object From Storage Functions |
1384 | 1545 | ||
1385 | public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) | 1546 | private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) |
1386 | { | 1547 | { |
1387 | // m_log.DebugFormat( | 1548 | // m_log.DebugFormat( |
1388 | // "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); | 1549 | // "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); |
1389 | 1550 | ||
1390 | for (int i = 0; i < data.Count; i++) | 1551 | // Prevent race conditions from any auto-creation of new parcels for varregions whilst we are still loading |
1391 | IncomingLandObjectFromStorage(data[i]); | 1552 | // the existing parcels. |
1553 | lock (m_landList) | ||
1554 | { | ||
1555 | for (int i = 0; i < data.Count; i++) | ||
1556 | IncomingLandObjectFromStorage(data[i]); | ||
1557 | |||
1558 | // Layer data is in landUnit (4m) chunks | ||
1559 | for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) | ||
1560 | { | ||
1561 | for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) | ||
1562 | { | ||
1563 | if (m_landIDList[x, y] == 0) | ||
1564 | { | ||
1565 | if (m_landList.Count == 1) | ||
1566 | { | ||
1567 | m_log.DebugFormat( | ||
1568 | "[{0}]: Auto-extending land parcel as landID at {1},{2} is 0 and only one land parcel is present in {3}", | ||
1569 | LogHeader, x, y, m_scene.Name); | ||
1570 | |||
1571 | int onlyParcelID = 0; | ||
1572 | ILandObject onlyLandObject = null; | ||
1573 | foreach (KeyValuePair<int, ILandObject> kvp in m_landList) | ||
1574 | { | ||
1575 | onlyParcelID = kvp.Key; | ||
1576 | onlyLandObject = kvp.Value; | ||
1577 | break; | ||
1578 | } | ||
1579 | |||
1580 | // There is only one parcel. Grow it to fill all the unallocated spaces. | ||
1581 | for (int xx = 0; xx < m_landIDList.GetLength(0); xx++) | ||
1582 | for (int yy = 0; yy < m_landIDList.GetLength(1); yy++) | ||
1583 | if (m_landIDList[xx, yy] == 0) | ||
1584 | m_landIDList[xx, yy] = onlyParcelID; | ||
1585 | |||
1586 | onlyLandObject.LandBitmap = CreateBitmapForID(onlyParcelID); | ||
1587 | } | ||
1588 | else if (m_landList.Count > 1) | ||
1589 | { | ||
1590 | m_log.DebugFormat( | ||
1591 | "{0}: Auto-creating land parcel as landID at {1},{2} is 0 and more than one land parcel is present in {3}", | ||
1592 | LogHeader, x, y, m_scene.Name); | ||
1593 | |||
1594 | // There are several other parcels so we must create a new one for the unassigned space | ||
1595 | ILandObject newLand = new LandObject(UUID.Zero, false, m_scene); | ||
1596 | // Claim all the unclaimed "0" ids | ||
1597 | newLand.SetLandBitmap(CreateBitmapForID(0)); | ||
1598 | newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
1599 | newLand.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | ||
1600 | newLand = AddLandObject(newLand); | ||
1601 | } | ||
1602 | else | ||
1603 | { | ||
1604 | // We should never reach this point as the separate code path when no land data exists should have fired instead. | ||
1605 | m_log.WarnFormat( | ||
1606 | "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present", | ||
1607 | LogHeader, m_scene.Name); | ||
1608 | } | ||
1609 | } | ||
1610 | } | ||
1611 | } | ||
1612 | } | ||
1392 | } | 1613 | } |
1393 | 1614 | ||
1394 | public void IncomingLandObjectFromStorage(LandData data) | 1615 | private void IncomingLandObjectFromStorage(LandData data) |
1395 | { | 1616 | { |
1396 | ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); | 1617 | ILandObject new_land = new LandObject(data, m_scene); |
1397 | new_land.LandData = data.Copy(); | ||
1398 | new_land.SetLandBitmapFromByteArray(); | 1618 | new_land.SetLandBitmapFromByteArray(); |
1399 | AddLandObject(new_land); | 1619 | AddLandObject(new_land); |
1400 | } | 1620 | } |
@@ -1409,7 +1629,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1409 | m_landList.TryGetValue(localID, out selectedParcel); | 1629 | m_landList.TryGetValue(localID, out selectedParcel); |
1410 | } | 1630 | } |
1411 | 1631 | ||
1412 | if (selectedParcel == null) return; | 1632 | if (selectedParcel == null) |
1633 | return; | ||
1413 | 1634 | ||
1414 | selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient); | 1635 | selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient); |
1415 | } | 1636 | } |
@@ -1417,7 +1638,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1417 | { | 1638 | { |
1418 | if (returnType != 1) | 1639 | if (returnType != 1) |
1419 | { | 1640 | { |
1420 | m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: unknown return type {0}", returnType); | 1641 | m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: unknown return type {0}", returnType); |
1421 | return; | 1642 | return; |
1422 | } | 1643 | } |
1423 | 1644 | ||
@@ -1437,14 +1658,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1437 | } | 1658 | } |
1438 | else | 1659 | else |
1439 | { | 1660 | { |
1440 | m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: unknown object {0}", groupID); | 1661 | m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: unknown object {0}", groupID); |
1441 | } | 1662 | } |
1442 | } | 1663 | } |
1443 | 1664 | ||
1444 | int num = 0; | 1665 | int num = 0; |
1445 | foreach (HashSet<SceneObjectGroup> objs in returns.Values) | 1666 | foreach (HashSet<SceneObjectGroup> objs in returns.Values) |
1446 | num += objs.Count; | 1667 | num += objs.Count; |
1447 | m_log.DebugFormat("[LAND MANAGEMENT MODULE] Returning {0} specific object(s)", num); | 1668 | m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Returning {0} specific object(s)", num); |
1448 | 1669 | ||
1449 | foreach (HashSet<SceneObjectGroup> objs in returns.Values) | 1670 | foreach (HashSet<SceneObjectGroup> objs in returns.Values) |
1450 | { | 1671 | { |
@@ -1455,7 +1676,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1455 | } | 1676 | } |
1456 | else | 1677 | else |
1457 | { | 1678 | { |
1458 | m_log.WarnFormat("[LAND MANAGEMENT MODULE] ReturnObjectsInParcel: not permitted to return {0} object(s) belonging to user {1}", | 1679 | m_log.WarnFormat("[LAND MANAGEMENT MODULE]: ReturnObjectsInParcel: not permitted to return {0} object(s) belonging to user {1}", |
1459 | objs2.Count, objs2[0].OwnerID); | 1680 | objs2.Count, objs2[0].OwnerID); |
1460 | } | 1681 | } |
1461 | } | 1682 | } |
@@ -1464,11 +1685,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1464 | 1685 | ||
1465 | public void EventManagerOnNoLandDataFromStorage() | 1686 | public void EventManagerOnNoLandDataFromStorage() |
1466 | { | 1687 | { |
1467 | lock (m_landList) | 1688 | ResetSimLandObjects(); |
1468 | { | 1689 | CreateDefaultParcel(); |
1469 | ResetSimLandObjects(); | ||
1470 | CreateDefaultParcel(); | ||
1471 | } | ||
1472 | } | 1690 | } |
1473 | 1691 | ||
1474 | #endregion | 1692 | #endregion |
@@ -1694,7 +1912,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1694 | { | 1912 | { |
1695 | // most likely still cached from building the extLandData entry | 1913 | // most likely still cached from building the extLandData entry |
1696 | uint x = 0, y = 0; | 1914 | uint x = 0, y = 0; |
1697 | Utils.LongToUInts(data.RegionHandle, out x, out y); | 1915 | Util.RegionHandleToWorldLoc(data.RegionHandle, out x, out y); |
1698 | info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); | 1916 | info = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); |
1699 | } | 1917 | } |
1700 | // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. | 1918 | // we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark. |
@@ -1730,66 +1948,332 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1730 | UpdateLandObject(localID, land.LandData); | 1948 | UpdateLandObject(localID, land.LandData); |
1731 | } | 1949 | } |
1732 | 1950 | ||
1733 | protected void InstallInterfaces() | 1951 | Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); |
1952 | |||
1953 | public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) | ||
1954 | { | ||
1955 | ScenePresence targetAvatar = null; | ||
1956 | ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar); | ||
1957 | ScenePresence parcelManager = null; | ||
1958 | ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); | ||
1959 | System.Threading.Timer Timer; | ||
1960 | |||
1961 | if (targetAvatar.UserLevel == 0) | ||
1962 | { | ||
1963 | ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); | ||
1964 | if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) | ||
1965 | return; | ||
1966 | if (flags == 0) | ||
1967 | { | ||
1968 | targetAvatar.AllowMovement = false; | ||
1969 | targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world."); | ||
1970 | parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen."); | ||
1971 | System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen); | ||
1972 | Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0); | ||
1973 | Timers.Add(targetAvatar.UUID, Timer); | ||
1974 | } | ||
1975 | else | ||
1976 | { | ||
1977 | targetAvatar.AllowMovement = true; | ||
1978 | targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you."); | ||
1979 | parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen."); | ||
1980 | Timers.TryGetValue(targetAvatar.UUID, out Timer); | ||
1981 | Timers.Remove(targetAvatar.UUID); | ||
1982 | Timer.Dispose(); | ||
1983 | } | ||
1984 | } | ||
1985 | } | ||
1986 | |||
1987 | private void OnEndParcelFrozen(object avatar) | ||
1734 | { | 1988 | { |
1735 | Command clearCommand | 1989 | ScenePresence targetAvatar = (ScenePresence)avatar; |
1736 | = new Command("clear", CommandIntentions.COMMAND_HAZARDOUS, ClearCommand, "Clears all the parcels from the region."); | 1990 | targetAvatar.AllowMovement = true; |
1737 | Command showCommand | 1991 | System.Threading.Timer Timer; |
1738 | = new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowParcelsCommand, "Shows all parcels on the region."); | 1992 | Timers.TryGetValue(targetAvatar.UUID, out Timer); |
1993 | Timers.Remove(targetAvatar.UUID); | ||
1994 | targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); | ||
1995 | } | ||
1996 | |||
1997 | public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) | ||
1998 | { | ||
1999 | ScenePresence targetAvatar = null; | ||
2000 | ScenePresence parcelManager = null; | ||
2001 | |||
2002 | // Must have presences | ||
2003 | if (!m_scene.TryGetScenePresence(target, out targetAvatar) || | ||
2004 | !m_scene.TryGetScenePresence(client.AgentId, out parcelManager)) | ||
2005 | return; | ||
2006 | |||
2007 | // Cannot eject estate managers or gods | ||
2008 | if (m_scene.Permissions.IsAdministrator(target)) | ||
2009 | return; | ||
2010 | |||
2011 | // Check if you even have permission to do this | ||
2012 | ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); | ||
2013 | if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && | ||
2014 | !m_scene.Permissions.IsAdministrator(client.AgentId)) | ||
2015 | return; | ||
2016 | Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); | ||
2017 | |||
2018 | targetAvatar.TeleportWithMomentum(pos, null); | ||
2019 | targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); | ||
2020 | parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); | ||
1739 | 2021 | ||
1740 | m_commander.RegisterCommand("clear", clearCommand); | 2022 | if ((flags & 1) != 0) // Ban TODO: Remove magic number |
1741 | m_commander.RegisterCommand("show", showCommand); | 2023 | { |
2024 | LandAccessEntry entry = new LandAccessEntry(); | ||
2025 | entry.AgentID = targetAvatar.UUID; | ||
2026 | entry.Flags = AccessList.Ban; | ||
2027 | entry.Expires = 0; // Perm | ||
1742 | 2028 | ||
1743 | // Add this to our scene so scripts can call these functions | 2029 | land.LandData.ParcelAccessList.Add(entry); |
1744 | m_scene.RegisterModuleCommander(m_commander); | 2030 | } |
2031 | } | ||
2032 | |||
2033 | /// <summary> | ||
2034 | /// Sets the Home Point. The LoginService uses this to know where to put a user when they log-in | ||
2035 | /// </summary> | ||
2036 | /// <param name="remoteClient"></param> | ||
2037 | /// <param name="regionHandle"></param> | ||
2038 | /// <param name="position"></param> | ||
2039 | /// <param name="lookAt"></param> | ||
2040 | /// <param name="flags"></param> | ||
2041 | public virtual void ClientOnSetHome(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) | ||
2042 | { | ||
2043 | // Let's find the parcel in question | ||
2044 | ILandObject land = landChannel.GetLandObject(position); | ||
2045 | if (land == null || m_scene.GridUserService == null) | ||
2046 | { | ||
2047 | m_Dialog.SendAlertToUser(remoteClient, "Set Home request failed."); | ||
2048 | return; | ||
2049 | } | ||
2050 | |||
2051 | // Gather some data | ||
2052 | ulong gpowers = remoteClient.GetGroupPowers(land.LandData.GroupID); | ||
2053 | SceneObjectGroup telehub = null; | ||
2054 | if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero) | ||
2055 | // Does the telehub exist in the scene? | ||
2056 | telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); | ||
2057 | |||
2058 | // Can the user set home here? | ||
2059 | if (// Required: local user; foreign users cannot set home | ||
2060 | m_scene.UserManagementModule.IsLocalGridUser(remoteClient.AgentId) && | ||
2061 | (// (a) gods and land managers can set home | ||
2062 | m_scene.Permissions.IsAdministrator(remoteClient.AgentId) || | ||
2063 | m_scene.Permissions.IsGod(remoteClient.AgentId) || | ||
2064 | // (b) land owners can set home | ||
2065 | remoteClient.AgentId == land.LandData.OwnerID || | ||
2066 | // (c) members of the land-associated group in roles that can set home | ||
2067 | ((gpowers & (ulong)GroupPowers.AllowSetHome) == (ulong)GroupPowers.AllowSetHome) || | ||
2068 | // (d) parcels with telehubs can be the home of anyone | ||
2069 | (telehub != null && land.ContainsPoint((int)telehub.AbsolutePosition.X, (int)telehub.AbsolutePosition.Y)))) | ||
2070 | { | ||
2071 | string userId; | ||
2072 | UUID test; | ||
2073 | if (!m_scene.UserManagementModule.GetUserUUI(remoteClient.AgentId, out userId)) | ||
2074 | { | ||
2075 | /* Do not set a home position in this grid for a HG visitor */ | ||
2076 | m_Dialog.SendAlertToUser(remoteClient, "Set Home request failed. (User Lookup)"); | ||
2077 | } | ||
2078 | else if (!UUID.TryParse(userId, out test)) | ||
2079 | { | ||
2080 | m_Dialog.SendAlertToUser(remoteClient, "Set Home request failed. (HG visitor)"); | ||
2081 | } | ||
2082 | else if (m_scene.GridUserService.SetHome(userId, land.RegionUUID, position, lookAt)) | ||
2083 | { | ||
2084 | // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. | ||
2085 | m_Dialog.SendAlertToUser(remoteClient, "Home position set."); | ||
2086 | } | ||
2087 | else | ||
2088 | { | ||
2089 | m_Dialog.SendAlertToUser(remoteClient, "Set Home request failed."); | ||
2090 | } | ||
2091 | } | ||
2092 | else | ||
2093 | m_Dialog.SendAlertToUser(remoteClient, "You are not allowed to set your home location in this parcel."); | ||
2094 | } | ||
2095 | |||
2096 | protected void RegisterCommands() | ||
2097 | { | ||
2098 | ICommands commands = MainConsole.Instance.Commands; | ||
2099 | |||
2100 | commands.AddCommand( | ||
2101 | "Land", false, "land clear", | ||
2102 | "land clear", | ||
2103 | "Clear all the parcels from the region.", | ||
2104 | "Command will ask for confirmation before proceeding.", | ||
2105 | HandleClearCommand); | ||
2106 | |||
2107 | commands.AddCommand( | ||
2108 | "Land", false, "land show", | ||
2109 | "land show [<local-land-id>]", | ||
2110 | "Show information about the parcels on the region.", | ||
2111 | "If no local land ID is given, then summary information about all the parcels is shown.\n" | ||
2112 | + "If a local land ID is given then full information about that parcel is shown.", | ||
2113 | HandleShowCommand); | ||
1745 | } | 2114 | } |
1746 | 2115 | ||
1747 | protected void ClearCommand(Object[] args) | 2116 | protected void HandleClearCommand(string module, string[] args) |
1748 | { | 2117 | { |
2118 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) | ||
2119 | return; | ||
2120 | |||
1749 | string response = MainConsole.Instance.CmdPrompt( | 2121 | string response = MainConsole.Instance.CmdPrompt( |
1750 | string.Format( | 2122 | string.Format( |
1751 | "Are you sure that you want to clear all land parcels from {0} (y or n)", | 2123 | "Are you sure that you want to clear all land parcels from {0} (y or n)", m_scene.Name), |
1752 | m_scene.RegionInfo.RegionName), | ||
1753 | "n"); | 2124 | "n"); |
1754 | 2125 | ||
1755 | if (response.ToLower() == "y") | 2126 | if (response.ToLower() == "y") |
1756 | { | 2127 | { |
1757 | Clear(true); | 2128 | Clear(true); |
1758 | MainConsole.Instance.OutputFormat("Cleared all parcels from {0}", m_scene.RegionInfo.RegionName); | 2129 | MainConsole.Instance.OutputFormat("Cleared all parcels from {0}", m_scene.Name); |
1759 | } | 2130 | } |
1760 | else | 2131 | else |
1761 | { | 2132 | { |
1762 | MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.RegionInfo.RegionName); | 2133 | MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.Name); |
1763 | } | 2134 | } |
1764 | } | 2135 | } |
1765 | 2136 | ||
1766 | protected void ShowParcelsCommand(Object[] args) | 2137 | protected void HandleShowCommand(string module, string[] args) |
1767 | { | 2138 | { |
1768 | StringBuilder report = new StringBuilder(); | 2139 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) |
1769 | 2140 | return; | |
1770 | report.AppendFormat("Land information for {0}\n", m_scene.RegionInfo.RegionName); | 2141 | |
1771 | report.AppendFormat( | 2142 | StringBuilder report = new StringBuilder(); |
1772 | "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n", | 2143 | |
1773 | "Parcel Name", | 2144 | if (args.Length <= 2) |
1774 | "Local ID", | 2145 | { |
1775 | "Area", | 2146 | AppendParcelsSummaryReport(report); |
1776 | "Starts", | 2147 | } |
1777 | "Ends", | 2148 | else |
1778 | "Owner"); | 2149 | { |
2150 | int landLocalId; | ||
2151 | |||
2152 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[2], out landLocalId)) | ||
2153 | return; | ||
2154 | |||
2155 | ILandObject lo; | ||
2156 | |||
2157 | lock (m_landList) | ||
2158 | { | ||
2159 | if (!m_landList.TryGetValue(landLocalId, out lo)) | ||
2160 | { | ||
2161 | MainConsole.Instance.OutputFormat("No parcel found with local ID {0}", landLocalId); | ||
2162 | return; | ||
2163 | } | ||
2164 | } | ||
2165 | |||
2166 | AppendParcelReport(report, lo); | ||
2167 | } | ||
2168 | |||
2169 | MainConsole.Instance.Output(report.ToString()); | ||
2170 | } | ||
2171 | |||
2172 | private void AppendParcelsSummaryReport(StringBuilder report) | ||
2173 | { | ||
2174 | report.AppendFormat("Land information for {0}\n", m_scene.Name); | ||
2175 | |||
2176 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
2177 | cdt.AddColumn("Parcel Name", ConsoleDisplayUtil.ParcelNameSize); | ||
2178 | cdt.AddColumn("ID", 3); | ||
2179 | cdt.AddColumn("Area", 6); | ||
2180 | cdt.AddColumn("Starts", ConsoleDisplayUtil.VectorSize); | ||
2181 | cdt.AddColumn("Ends", ConsoleDisplayUtil.VectorSize); | ||
2182 | cdt.AddColumn("Owner", ConsoleDisplayUtil.UserNameSize); | ||
1779 | 2183 | ||
1780 | lock (m_landList) | 2184 | lock (m_landList) |
1781 | { | 2185 | { |
1782 | foreach (ILandObject lo in m_landList.Values) | 2186 | foreach (ILandObject lo in m_landList.Values) |
1783 | { | 2187 | { |
1784 | LandData ld = lo.LandData; | 2188 | LandData ld = lo.LandData; |
1785 | 2189 | string ownerName; | |
1786 | report.AppendFormat( | 2190 | if (ld.IsGroupOwned) |
1787 | "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n", | 2191 | { |
1788 | ld.Name, ld.LocalID, ld.Area, lo.StartPoint, lo.EndPoint, m_userManager.GetUserName(ld.OwnerID)); | 2192 | GroupRecord rec = m_groupManager.GetGroupRecord(ld.GroupID); |
2193 | ownerName = (rec != null) ? rec.GroupName : "Unknown Group"; | ||
2194 | } | ||
2195 | else | ||
2196 | { | ||
2197 | ownerName = m_userManager.GetUserName(ld.OwnerID); | ||
2198 | } | ||
2199 | cdt.AddRow( | ||
2200 | ld.Name, ld.LocalID, ld.Area, lo.StartPoint, lo.EndPoint, ownerName); | ||
1789 | } | 2201 | } |
1790 | } | 2202 | } |
1791 | 2203 | ||
1792 | MainConsole.Instance.Output(report.ToString()); | 2204 | report.Append(cdt.ToString()); |
1793 | } | 2205 | } |
2206 | |||
2207 | private void AppendParcelReport(StringBuilder report, ILandObject lo) | ||
2208 | { | ||
2209 | LandData ld = lo.LandData; | ||
2210 | |||
2211 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
2212 | cdl.AddRow("Parcel name", ld.Name); | ||
2213 | cdl.AddRow("Local ID", ld.LocalID); | ||
2214 | cdl.AddRow("Description", ld.Description); | ||
2215 | cdl.AddRow("Snapshot ID", ld.SnapshotID); | ||
2216 | cdl.AddRow("Area", ld.Area); | ||
2217 | cdl.AddRow("Starts", lo.StartPoint); | ||
2218 | cdl.AddRow("Ends", lo.EndPoint); | ||
2219 | cdl.AddRow("AABB Min", ld.AABBMin); | ||
2220 | cdl.AddRow("AABB Max", ld.AABBMax); | ||
2221 | string ownerName; | ||
2222 | if (ld.IsGroupOwned) | ||
2223 | { | ||
2224 | GroupRecord rec = m_groupManager.GetGroupRecord(ld.GroupID); | ||
2225 | ownerName = (rec != null) ? rec.GroupName : "Unknown Group"; | ||
2226 | } | ||
2227 | else | ||
2228 | { | ||
2229 | ownerName = m_userManager.GetUserName(ld.OwnerID); | ||
2230 | } | ||
2231 | cdl.AddRow("Owner", ownerName); | ||
2232 | cdl.AddRow("Is group owned?", ld.IsGroupOwned); | ||
2233 | cdl.AddRow("GroupID", ld.GroupID); | ||
2234 | |||
2235 | cdl.AddRow("Status", ld.Status); | ||
2236 | cdl.AddRow("Flags", (ParcelFlags)ld.Flags); | ||
2237 | |||
2238 | cdl.AddRow("Landing Type", (LandingType)ld.LandingType); | ||
2239 | cdl.AddRow("User Location", ld.UserLocation); | ||
2240 | cdl.AddRow("User look at", ld.UserLookAt); | ||
2241 | |||
2242 | cdl.AddRow("Other clean time", ld.OtherCleanTime); | ||
2243 | |||
2244 | cdl.AddRow("Max Prims", lo.GetParcelMaxPrimCount()); | ||
2245 | IPrimCounts pc = lo.PrimCounts; | ||
2246 | cdl.AddRow("Owner Prims", pc.Owner); | ||
2247 | cdl.AddRow("Group Prims", pc.Group); | ||
2248 | cdl.AddRow("Other Prims", pc.Others); | ||
2249 | cdl.AddRow("Selected Prims", pc.Selected); | ||
2250 | cdl.AddRow("Total Prims", pc.Total); | ||
2251 | |||
2252 | cdl.AddRow("Music URL", ld.MusicURL); | ||
2253 | cdl.AddRow("Obscure Music", ld.ObscureMusic); | ||
2254 | |||
2255 | cdl.AddRow("Media ID", ld.MediaID); | ||
2256 | cdl.AddRow("Media Autoscale", Convert.ToBoolean(ld.MediaAutoScale)); | ||
2257 | cdl.AddRow("Media URL", ld.MediaURL); | ||
2258 | cdl.AddRow("Media Type", ld.MediaType); | ||
2259 | cdl.AddRow("Media Description", ld.MediaDescription); | ||
2260 | cdl.AddRow("Media Width", ld.MediaWidth); | ||
2261 | cdl.AddRow("Media Height", ld.MediaHeight); | ||
2262 | cdl.AddRow("Media Loop", ld.MediaLoop); | ||
2263 | cdl.AddRow("Obscure Media", ld.ObscureMedia); | ||
2264 | |||
2265 | cdl.AddRow("Parcel Category", ld.Category); | ||
2266 | |||
2267 | cdl.AddRow("Claim Date", ld.ClaimDate); | ||
2268 | cdl.AddRow("Claim Price", ld.ClaimPrice); | ||
2269 | cdl.AddRow("Pass Hours", ld.PassHours); | ||
2270 | cdl.AddRow("Pass Price", ld.PassPrice); | ||
2271 | |||
2272 | cdl.AddRow("Auction ID", ld.AuctionID); | ||
2273 | cdl.AddRow("Authorized Buyer ID", ld.AuthBuyerID); | ||
2274 | cdl.AddRow("Sale Price", ld.SalePrice); | ||
2275 | |||
2276 | cdl.AddToStringBuilder(report); | ||
2277 | } | ||
1794 | } | 2278 | } |
1795 | } | 2279 | } |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 5969d45..a0c1b9d 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -45,14 +45,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
45 | #region Member Variables | 45 | #region Member Variables |
46 | 46 | ||
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | #pragma warning disable 0429 | 48 | private static readonly string LogHeader = "[LAND OBJECT]"; |
49 | private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; | ||
50 | #pragma warning restore 0429 | ||
51 | private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; | ||
52 | 49 | ||
53 | private int m_lastSeqId = 0; | 50 | private readonly int landUnit = 4; |
54 | 51 | ||
55 | protected LandData m_landData = new LandData(); | 52 | private int m_lastSeqId = 0; |
53 | |||
56 | protected Scene m_scene; | 54 | protected Scene m_scene; |
57 | protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); | 55 | protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); |
58 | protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); | 56 | protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); |
@@ -60,76 +58,83 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
60 | protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>(); | 58 | protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>(); |
61 | protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds | 59 | protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds |
62 | 60 | ||
63 | public bool[,] LandBitmap | 61 | public bool[,] LandBitmap { get; set; } |
64 | { | ||
65 | get { return m_landBitmap; } | ||
66 | set { m_landBitmap = value; } | ||
67 | } | ||
68 | 62 | ||
69 | #endregion | 63 | #endregion |
70 | 64 | ||
71 | public int GetPrimsFree() | 65 | public int GetPrimsFree() |
72 | { | 66 | { |
73 | m_scene.EventManager.TriggerParcelPrimCountUpdate(); | 67 | m_scene.EventManager.TriggerParcelPrimCountUpdate(); |
74 | int free = GetSimulatorMaxPrimCount() - m_landData.SimwidePrims; | 68 | int free = GetSimulatorMaxPrimCount() - LandData.SimwidePrims; |
75 | return free; | 69 | return free; |
76 | } | 70 | } |
77 | 71 | ||
78 | public LandData LandData | 72 | public LandData LandData { get; set; } |
79 | { | ||
80 | get { return m_landData; } | ||
81 | 73 | ||
82 | set { m_landData = value; } | ||
83 | } | ||
84 | |||
85 | public IPrimCounts PrimCounts { get; set; } | 74 | public IPrimCounts PrimCounts { get; set; } |
86 | 75 | ||
87 | public UUID RegionUUID | 76 | public UUID RegionUUID |
88 | { | 77 | { |
89 | get { return m_scene.RegionInfo.RegionID; } | 78 | get { return m_scene.RegionInfo.RegionID; } |
90 | } | 79 | } |
91 | 80 | ||
92 | public Vector3 StartPoint | 81 | public Vector3 StartPoint |
93 | { | 82 | { |
94 | get | 83 | get |
95 | { | 84 | { |
96 | for (int y = 0; y < landArrayMax; y++) | 85 | for (int y = 0; y < LandBitmap.GetLength(1); y++) |
97 | { | 86 | { |
98 | for (int x = 0; x < landArrayMax; x++) | 87 | for (int x = 0; x < LandBitmap.GetLength(0); x++) |
99 | { | 88 | { |
100 | if (LandBitmap[x, y]) | 89 | if (LandBitmap[x, y]) |
101 | return new Vector3(x * 4, y * 4, 0); | 90 | return new Vector3(x * landUnit, y * landUnit, 0); |
102 | } | 91 | } |
103 | } | 92 | } |
104 | 93 | ||
94 | m_log.ErrorFormat("{0} StartPoint. No start point found. bitmapSize=<{1},{2}>", | ||
95 | LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); | ||
105 | return new Vector3(-1, -1, -1); | 96 | return new Vector3(-1, -1, -1); |
106 | } | 97 | } |
107 | } | 98 | } |
108 | 99 | ||
109 | public Vector3 EndPoint | 100 | public Vector3 EndPoint |
110 | { | 101 | { |
111 | get | 102 | get |
112 | { | 103 | { |
113 | for (int y = landArrayMax - 1; y >= 0; y--) | 104 | for (int y = LandBitmap.GetLength(1) - 1; y >= 0; y--) |
114 | { | 105 | { |
115 | for (int x = landArrayMax - 1; x >= 0; x--) | 106 | for (int x = LandBitmap.GetLength(0) - 1; x >= 0; x--) |
116 | { | 107 | { |
117 | if (LandBitmap[x, y]) | 108 | if (LandBitmap[x, y]) |
118 | { | 109 | { |
119 | return new Vector3(x * 4, y * 4, 0); | 110 | return new Vector3(x * landUnit + landUnit, y * landUnit + landUnit, 0); |
120 | } | 111 | } |
121 | } | 112 | } |
122 | } | 113 | } |
123 | 114 | ||
115 | m_log.ErrorFormat("{0} EndPoint. No end point found. bitmapSize=<{1},{2}>", | ||
116 | LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); | ||
124 | return new Vector3(-1, -1, -1); | 117 | return new Vector3(-1, -1, -1); |
125 | } | 118 | } |
126 | } | 119 | } |
127 | 120 | ||
128 | #region Constructors | 121 | #region Constructors |
129 | 122 | ||
123 | public LandObject(LandData landData, Scene scene) | ||
124 | { | ||
125 | LandData = landData.Copy(); | ||
126 | m_scene = scene; | ||
127 | } | ||
128 | |||
130 | public LandObject(UUID owner_id, bool is_group_owned, Scene scene) | 129 | public LandObject(UUID owner_id, bool is_group_owned, Scene scene) |
131 | { | 130 | { |
132 | m_scene = scene; | 131 | m_scene = scene; |
132 | if (m_scene == null) | ||
133 | LandBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit]; | ||
134 | else | ||
135 | LandBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; | ||
136 | |||
137 | LandData = new LandData(); | ||
133 | LandData.OwnerID = owner_id; | 138 | LandData.OwnerID = owner_id; |
134 | if (is_group_owned) | 139 | if (is_group_owned) |
135 | LandData.GroupID = owner_id; | 140 | LandData.GroupID = owner_id; |
@@ -152,9 +157,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
152 | /// <returns>Returns true if the piece of land contains the specified point</returns> | 157 | /// <returns>Returns true if the piece of land contains the specified point</returns> |
153 | public bool ContainsPoint(int x, int y) | 158 | public bool ContainsPoint(int x, int y) |
154 | { | 159 | { |
155 | if (x >= 0 && y >= 0 && x < Constants.RegionSize && y < Constants.RegionSize) | 160 | if (x >= 0 && y >= 0 && x < m_scene.RegionInfo.RegionSizeX && y < m_scene.RegionInfo.RegionSizeY) |
156 | { | 161 | { |
157 | return (LandBitmap[x / 4, y / 4] == true); | 162 | return LandBitmap[x / landUnit, y / landUnit]; |
158 | } | 163 | } |
159 | else | 164 | else |
160 | { | 165 | { |
@@ -164,12 +169,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
164 | 169 | ||
165 | public ILandObject Copy() | 170 | public ILandObject Copy() |
166 | { | 171 | { |
167 | ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); | 172 | ILandObject newLand = new LandObject(LandData, m_scene); |
168 | |||
169 | //Place all new variables here! | ||
170 | newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); | 173 | newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); |
171 | newLand.LandData = LandData.Copy(); | ||
172 | |||
173 | return newLand; | 174 | return newLand; |
174 | } | 175 | } |
175 | 176 | ||
@@ -194,7 +195,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
194 | else | 195 | else |
195 | { | 196 | { |
196 | // Normal Calculations | 197 | // Normal Calculations |
197 | int parcelMax = (int)(((float)LandData.Area / 65536.0f) | 198 | int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)) |
198 | * (float)m_scene.RegionInfo.ObjectCapacity | 199 | * (float)m_scene.RegionInfo.ObjectCapacity |
199 | * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); | 200 | * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); |
200 | // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! | 201 | // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! |
@@ -211,7 +212,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
211 | else | 212 | else |
212 | { | 213 | { |
213 | //Normal Calculations | 214 | //Normal Calculations |
214 | int simMax = (int)(((float)LandData.SimwideArea / 65536.0f) | 215 | int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)) |
215 | * (float)m_scene.RegionInfo.ObjectCapacity); | 216 | * (float)m_scene.RegionInfo.ObjectCapacity); |
216 | return simMax; | 217 | return simMax; |
217 | } | 218 | } |
@@ -224,17 +225,15 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
224 | public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) | 225 | public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) |
225 | { | 226 | { |
226 | IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); | 227 | IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); |
227 | uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); | 228 | // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); |
229 | uint regionFlags = (uint)(RegionFlags.PublicAllowed | ||
230 | | RegionFlags.AllowDirectTeleport | ||
231 | | RegionFlags.AllowParcelChanges | ||
232 | | RegionFlags.AllowVoice ); | ||
233 | |||
228 | if (estateModule != null) | 234 | if (estateModule != null) |
229 | regionFlags = estateModule.GetRegionFlags(); | 235 | regionFlags = estateModule.GetRegionFlags(); |
230 | 236 | ||
231 | // In a perfect world, this would have worked. | ||
232 | // | ||
233 | // if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) | ||
234 | // regionFlags |= (uint)RegionFlags.AllowLandmark; | ||
235 | // if (landData.OwnerID == remote_client.AgentId) | ||
236 | // regionFlags |= (uint)RegionFlags.AllowSetHome; | ||
237 | |||
238 | int seq_id; | 237 | int seq_id; |
239 | if (snap_selection && (sequence_id == 0)) | 238 | if (snap_selection && (sequence_id == 0)) |
240 | { | 239 | { |
@@ -368,12 +367,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
368 | ParcelFlags.DenyAgeUnverified); | 367 | ParcelFlags.DenyAgeUnverified); |
369 | } | 368 | } |
370 | 369 | ||
371 | uint preserve = LandData.Flags & ~allowedDelta; | 370 | if (allowedDelta != (uint)ParcelFlags.None) |
372 | newData.Flags = preserve | (args.ParcelFlags & allowedDelta); | 371 | { |
373 | 372 | uint preserve = LandData.Flags & ~allowedDelta; | |
374 | m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); | 373 | newData.Flags = preserve | (args.ParcelFlags & allowedDelta); |
375 | 374 | ||
376 | SendLandUpdateToAvatarsOverMe(snap_selection); | 375 | m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); |
376 | SendLandUpdateToAvatarsOverMe(snap_selection); | ||
377 | } | ||
377 | } | 378 | } |
378 | 379 | ||
379 | public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) | 380 | public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) |
@@ -388,9 +389,16 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
388 | newData.SalePrice = 0; | 389 | newData.SalePrice = 0; |
389 | newData.AuthBuyerID = UUID.Zero; | 390 | newData.AuthBuyerID = UUID.Zero; |
390 | newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); | 391 | newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); |
392 | |||
393 | bool sellObjects = (LandData.Flags & (uint)(ParcelFlags.SellParcelObjects)) != 0 | ||
394 | && !LandData.IsGroupOwned && !groupOwned; | ||
395 | UUID previousOwner = LandData.OwnerID; | ||
396 | |||
391 | m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); | 397 | m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); |
392 | m_scene.EventManager.TriggerParcelPrimCountUpdate(); | 398 | m_scene.EventManager.TriggerParcelPrimCountUpdate(); |
393 | SendLandUpdateToAvatarsOverMe(true); | 399 | SendLandUpdateToAvatarsOverMe(true); |
400 | |||
401 | if (sellObjects) SellLandObjects(previousOwner); | ||
394 | } | 402 | } |
395 | 403 | ||
396 | public void DeedToGroup(UUID groupID) | 404 | public void DeedToGroup(UUID groupID) |
@@ -421,6 +429,19 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
421 | return false; | 429 | return false; |
422 | } | 430 | } |
423 | 431 | ||
432 | public bool CanBeOnThisLand(UUID avatar, float posHeight) | ||
433 | { | ||
434 | if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar)) | ||
435 | { | ||
436 | return false; | ||
437 | } | ||
438 | else if (IsRestrictedFromLand(avatar)) | ||
439 | { | ||
440 | return false; | ||
441 | } | ||
442 | return true; | ||
443 | } | ||
444 | |||
424 | public bool HasGroupAccess(UUID avatar) | 445 | public bool HasGroupAccess(UUID avatar) |
425 | { | 446 | { |
426 | if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) | 447 | if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) |
@@ -553,8 +574,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
553 | try | 574 | try |
554 | { | 575 | { |
555 | over = | 576 | over = |
556 | m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), | 577 | m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)m_scene.RegionInfo.RegionSizeX - 1)), |
557 | Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); | 578 | Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)m_scene.RegionInfo.RegionSizeY - 1))); |
558 | } | 579 | } |
559 | catch (Exception) | 580 | catch (Exception) |
560 | { | 581 | { |
@@ -701,15 +722,15 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
701 | /// </summary> | 722 | /// </summary> |
702 | private void UpdateAABBAndAreaValues() | 723 | private void UpdateAABBAndAreaValues() |
703 | { | 724 | { |
704 | int min_x = 64; | 725 | int min_x = 10000; |
705 | int min_y = 64; | 726 | int min_y = 10000; |
706 | int max_x = 0; | 727 | int max_x = 0; |
707 | int max_y = 0; | 728 | int max_y = 0; |
708 | int tempArea = 0; | 729 | int tempArea = 0; |
709 | int x, y; | 730 | int x, y; |
710 | for (x = 0; x < 64; x++) | 731 | for (x = 0; x < LandBitmap.GetLength(0); x++) |
711 | { | 732 | { |
712 | for (y = 0; y < 64; y++) | 733 | for (y = 0; y < LandBitmap.GetLength(1); y++) |
713 | { | 734 | { |
714 | if (LandBitmap[x, y] == true) | 735 | if (LandBitmap[x, y] == true) |
715 | { | 736 | { |
@@ -717,31 +738,31 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
717 | if (min_y > y) min_y = y; | 738 | if (min_y > y) min_y = y; |
718 | if (max_x < x) max_x = x; | 739 | if (max_x < x) max_x = x; |
719 | if (max_y < y) max_y = y; | 740 | if (max_y < y) max_y = y; |
720 | tempArea += 16; //16sqm peice of land | 741 | tempArea += landUnit * landUnit; //16sqm peice of land |
721 | } | 742 | } |
722 | } | 743 | } |
723 | } | 744 | } |
724 | int tx = min_x * 4; | 745 | int tx = min_x * landUnit; |
725 | if (tx > ((int)Constants.RegionSize - 1)) | 746 | if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) |
726 | tx = ((int)Constants.RegionSize - 1); | 747 | tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); |
727 | int ty = min_y * 4; | 748 | int ty = min_y * landUnit; |
728 | if (ty > ((int)Constants.RegionSize - 1)) | 749 | if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1)) |
729 | ty = ((int)Constants.RegionSize - 1); | 750 | ty = ((int)m_scene.RegionInfo.RegionSizeY - 1); |
730 | 751 | ||
731 | LandData.AABBMin = | 752 | LandData.AABBMin = |
732 | new Vector3( | 753 | new Vector3( |
733 | (float)(min_x * 4), (float)(min_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); | 754 | (float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); |
734 | 755 | ||
735 | tx = max_x * 4; | 756 | tx = max_x * landUnit; |
736 | if (tx > ((int)Constants.RegionSize - 1)) | 757 | if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) |
737 | tx = ((int)Constants.RegionSize - 1); | 758 | tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); |
738 | ty = max_y * 4; | 759 | ty = max_y * landUnit; |
739 | if (ty > ((int)Constants.RegionSize - 1)) | 760 | if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1)) |
740 | ty = ((int)Constants.RegionSize - 1); | 761 | ty = ((int)m_scene.RegionInfo.RegionSizeY - 1); |
741 | 762 | ||
742 | LandData.AABBMax | 763 | LandData.AABBMax |
743 | = new Vector3( | 764 | = new Vector3( |
744 | (float)(max_x * 4), (float)(max_y * 4), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); | 765 | (float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); |
745 | 766 | ||
746 | LandData.Area = tempArea; | 767 | LandData.Area = tempArea; |
747 | } | 768 | } |
@@ -753,20 +774,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
753 | /// <summary> | 774 | /// <summary> |
754 | /// Sets the land's bitmap manually | 775 | /// Sets the land's bitmap manually |
755 | /// </summary> | 776 | /// </summary> |
756 | /// <param name="bitmap">64x64 block representing where this land is on a map</param> | 777 | /// <param name="bitmap">block representing where this land is on a map mapped in a 4x4 meter grid</param> |
757 | public void SetLandBitmap(bool[,] bitmap) | 778 | public void SetLandBitmap(bool[,] bitmap) |
758 | { | 779 | { |
759 | if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) | 780 | LandBitmap = bitmap; |
760 | { | 781 | // m_log.DebugFormat("{0} SetLandBitmap. BitmapSize=<{1},{2}>", LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); |
761 | //Throw an exception - The bitmap is not 64x64 | 782 | ForceUpdateLandInfo(); |
762 | //throw new Exception("Error: Invalid Parcel Bitmap"); | ||
763 | } | ||
764 | else | ||
765 | { | ||
766 | //Valid: Lets set it | ||
767 | LandBitmap = bitmap; | ||
768 | ForceUpdateLandInfo(); | ||
769 | } | ||
770 | } | 783 | } |
771 | 784 | ||
772 | /// <summary> | 785 | /// <summary> |
@@ -780,15 +793,19 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
780 | 793 | ||
781 | public bool[,] BasicFullRegionLandBitmap() | 794 | public bool[,] BasicFullRegionLandBitmap() |
782 | { | 795 | { |
783 | return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); | 796 | return GetSquareLandBitmap(0, 0, (int)m_scene.RegionInfo.RegionSizeX, (int) m_scene.RegionInfo.RegionSizeY); |
784 | } | 797 | } |
785 | 798 | ||
786 | public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) | 799 | public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) |
787 | { | 800 | { |
788 | bool[,] tempBitmap = new bool[64,64]; | 801 | // Empty bitmap for the whole region |
802 | bool[,] tempBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; | ||
789 | tempBitmap.Initialize(); | 803 | tempBitmap.Initialize(); |
790 | 804 | ||
805 | // Fill the bitmap square area specified by state and end | ||
791 | tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); | 806 | tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); |
807 | // m_log.DebugFormat("{0} GetSquareLandBitmap. tempBitmapSize=<{1},{2}>", | ||
808 | // LogHeader, tempBitmap.GetLength(0), tempBitmap.GetLength(1)); | ||
792 | return tempBitmap; | 809 | return tempBitmap; |
793 | } | 810 | } |
794 | 811 | ||
@@ -805,24 +822,20 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
805 | public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, | 822 | public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, |
806 | bool set_value) | 823 | bool set_value) |
807 | { | 824 | { |
808 | if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) | ||
809 | { | ||
810 | //Throw an exception - The bitmap is not 64x64 | ||
811 | //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); | ||
812 | } | ||
813 | |||
814 | int x, y; | 825 | int x, y; |
815 | for (y = 0; y < 64; y++) | 826 | for (y = 0; y < land_bitmap.GetLength(1); y++) |
816 | { | 827 | { |
817 | for (x = 0; x < 64; x++) | 828 | for (x = 0; x < land_bitmap.GetLength(0); x++) |
818 | { | 829 | { |
819 | if (x >= start_x / 4 && x < end_x / 4 | 830 | if (x >= start_x / landUnit && x < end_x / landUnit |
820 | && y >= start_y / 4 && y < end_y / 4) | 831 | && y >= start_y / landUnit && y < end_y / landUnit) |
821 | { | 832 | { |
822 | land_bitmap[x, y] = set_value; | 833 | land_bitmap[x, y] = set_value; |
823 | } | 834 | } |
824 | } | 835 | } |
825 | } | 836 | } |
837 | // m_log.DebugFormat("{0} ModifyLandBitmapSquare. startXY=<{1},{2}>, endXY=<{3},{4}>, val={5}, landBitmapSize=<{6},{7}>", | ||
838 | // LogHeader, start_x, start_y, end_x, end_y, set_value, land_bitmap.GetLength(0), land_bitmap.GetLength(1)); | ||
826 | return land_bitmap; | 839 | return land_bitmap; |
827 | } | 840 | } |
828 | 841 | ||
@@ -834,21 +847,21 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
834 | /// <returns></returns> | 847 | /// <returns></returns> |
835 | public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) | 848 | public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) |
836 | { | 849 | { |
837 | if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) | 850 | if (bitmap_base.GetLength(0) != bitmap_add.GetLength(0) |
851 | || bitmap_base.GetLength(1) != bitmap_add.GetLength(1) | ||
852 | || bitmap_add.Rank != 2 | ||
853 | || bitmap_base.Rank != 2) | ||
838 | { | 854 | { |
839 | //Throw an exception - The bitmap is not 64x64 | 855 | throw new Exception( |
840 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); | 856 | String.Format("{0} MergeLandBitmaps. merging maps not same size. baseSizeXY=<{1},{2}>, addSizeXY=<{3},{4}>", |
841 | } | 857 | LogHeader, bitmap_base.GetLength(0), bitmap_base.GetLength(1), bitmap_add.GetLength(0), bitmap_add.GetLength(1)) |
842 | if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) | 858 | ); |
843 | { | ||
844 | //Throw an exception - The bitmap is not 64x64 | ||
845 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); | ||
846 | } | 859 | } |
847 | 860 | ||
848 | int x, y; | 861 | int x, y; |
849 | for (y = 0; y < 64; y++) | 862 | for (y = 0; y < bitmap_base.GetLength(1); y++) |
850 | { | 863 | { |
851 | for (x = 0; x < 64; x++) | 864 | for (x = 0; x < bitmap_add.GetLength(0); x++) |
852 | { | 865 | { |
853 | if (bitmap_add[x, y]) | 866 | if (bitmap_add[x, y]) |
854 | { | 867 | { |
@@ -865,13 +878,13 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
865 | /// <returns></returns> | 878 | /// <returns></returns> |
866 | private byte[] ConvertLandBitmapToBytes() | 879 | private byte[] ConvertLandBitmapToBytes() |
867 | { | 880 | { |
868 | byte[] tempConvertArr = new byte[512]; | 881 | byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8]; |
869 | byte tempByte = 0; | 882 | byte tempByte = 0; |
870 | int x, y, i, byteNum = 0; | 883 | int byteNum = 0; |
871 | i = 0; | 884 | int i = 0; |
872 | for (y = 0; y < 64; y++) | 885 | for (int y = 0; y < LandBitmap.GetLength(1); y++) |
873 | { | 886 | { |
874 | for (x = 0; x < 64; x++) | 887 | for (int x = 0; x < LandBitmap.GetLength(0); x++) |
875 | { | 888 | { |
876 | tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); | 889 | tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); |
877 | if (i % 8 == 0) | 890 | if (i % 8 == 0) |
@@ -883,30 +896,52 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
883 | } | 896 | } |
884 | } | 897 | } |
885 | } | 898 | } |
899 | // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>", | ||
900 | // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); | ||
886 | return tempConvertArr; | 901 | return tempConvertArr; |
887 | } | 902 | } |
888 | 903 | ||
889 | private bool[,] ConvertBytesToLandBitmap() | 904 | private bool[,] ConvertBytesToLandBitmap() |
890 | { | 905 | { |
891 | bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; | 906 | bool[,] tempConvertMap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; |
892 | tempConvertMap.Initialize(); | 907 | tempConvertMap.Initialize(); |
893 | byte tempByte = 0; | 908 | byte tempByte = 0; |
894 | int x = 0, y = 0, i = 0, bitNum = 0; | 909 | // Math.Min overcomes an old bug that might have made it into the database. Only use the bytes that fit into convertMap. |
895 | for (i = 0; i < 512; i++) | 910 | int bitmapLen = Math.Min(LandData.Bitmap.Length, tempConvertMap.GetLength(0) * tempConvertMap.GetLength(1) / 8); |
911 | int xLen = (int)(m_scene.RegionInfo.RegionSizeX / landUnit); | ||
912 | |||
913 | if (bitmapLen == 512) | ||
914 | { | ||
915 | // Legacy bitmap being passed in. Use the legacy region size | ||
916 | // and only set the lower area of the larger region. | ||
917 | xLen = (int)(Constants.RegionSize / landUnit); | ||
918 | } | ||
919 | // m_log.DebugFormat("{0} ConvertBytesToLandBitmap: bitmapLen={1}, xLen={2}", LogHeader, bitmapLen, xLen); | ||
920 | |||
921 | int x = 0, y = 0; | ||
922 | for (int i = 0; i < bitmapLen; i++) | ||
896 | { | 923 | { |
897 | tempByte = LandData.Bitmap[i]; | 924 | tempByte = LandData.Bitmap[i]; |
898 | for (bitNum = 0; bitNum < 8; bitNum++) | 925 | for (int bitNum = 0; bitNum < 8; bitNum++) |
899 | { | 926 | { |
900 | bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); | 927 | bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); |
901 | tempConvertMap[x, y] = bit; | 928 | try |
929 | { | ||
930 | tempConvertMap[x, y] = bit; | ||
931 | } | ||
932 | catch (Exception) | ||
933 | { | ||
934 | m_log.DebugFormat("{0} ConvertBytestoLandBitmap: i={1}, x={2}, y={3}", LogHeader, i, x, y); | ||
935 | } | ||
902 | x++; | 936 | x++; |
903 | if (x > 63) | 937 | if (x >= xLen) |
904 | { | 938 | { |
905 | x = 0; | 939 | x = 0; |
906 | y++; | 940 | y++; |
907 | } | 941 | } |
908 | } | 942 | } |
909 | } | 943 | } |
944 | |||
910 | return tempConvertMap; | 945 | return tempConvertMap; |
911 | } | 946 | } |
912 | 947 | ||
@@ -1043,6 +1078,43 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1043 | 1078 | ||
1044 | #endregion | 1079 | #endregion |
1045 | 1080 | ||
1081 | #region Object Sales | ||
1082 | |||
1083 | public void SellLandObjects(UUID previousOwner) | ||
1084 | { | ||
1085 | // m_log.DebugFormat( | ||
1086 | // "[LAND OBJECT]: Request to sell objects in {0} from {1}", LandData.Name, previousOwner); | ||
1087 | |||
1088 | if (LandData.IsGroupOwned) | ||
1089 | return; | ||
1090 | |||
1091 | IBuySellModule m_BuySellModule = m_scene.RequestModuleInterface<IBuySellModule>(); | ||
1092 | if (m_BuySellModule == null) | ||
1093 | { | ||
1094 | m_log.Error("[LAND OBJECT]: BuySellModule not found"); | ||
1095 | return; | ||
1096 | } | ||
1097 | |||
1098 | ScenePresence sp; | ||
1099 | if (!m_scene.TryGetScenePresence(LandData.OwnerID, out sp)) | ||
1100 | { | ||
1101 | m_log.Error("[LAND OBJECT]: New owner is not present in scene"); | ||
1102 | return; | ||
1103 | } | ||
1104 | |||
1105 | lock (primsOverMe) | ||
1106 | { | ||
1107 | foreach (SceneObjectGroup obj in primsOverMe) | ||
1108 | { | ||
1109 | if (obj.OwnerID == previousOwner && obj.GroupID == UUID.Zero && | ||
1110 | (obj.GetEffectivePermissions() & (uint)(OpenSim.Framework.PermissionMask.Transfer)) != 0) | ||
1111 | m_BuySellModule.BuyObject(sp.ControllingClient, UUID.Zero, obj.LocalId, 1, 0); | ||
1112 | } | ||
1113 | } | ||
1114 | } | ||
1115 | |||
1116 | #endregion | ||
1117 | |||
1046 | #region Object Returning | 1118 | #region Object Returning |
1047 | 1119 | ||
1048 | public void ReturnObject(SceneObjectGroup obj) | 1120 | public void ReturnObject(SceneObjectGroup obj) |
@@ -1065,7 +1137,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1065 | { | 1137 | { |
1066 | foreach (SceneObjectGroup obj in primsOverMe) | 1138 | foreach (SceneObjectGroup obj in primsOverMe) |
1067 | { | 1139 | { |
1068 | if (obj.OwnerID == m_landData.OwnerID) | 1140 | if (obj.OwnerID == LandData.OwnerID) |
1069 | { | 1141 | { |
1070 | if (!returns.ContainsKey(obj.OwnerID)) | 1142 | if (!returns.ContainsKey(obj.OwnerID)) |
1071 | returns[obj.OwnerID] = | 1143 | returns[obj.OwnerID] = |
@@ -1074,11 +1146,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1074 | } | 1146 | } |
1075 | } | 1147 | } |
1076 | } | 1148 | } |
1077 | else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) | 1149 | else if (type == (uint)ObjectReturnType.Group && LandData.GroupID != UUID.Zero) |
1078 | { | 1150 | { |
1079 | foreach (SceneObjectGroup obj in primsOverMe) | 1151 | foreach (SceneObjectGroup obj in primsOverMe) |
1080 | { | 1152 | { |
1081 | if (obj.GroupID == m_landData.GroupID) | 1153 | if (obj.GroupID == LandData.GroupID) |
1082 | { | 1154 | { |
1083 | if (!returns.ContainsKey(obj.OwnerID)) | 1155 | if (!returns.ContainsKey(obj.OwnerID)) |
1084 | returns[obj.OwnerID] = | 1156 | returns[obj.OwnerID] = |
@@ -1091,9 +1163,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1091 | { | 1163 | { |
1092 | foreach (SceneObjectGroup obj in primsOverMe) | 1164 | foreach (SceneObjectGroup obj in primsOverMe) |
1093 | { | 1165 | { |
1094 | if (obj.OwnerID != m_landData.OwnerID && | 1166 | if (obj.OwnerID != LandData.OwnerID && |
1095 | (obj.GroupID != m_landData.GroupID || | 1167 | (obj.GroupID != LandData.GroupID || |
1096 | m_landData.GroupID == UUID.Zero)) | 1168 | LandData.GroupID == UUID.Zero)) |
1097 | { | 1169 | { |
1098 | if (!returns.ContainsKey(obj.OwnerID)) | 1170 | if (!returns.ContainsKey(obj.OwnerID)) |
1099 | returns[obj.OwnerID] = | 1171 | returns[obj.OwnerID] = |
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index f9cc0cf..9b51cc8 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs | |||
@@ -490,11 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
490 | 490 | ||
491 | m_Scene.ForEachSOG(AddObject); | 491 | m_Scene.ForEachSOG(AddObject); |
492 | 492 | ||
493 | List<UUID> primcountKeys = new List<UUID>(m_PrimCounts.Keys); | 493 | lock (m_PrimCounts) |
494 | foreach (UUID k in primcountKeys) | ||
495 | { | 494 | { |
496 | if (!m_OwnerMap.ContainsKey(k)) | 495 | List<UUID> primcountKeys = new List<UUID>(m_PrimCounts.Keys); |
497 | m_PrimCounts.Remove(k); | 496 | foreach (UUID k in primcountKeys) |
497 | { | ||
498 | if (!m_OwnerMap.ContainsKey(k)) | ||
499 | m_PrimCounts.Remove(k); | ||
500 | } | ||
498 | } | 501 | } |
499 | 502 | ||
500 | m_Tainted = false; | 503 | m_Tainted = false; |
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs new file mode 100644 index 0000000..4ed67f3 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs | |||
@@ -0,0 +1,266 @@ | |||
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 | |||
28 | using System; | ||
29 | using NUnit.Framework; | ||
30 | using OpenMetaverse; | ||
31 | using OpenSim.Framework; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using OpenSim.Tests.Common; | ||
34 | |||
35 | namespace OpenSim.Region.CoreModules.World.Land.Tests | ||
36 | { | ||
37 | public class LandManagementModuleTests : OpenSimTestCase | ||
38 | { | ||
39 | [Test] | ||
40 | public void TestAddLandObject() | ||
41 | { | ||
42 | TestHelpers.InMethod(); | ||
43 | // TestHelpers.EnableLogging(); | ||
44 | |||
45 | UUID userId = TestHelpers.ParseTail(0x1); | ||
46 | |||
47 | LandManagementModule lmm = new LandManagementModule(); | ||
48 | Scene scene = new SceneHelpers().SetupScene(); | ||
49 | SceneHelpers.SetupSceneModules(scene, lmm); | ||
50 | |||
51 | ILandObject lo = new LandObject(userId, false, scene); | ||
52 | lo.LandData.Name = "lo1"; | ||
53 | lo.SetLandBitmap( | ||
54 | lo.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); | ||
55 | lo = lmm.AddLandObject(lo); | ||
56 | |||
57 | // TODO: Should add asserts to check that land object was added properly. | ||
58 | |||
59 | // At the moment, this test just makes sure that we can't add a land object that overlaps the areas that | ||
60 | // the first still holds. | ||
61 | ILandObject lo2 = new LandObject(userId, false, scene); | ||
62 | lo2.SetLandBitmap( | ||
63 | lo2.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); | ||
64 | lo2.LandData.Name = "lo2"; | ||
65 | lo2 = lmm.AddLandObject(lo2); | ||
66 | |||
67 | { | ||
68 | ILandObject loAtCoord = lmm.GetLandObject(0, 0); | ||
69 | Assert.That(loAtCoord.LandData.LocalID, Is.EqualTo(lo.LandData.LocalID)); | ||
70 | Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(lo.LandData.GlobalID)); | ||
71 | } | ||
72 | |||
73 | { | ||
74 | ILandObject loAtCoord = lmm.GetLandObject((int)Constants.RegionSize - 1, ((int)Constants.RegionSize - 1)); | ||
75 | Assert.That(loAtCoord.LandData.LocalID, Is.EqualTo(lo.LandData.LocalID)); | ||
76 | Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(lo.LandData.GlobalID)); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | /// <summary> | ||
81 | /// Test parcels on region when no land data exists to be loaded. | ||
82 | /// </summary> | ||
83 | [Test] | ||
84 | public void TestLoadWithNoParcels() | ||
85 | { | ||
86 | TestHelpers.InMethod(); | ||
87 | // TestHelpers.EnableLogging(); | ||
88 | |||
89 | SceneHelpers sh = new SceneHelpers(); | ||
90 | LandManagementModule lmm = new LandManagementModule(); | ||
91 | Scene scene = sh.SetupScene(); | ||
92 | SceneHelpers.SetupSceneModules(scene, lmm); | ||
93 | |||
94 | scene.loadAllLandObjectsFromStorage(scene.RegionInfo.RegionID); | ||
95 | |||
96 | ILandObject loAtCoord1 = lmm.GetLandObject(0, 0); | ||
97 | Assert.That(loAtCoord1.LandData.LocalID, Is.Not.EqualTo(0)); | ||
98 | Assert.That(loAtCoord1.LandData.GlobalID, Is.Not.EqualTo(UUID.Zero)); | ||
99 | |||
100 | ILandObject loAtCoord2 = lmm.GetLandObject((int)Constants.RegionSize - 1, ((int)Constants.RegionSize - 1)); | ||
101 | Assert.That(loAtCoord2.LandData.LocalID, Is.EqualTo(loAtCoord1.LandData.LocalID)); | ||
102 | Assert.That(loAtCoord2.LandData.GlobalID, Is.EqualTo(loAtCoord1.LandData.GlobalID)); | ||
103 | } | ||
104 | |||
105 | /// <summary> | ||
106 | /// Test parcels on region when a single parcel already exists but it does not cover the whole region. | ||
107 | /// </summary> | ||
108 | [Test] | ||
109 | public void TestLoadWithSinglePartialCoveringParcel() | ||
110 | { | ||
111 | TestHelpers.InMethod(); | ||
112 | // TestHelpers.EnableLogging(); | ||
113 | |||
114 | UUID userId = TestHelpers.ParseTail(0x1); | ||
115 | |||
116 | SceneHelpers sh = new SceneHelpers(); | ||
117 | LandManagementModule lmm = new LandManagementModule(); | ||
118 | Scene scene = sh.SetupScene(); | ||
119 | SceneHelpers.SetupSceneModules(scene, lmm); | ||
120 | |||
121 | ILandObject originalLo1 = new LandObject(userId, false, scene); | ||
122 | originalLo1.LandData.Name = "lo1"; | ||
123 | originalLo1.SetLandBitmap( | ||
124 | originalLo1.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize / 2)); | ||
125 | |||
126 | sh.SimDataService.StoreLandObject(originalLo1); | ||
127 | |||
128 | scene.loadAllLandObjectsFromStorage(scene.RegionInfo.RegionID); | ||
129 | |||
130 | ILandObject loAtCoord1 = lmm.GetLandObject(0, 0); | ||
131 | Assert.That(loAtCoord1.LandData.Name, Is.EqualTo(originalLo1.LandData.Name)); | ||
132 | Assert.That(loAtCoord1.LandData.GlobalID, Is.EqualTo(originalLo1.LandData.GlobalID)); | ||
133 | |||
134 | ILandObject loAtCoord2 = lmm.GetLandObject((int)Constants.RegionSize - 1, ((int)Constants.RegionSize - 1)); | ||
135 | Assert.That(loAtCoord2.LandData.LocalID, Is.EqualTo(loAtCoord1.LandData.LocalID)); | ||
136 | Assert.That(loAtCoord2.LandData.GlobalID, Is.EqualTo(loAtCoord1.LandData.GlobalID)); | ||
137 | } | ||
138 | |||
139 | /// <summary> | ||
140 | /// Test parcels on region when a single parcel already exists but it does not cover the whole region. | ||
141 | /// </summary> | ||
142 | [Test] | ||
143 | public void TestLoadWithMultiplePartialCoveringParcels() | ||
144 | { | ||
145 | TestHelpers.InMethod(); | ||
146 | // TestHelpers.EnableLogging(); | ||
147 | |||
148 | UUID userId = TestHelpers.ParseTail(0x1); | ||
149 | |||
150 | SceneHelpers sh = new SceneHelpers(); | ||
151 | LandManagementModule lmm = new LandManagementModule(); | ||
152 | Scene scene = sh.SetupScene(); | ||
153 | SceneHelpers.SetupSceneModules(scene, lmm); | ||
154 | |||
155 | ILandObject originalLo1 = new LandObject(userId, false, scene); | ||
156 | originalLo1.LandData.Name = "lo1"; | ||
157 | originalLo1.SetLandBitmap( | ||
158 | originalLo1.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize / 2)); | ||
159 | |||
160 | sh.SimDataService.StoreLandObject(originalLo1); | ||
161 | |||
162 | ILandObject originalLo2 = new LandObject(userId, false, scene); | ||
163 | originalLo2.LandData.Name = "lo2"; | ||
164 | originalLo2.SetLandBitmap( | ||
165 | originalLo2.GetSquareLandBitmap( | ||
166 | 0, (int)Constants.RegionSize / 2, (int)Constants.RegionSize, ((int)Constants.RegionSize / 4) * 3)); | ||
167 | |||
168 | sh.SimDataService.StoreLandObject(originalLo2); | ||
169 | |||
170 | scene.loadAllLandObjectsFromStorage(scene.RegionInfo.RegionID); | ||
171 | |||
172 | ILandObject loAtCoord1 = lmm.GetLandObject(0, 0); | ||
173 | Assert.That(loAtCoord1.LandData.Name, Is.EqualTo(originalLo1.LandData.Name)); | ||
174 | Assert.That(loAtCoord1.LandData.GlobalID, Is.EqualTo(originalLo1.LandData.GlobalID)); | ||
175 | |||
176 | ILandObject loAtCoord2 | ||
177 | = lmm.GetLandObject((int)Constants.RegionSize - 1, (((int)Constants.RegionSize / 4) * 3) - 1); | ||
178 | Assert.That(loAtCoord2.LandData.Name, Is.EqualTo(originalLo2.LandData.Name)); | ||
179 | Assert.That(loAtCoord2.LandData.GlobalID, Is.EqualTo(originalLo2.LandData.GlobalID)); | ||
180 | |||
181 | ILandObject loAtCoord3 = lmm.GetLandObject((int)Constants.RegionSize - 1, ((int)Constants.RegionSize - 1)); | ||
182 | Assert.That(loAtCoord3.LandData.LocalID, Is.Not.EqualTo(loAtCoord1.LandData.LocalID)); | ||
183 | Assert.That(loAtCoord3.LandData.LocalID, Is.Not.EqualTo(loAtCoord2.LandData.LocalID)); | ||
184 | Assert.That(loAtCoord3.LandData.GlobalID, Is.Not.EqualTo(loAtCoord1.LandData.GlobalID)); | ||
185 | Assert.That(loAtCoord3.LandData.GlobalID, Is.Not.EqualTo(loAtCoord2.LandData.GlobalID)); | ||
186 | } | ||
187 | |||
188 | /// <summary> | ||
189 | /// Test parcels on region when whole region is parcelled (which should normally always be the case). | ||
190 | /// </summary> | ||
191 | [Test] | ||
192 | public void TestLoad() | ||
193 | { | ||
194 | TestHelpers.InMethod(); | ||
195 | // TestHelpers.EnableLogging(); | ||
196 | |||
197 | UUID userId = TestHelpers.ParseTail(0x1); | ||
198 | |||
199 | SceneHelpers sh = new SceneHelpers(); | ||
200 | LandManagementModule lmm = new LandManagementModule(); | ||
201 | Scene scene = sh.SetupScene(); | ||
202 | SceneHelpers.SetupSceneModules(scene, lmm); | ||
203 | |||
204 | ILandObject originalLo1 = new LandObject(userId, false, scene); | ||
205 | originalLo1.LandData.Name = "lo1"; | ||
206 | originalLo1.SetLandBitmap( | ||
207 | originalLo1.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize / 2)); | ||
208 | |||
209 | sh.SimDataService.StoreLandObject(originalLo1); | ||
210 | |||
211 | ILandObject originalLo2 = new LandObject(userId, false, scene); | ||
212 | originalLo2.LandData.Name = "lo2"; | ||
213 | originalLo2.SetLandBitmap( | ||
214 | originalLo2.GetSquareLandBitmap(0, (int)Constants.RegionSize / 2, (int)Constants.RegionSize, (int)Constants.RegionSize)); | ||
215 | |||
216 | sh.SimDataService.StoreLandObject(originalLo2); | ||
217 | |||
218 | scene.loadAllLandObjectsFromStorage(scene.RegionInfo.RegionID); | ||
219 | |||
220 | { | ||
221 | ILandObject loAtCoord = lmm.GetLandObject(0, 0); | ||
222 | Assert.That(loAtCoord.LandData.Name, Is.EqualTo(originalLo1.LandData.Name)); | ||
223 | Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(originalLo1.LandData.GlobalID)); | ||
224 | } | ||
225 | |||
226 | { | ||
227 | ILandObject loAtCoord = lmm.GetLandObject((int)Constants.RegionSize - 1, ((int)Constants.RegionSize - 1)); | ||
228 | Assert.That(loAtCoord.LandData.Name, Is.EqualTo(originalLo2.LandData.Name)); | ||
229 | Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(originalLo2.LandData.GlobalID)); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | [Test] | ||
234 | public void TestSubdivide() | ||
235 | { | ||
236 | TestHelpers.InMethod(); | ||
237 | // TestHelpers.EnableLogging(); | ||
238 | |||
239 | UUID userId = TestHelpers.ParseTail(0x1); | ||
240 | |||
241 | LandManagementModule lmm = new LandManagementModule(); | ||
242 | Scene scene = new SceneHelpers().SetupScene(); | ||
243 | SceneHelpers.SetupSceneModules(scene, lmm); | ||
244 | |||
245 | ILandObject lo = new LandObject(userId, false, scene); | ||
246 | lo.LandData.Name = "lo1"; | ||
247 | lo.SetLandBitmap( | ||
248 | lo.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); | ||
249 | lo = lmm.AddLandObject(lo); | ||
250 | |||
251 | lmm.Subdivide(0, 0, LandManagementModule.LandUnit, LandManagementModule.LandUnit, userId); | ||
252 | |||
253 | { | ||
254 | ILandObject loAtCoord = lmm.GetLandObject(0, 0); | ||
255 | Assert.That(loAtCoord.LandData.LocalID, Is.Not.EqualTo(lo.LandData.LocalID)); | ||
256 | Assert.That(loAtCoord.LandData.GlobalID, Is.Not.EqualTo(lo.LandData.GlobalID)); | ||
257 | } | ||
258 | |||
259 | { | ||
260 | ILandObject loAtCoord = lmm.GetLandObject(LandManagementModule.LandUnit, LandManagementModule.LandUnit); | ||
261 | Assert.That(loAtCoord.LandData.LocalID, Is.EqualTo(lo.LandData.LocalID)); | ||
262 | Assert.That(loAtCoord.LandData.GlobalID, Is.EqualTo(lo.LandData.GlobalID)); | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index 0945b43..949acb6 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs | |||
@@ -36,7 +36,6 @@ using OpenSim.Framework; | |||
36 | using OpenSim.Region.Framework.Interfaces; | 36 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
38 | using OpenSim.Tests.Common; | 38 | using OpenSim.Tests.Common; |
39 | using OpenSim.Tests.Common.Mock; | ||
40 | 39 | ||
41 | namespace OpenSim.Region.CoreModules.World.Land.Tests | 40 | namespace OpenSim.Region.CoreModules.World.Land.Tests |
42 | { | 41 | { |