aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs1333
1 files changed, 793 insertions, 540 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 92f6c1b..b1f5122 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -41,6 +41,7 @@ using OpenSim.Framework;
41using OpenSim.Framework.Capabilities; 41using OpenSim.Framework.Capabilities;
42using OpenSim.Framework.Console; 42using OpenSim.Framework.Console;
43using OpenSim.Framework.Servers; 43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Monitoring;
44using OpenSim.Framework.Servers.HttpServer; 45using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces; 46using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
@@ -52,7 +53,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
52namespace OpenSim.Region.CoreModules.World.Land 53namespace OpenSim.Region.CoreModules.World.Land
53{ 54{
54 // used for caching 55 // used for caching
55 internal class ExtendedLandData 56 internal class ExtendedLandData
56 { 57 {
57 public LandData LandData; 58 public LandData LandData;
58 public ulong RegionHandle; 59 public ulong RegionHandle;
@@ -69,9 +70,8 @@ namespace OpenSim.Region.CoreModules.World.Land
69 /// <summary> 70 /// <summary>
70 /// Minimum land unit size in region co-ordinates. 71 /// Minimum land unit size in region co-ordinates.
71 /// </summary> 72 /// </summary>
72 public const int LandUnit = 4;
73 73
74 private static readonly string remoteParcelRequestPath = "0009/"; 74 public const int LandUnit = 4;
75 75
76 private LandChannel landChannel; 76 private LandChannel landChannel;
77 private Scene m_scene; 77 private Scene m_scene;
@@ -89,20 +89,27 @@ namespace OpenSim.Region.CoreModules.World.Land
89 /// <value> 89 /// <value>
90 /// Land objects keyed by local id 90 /// Land objects keyed by local id
91 /// </value> 91 /// </value>
92 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 92// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
93
94 //ubit: removed the readonly so i can move it around
95 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
96 private Dictionary<UUID, int> m_landUUIDList = new Dictionary<UUID, int>();
93 97
94 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 98 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
95 99
96 private bool m_allowedForcefulBans = true; 100 private bool m_allowedForcefulBans = true;
101 private bool m_showBansLines = true;
102 private UUID DefaultGodParcelGroup;
103 private string DefaultGodParcelName;
97 104
98 // caches ExtendedLandData 105 // caches ExtendedLandData
99 private Cache parcelInfoCache; 106 private Cache parcelInfoCache;
100 107
101
102 /// <summary> 108 /// <summary>
103 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. 109 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
104 /// </summary> 110 /// </summary>
105 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); 111 private HashSet<UUID> forcedPosition = new HashSet<UUID>();
112
106 113
107 // Enables limiting parcel layer info transmission when doing simple updates 114 // Enables limiting parcel layer info transmission when doing simple updates
108 private bool shouldLimitParcelLayerInfoToViewDistance { get; set; } 115 private bool shouldLimitParcelLayerInfoToViewDistance { get; set; }
@@ -125,6 +132,11 @@ namespace OpenSim.Region.CoreModules.World.Land
125 { 132 {
126 shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance); 133 shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance);
127 parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance); 134 parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance);
135 DefaultGodParcelGroup = new UUID(landManagementConfig.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
136 DefaultGodParcelName = landManagementConfig.GetString("DefaultAdministratorParcelName", "Default Parcel");
137 bool disablebans = landManagementConfig.GetBoolean("DisableParcelBans", !m_allowedForcefulBans);
138 m_allowedForcefulBans = !disablebans;
139 m_showBansLines = landManagementConfig.GetBoolean("ShowParcelBansLines", m_showBansLines);
128 } 140 }
129 } 141 }
130 142
@@ -132,17 +144,20 @@ namespace OpenSim.Region.CoreModules.World.Land
132 { 144 {
133 m_scene = scene; 145 m_scene = scene;
134 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; 146 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
147
135 landChannel = new LandChannel(scene, this); 148 landChannel = new LandChannel(scene, this);
136 149
137 parcelInfoCache = new Cache(); 150 parcelInfoCache = new Cache();
138 parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache 151 parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache
139 parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0); 152 parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0);
140 153
154 m_scene.EventManager.OnObjectAddedToScene += EventManagerOnParcelPrimCountAdd;
141 m_scene.EventManager.OnParcelPrimCountAdd += EventManagerOnParcelPrimCountAdd; 155 m_scene.EventManager.OnParcelPrimCountAdd += EventManagerOnParcelPrimCountAdd;
156
157 m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene;
142 m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate; 158 m_scene.EventManager.OnParcelPrimCountUpdate += EventManagerOnParcelPrimCountUpdate;
143 m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManagerOnObjectBeingRemovedFromScene;
144 m_scene.EventManager.OnRequestParcelPrimCountUpdate += EventManagerOnRequestParcelPrimCountUpdate; 159 m_scene.EventManager.OnRequestParcelPrimCountUpdate += EventManagerOnRequestParcelPrimCountUpdate;
145 160
146 m_scene.EventManager.OnAvatarEnteringNewParcel += EventManagerOnAvatarEnteringNewParcel; 161 m_scene.EventManager.OnAvatarEnteringNewParcel += EventManagerOnAvatarEnteringNewParcel;
147 m_scene.EventManager.OnClientMovement += EventManagerOnClientMovement; 162 m_scene.EventManager.OnClientMovement += EventManagerOnClientMovement;
148 m_scene.EventManager.OnValidateLandBuy += EventManagerOnValidateLandBuy; 163 m_scene.EventManager.OnValidateLandBuy += EventManagerOnValidateLandBuy;
@@ -152,14 +167,14 @@ namespace OpenSim.Region.CoreModules.World.Land
152 m_scene.EventManager.OnSignificantClientMovement += EventManagerOnSignificantClientMovement; 167 m_scene.EventManager.OnSignificantClientMovement += EventManagerOnSignificantClientMovement;
153 m_scene.EventManager.OnNoticeNoLandDataFromStorage += EventManagerOnNoLandDataFromStorage; 168 m_scene.EventManager.OnNoticeNoLandDataFromStorage += EventManagerOnNoLandDataFromStorage;
154 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; 169 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage;
155 m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan; 170 m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan;
156 m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps; 171 m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps;
157 172
158 lock (m_scene) 173 lock (m_scene)
159 { 174 {
160 m_scene.LandChannel = (ILandChannel)landChannel; 175 m_scene.LandChannel = (ILandChannel)landChannel;
161 } 176 }
162 177
163 RegisterCommands(); 178 RegisterCommands();
164 } 179 }
165 180
@@ -172,8 +187,8 @@ namespace OpenSim.Region.CoreModules.World.Land
172 } 187 }
173 188
174 public void RemoveRegion(Scene scene) 189 public void RemoveRegion(Scene scene)
175 { 190 {
176 // TODO: Release event manager listeners here 191 // TODO: Release event manager listeners here
177 } 192 }
178 193
179// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason) 194// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
@@ -181,7 +196,7 @@ namespace OpenSim.Region.CoreModules.World.Land
181// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y); 196// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
182// reason = "You are not allowed to enter this sim."; 197// reason = "You are not allowed to enter this sim.";
183// return nearestParcel != null; 198// return nearestParcel != null;
184// } 199// }
185 200
186 void EventManagerOnNewClient(IClientAPI client) 201 void EventManagerOnNewClient(IClientAPI client)
187 { 202 {
@@ -199,18 +214,10 @@ namespace OpenSim.Region.CoreModules.World.Land
199 client.OnParcelReclaim += ClientOnParcelReclaim; 214 client.OnParcelReclaim += ClientOnParcelReclaim;
200 client.OnParcelInfoRequest += ClientOnParcelInfoRequest; 215 client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
201 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; 216 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
202 client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
203 client.OnParcelEjectUser += ClientOnParcelEjectUser; 217 client.OnParcelEjectUser += ClientOnParcelEjectUser;
204 client.OnParcelFreezeUser += ClientOnParcelFreezeUser; 218 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
205 client.OnSetStartLocationRequest += ClientOnSetHome; 219 client.OnSetStartLocationRequest += ClientOnSetHome;
206 220 client.OnParcelBuyPass += ClientParcelBuyPass;
207
208 EntityBase presenceEntity;
209 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
210 {
211 SendLandUpdate((ScenePresence)presenceEntity, true);
212 SendParcelOverlay(client);
213 }
214 } 221 }
215 222
216 public void EventMakeChildAgent(ScenePresence avatar) 223 public void EventMakeChildAgent(ScenePresence avatar)
@@ -218,52 +225,6 @@ namespace OpenSim.Region.CoreModules.World.Land
218 avatar.currentParcelUUID = UUID.Zero; 225 avatar.currentParcelUUID = UUID.Zero;
219 } 226 }
220 227
221 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
222 {
223 //If we are forcing a position for them to go
224 if (forcedPosition.ContainsKey(remoteClient.AgentId))
225 {
226 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
227
228 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
229 //When the avatar walks into a ban line on the ground, it prevents getting stuck
230 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
231
232 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
233 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
234 {
235// m_log.DebugFormat(
236// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
237// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
238
239 forcedPosition.Remove(remoteClient.AgentId);
240 }
241 //if we are far away, teleport
242 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
243 {
244 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
245// m_log.DebugFormat(
246// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
247// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
248
249 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
250 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
251
252 forcedPosition.Remove(remoteClient.AgentId);
253 }
254 else
255 {
256// m_log.DebugFormat(
257// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
258// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
259
260 //Forces them toward the forced position we want if they aren't there yet
261 agentData.UseClientAgentPosition = true;
262 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
263 }
264 }
265 }
266
267 public void Close() 228 public void Close()
268 { 229 {
269 } 230 }
@@ -291,7 +252,10 @@ namespace OpenSim.Region.CoreModules.World.Land
291 lock (m_landList) 252 lock (m_landList)
292 { 253 {
293 if (m_landList.TryGetValue(local_id, out land)) 254 if (m_landList.TryGetValue(local_id, out land))
255 {
294 land.LandData = newData; 256 land.LandData = newData;
257 m_landUUIDList[newData.GlobalID] = local_id;
258 }
295 } 259 }
296 260
297 if (land != null) 261 if (land != null)
@@ -312,28 +276,35 @@ namespace OpenSim.Region.CoreModules.World.Land
312 //Remove all the land objects in the sim and add a blank, full sim land object set to public 276 //Remove all the land objects in the sim and add a blank, full sim land object set to public
313 lock (m_landList) 277 lock (m_landList)
314 { 278 {
279 foreach(ILandObject parcel in m_landList.Values)
280 parcel.Clear();
281
315 m_landList.Clear(); 282 m_landList.Clear();
283 m_landUUIDList.Clear();
316 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 284 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
285
317 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; 286 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
318 } 287 }
319 } 288 }
320 289
321 /// <summary> 290 /// <summary>
322 /// Create a default parcel that spans the entire region and is owned by the estate owner. 291 /// Create a default parcel that spans the entire region and is owned by the estate owner.
323 /// </summary> 292 /// </summary>
324 /// <returns>The parcel created.</returns> 293 /// <returns>The parcel created.</returns>
325 protected ILandObject CreateDefaultParcel() 294 protected ILandObject CreateDefaultParcel()
326 { 295 {
327 m_log.DebugFormat( 296 m_log.DebugFormat("{0} Creating default parcel for region {1}", LogHeader, m_scene.RegionInfo.RegionName);
328 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 297
329 298 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
330 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 299
331 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, 300 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0,
332 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY)); 301 (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY));
333 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 302 LandData ldata = fullSimParcel.LandData;
334 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 303 ldata.SimwideArea = ldata.Area;
335 304 ldata.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
336 return AddLandObject(fullSimParcel); 305 ldata.ClaimDate = Util.UnixTimeSinceEpoch();
306
307 return AddLandObject(fullSimParcel);
337 } 308 }
338 309
339 public List<ILandObject> AllParcels() 310 public List<ILandObject> AllParcels()
@@ -347,9 +318,9 @@ namespace OpenSim.Region.CoreModules.World.Land
347 public List<ILandObject> ParcelsNearPoint(Vector3 position) 318 public List<ILandObject> ParcelsNearPoint(Vector3 position)
348 { 319 {
349 List<ILandObject> parcelsNear = new List<ILandObject>(); 320 List<ILandObject> parcelsNear = new List<ILandObject>();
350 for (int x = -4; x <= 4; x += 4) 321 for (int x = -8; x <= 8; x += 4)
351 { 322 {
352 for (int y = -4; y <= 4; y += 4) 323 for (int y = -8; y <= 8; y += 4)
353 { 324 {
354 ILandObject check = GetLandObject(position.X + x, position.Y + y); 325 ILandObject check = GetLandObject(position.X + x, position.Y + y);
355 if (check != null) 326 if (check != null)
@@ -365,33 +336,99 @@ namespace OpenSim.Region.CoreModules.World.Land
365 return parcelsNear; 336 return parcelsNear;
366 } 337 }
367 338
368 public void SendYouAreBannedNotice(ScenePresence avatar) 339 // checks and enforces bans or restrictions
340 // returns true if enforced
341 public bool EnforceBans(ILandObject land, ScenePresence avatar)
369 { 342 {
370 if (AllowedForcefulBans) 343 Vector3 agentpos = avatar.AbsolutePosition;
344 float h = m_scene.GetGroundHeight(agentpos.X, agentpos.Y) + LandChannel.BAN_LINE_SAFETY_HEIGHT;
345 float zdif = avatar.AbsolutePosition.Z - h;
346 if (zdif > 0 )
347 {
348 forcedPosition.Remove(avatar.UUID);
349 avatar.lastKnownAllowedPosition = agentpos;
350 return false;
351 }
352
353 bool ban = false;
354 string reason = "";
355 if (land.IsRestrictedFromLand(avatar.UUID))
371 { 356 {
372 avatar.ControllingClient.SendAlertMessage( 357 reason = "You do not have access to the parcel";
373 "You are not allowed on this parcel because you are banned. Please go away."); 358 ban = true;
359 }
360
361 if (land.IsBannedFromLand(avatar.UUID))
362 {
363 if ( m_allowedForcefulBans)
364 {
365 reason ="You are banned from parcel";
366 ban = true;
367 }
368 else if(!ban)
369 {
370 if (forcedPosition.Contains(avatar.UUID))
371 avatar.ControllingClient.SendAlertMessage("You are banned from parcel, please leave by your own will");
372 forcedPosition.Remove(avatar.UUID);
373 avatar.lastKnownAllowedPosition = agentpos;
374 return false;
375 }
376 }
377
378 if(ban)
379 {
380 if (!forcedPosition.Contains(avatar.UUID))
381 avatar.ControllingClient.SendAlertMessage(reason);
382
383 if(zdif > -4f)
384 {
385
386 agentpos.Z = h + 4.0f;
387 ForceAvatarToPosition(avatar, agentpos);
388 return true;
389 }
390
391 if (land.ContainsPoint((int)avatar.lastKnownAllowedPosition.X,
392 (int) avatar.lastKnownAllowedPosition.Y))
393 {
394 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
395 if (pos == null)
396 {
397 forcedPosition.Remove(avatar.UUID);
398 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
399 }
400 else
401 ForceAvatarToPosition(avatar, (Vector3)pos);
402 }
403 else
404 {
405 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
406 }
407 return true;
374 } 408 }
375 else 409 else
376 { 410 {
377 avatar.ControllingClient.SendAlertMessage( 411 forcedPosition.Remove(avatar.UUID);
378 "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim!"); 412 avatar.lastKnownAllowedPosition = agentpos;
413 return false;
379 } 414 }
380 } 415 }
381 416
382 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 417 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
383 { 418 {
384 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 419 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
385 if (position.HasValue)
386 {
387 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position;
388 }
389 }
390 420
391 public void SendYouAreRestrictedNotice(ScenePresence avatar) 421 if (!position.HasValue)
392 { 422 return;
393 avatar.ControllingClient.SendAlertMessage( 423
394 "You are not allowed on this parcel because the land owner has restricted access."); 424 if(avatar.MovingToTarget)
425 avatar.ResetMoveToTarget();
426 avatar.AbsolutePosition = position.Value;
427 avatar.lastKnownAllowedPosition = position.Value;
428 avatar.Velocity = Vector3.Zero;
429 if(avatar.IsSatOnObject)
430 avatar.StandUp();
431 forcedPosition.Add(avatar.UUID);
395 } 432 }
396 433
397 public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID) 434 public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
@@ -404,29 +441,12 @@ namespace OpenSim.Region.CoreModules.World.Land
404 parcelAvatarIsEntering = m_landList[localLandID]; 441 parcelAvatarIsEntering = m_landList[localLandID];
405 } 442 }
406 443
407 if (parcelAvatarIsEntering != null) 444 if (parcelAvatarIsEntering != null &&
445 avatar.currentParcelUUID != parcelAvatarIsEntering.LandData.GlobalID)
408 { 446 {
409 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) 447 SendLandUpdate(avatar, parcelAvatarIsEntering);
410 { 448 avatar.currentParcelUUID = parcelAvatarIsEntering.LandData.GlobalID;
411 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) 449 EnforceBans(parcelAvatarIsEntering, avatar);
412 {
413 SendYouAreBannedNotice(avatar);
414 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
415 }
416 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
417 {
418 SendYouAreRestrictedNotice(avatar);
419 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
420 }
421 else
422 {
423 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
424 }
425 }
426 else
427 {
428 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
429 }
430 } 450 }
431 } 451 }
432 } 452 }
@@ -434,7 +454,7 @@ namespace OpenSim.Region.CoreModules.World.Land
434 public void SendOutNearestBanLine(IClientAPI client) 454 public void SendOutNearestBanLine(IClientAPI client)
435 { 455 {
436 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 456 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
437 if (sp == null || sp.IsChildAgent) 457 if (sp == null || sp.IsDeleted)
438 return; 458 return;
439 459
440 List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition); 460 List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition);
@@ -454,98 +474,180 @@ namespace OpenSim.Region.CoreModules.World.Land
454 return; 474 return;
455 } 475 }
456 476
457 public void SendLandUpdate(ScenePresence avatar, bool force) 477 public void sendClientInitialLandInfo(IClientAPI remoteClient)
458 { 478 {
459 ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 479 ScenePresence avatar;
460 (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
461 480
462 if (over != null) 481 if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out avatar))
482 return;
483
484 if (!avatar.IsChildAgent)
463 { 485 {
464 if (force) 486 ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
465 { 487 if (over == null)
466 if (!avatar.IsChildAgent) 488 return;
467 {
468 over.SendLandUpdateToClient(avatar.ControllingClient);
469 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
470 m_scene.RegionInfo.RegionID);
471 }
472 }
473 489
474 if (avatar.currentParcelUUID != over.LandData.GlobalID) 490 avatar.currentParcelUUID = over.LandData.GlobalID;
475 { 491 over.SendLandUpdateToClient(avatar.ControllingClient);
476 if (!avatar.IsChildAgent)
477 {
478 over.SendLandUpdateToClient(avatar.ControllingClient);
479 avatar.currentParcelUUID = over.LandData.GlobalID;
480 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
481 m_scene.RegionInfo.RegionID);
482 }
483 }
484 } 492 }
493 SendParcelOverlay(remoteClient);
485 } 494 }
486 495
487 public void SendLandUpdate(ScenePresence avatar) 496 public void SendLandUpdate(ScenePresence avatar, ILandObject over)
488 { 497 {
489 SendLandUpdate(avatar, false); 498 if (avatar.IsChildAgent)
490 } 499 return;
491 500
492 public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar) 501 if (over != null)
493 {
494 SendLandUpdate(clientAvatar);
495 SendOutNearestBanLine(clientAvatar.ControllingClient);
496 ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
497 if (parcel != null)
498 { 502 {
499 if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && 503 over.SendLandUpdateToClient(avatar.ControllingClient);
500 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) 504// sl doesnt seem to send this now, as it used 2
501 { 505// SendParcelOverlay(avatar.ControllingClient);
502 EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID,
503 m_scene.RegionInfo.RegionID);
504 //They are going under the safety line!
505 if (!parcel.IsBannedFromLand(clientAvatar.UUID))
506 {
507 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
508 }
509 }
510 else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT &&
511 parcel.IsBannedFromLand(clientAvatar.UUID))
512 {
513 //once we've sent the message once, keep going toward the target until we are done
514 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
515 {
516 SendYouAreBannedNotice(clientAvatar);
517 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
518 }
519 }
520 else if (parcel.IsRestrictedFromLand(clientAvatar.UUID))
521 {
522 //once we've sent the message once, keep going toward the target until we are done
523 if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId))
524 {
525 SendYouAreRestrictedNotice(clientAvatar);
526 ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar));
527 }
528 }
529 else
530 {
531 //when we are finally in a safe place, lets release the forced position lock
532 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
533 }
534 } 506 }
535 } 507 }
536 508
509 public void EventManagerOnSignificantClientMovement(ScenePresence avatar)
510 {
511 if (avatar.IsChildAgent)
512 return;
513
514 if ( m_allowedForcefulBans && m_showBansLines)
515 SendOutNearestBanLine(avatar.ControllingClient);
516 }
517
537 /// <summary> 518 /// <summary>
538 /// Like handleEventManagerOnSignificantClientMovement, but called with an AgentUpdate regardless of distance. 519 /// Like handleEventManagerOnSignificantClientMovement, but called with an AgentUpdate regardless of distance.
539 /// </summary> 520 /// </summary>
540 /// <param name="avatar"></param> 521 /// <param name="avatar"></param>
541 public void EventManagerOnClientMovement(ScenePresence avatar) 522 public void EventManagerOnClientMovement(ScenePresence avatar)
542 { 523 {
524 if (avatar.IsChildAgent)
525 return;
526
543 Vector3 pos = avatar.AbsolutePosition; 527 Vector3 pos = avatar.AbsolutePosition;
544 ILandObject over = GetLandObject(pos.X, pos.Y); 528 ILandObject over = GetLandObject(pos.X, pos.Y);
545 if (over != null) 529 if (over != null)
546 { 530 {
547 if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || pos.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT)) 531 EnforceBans(over, avatar);
548 avatar.lastKnownAllowedPosition = pos; 532 pos = avatar.AbsolutePosition;
533 ILandObject newover = GetLandObject(pos.X, pos.Y);
534 if(over != newover || avatar.currentParcelUUID != newover.LandData.GlobalID)
535 {
536 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar,
537 newover.LandData.LocalID, m_scene.RegionInfo.RegionID);
538 }
539 }
540 }
541
542 public void ClientParcelBuyPass(IClientAPI remote_client, UUID targetID, int landLocalID)
543 {
544 ILandObject land;
545 lock (m_landList)
546 {
547 m_landList.TryGetValue(landLocalID, out land);
548 }
549 // trivial checks
550 if(land == null)
551 return;
552
553 LandData ldata = land.LandData;
554
555 if(ldata == null)
556 return;
557
558 if(ldata.OwnerID == targetID)
559 return;
560
561 if(ldata.PassHours == 0)
562 return;
563
564 // don't allow passes on group owned until we can give money to groups
565 if(ldata.IsGroupOwned)
566 {
567 remote_client.SendAgentAlertMessage("pass to group owned parcel not suported", false);
568 return;
569 }
570
571 if((ldata.Flags & (uint)ParcelFlags.UsePassList) == 0)
572 return;
573
574 int cost = ldata.PassPrice;
575
576 int idx = land.LandData.ParcelAccessList.FindIndex(
577 delegate(LandAccessEntry e)
578 {
579 if (e.AgentID == targetID && e.Flags == AccessList.Access)
580 return true;
581 return false;
582 });
583 int now = Util.UnixTimeSinceEpoch();
584 int expires = (int)(3600.0 * ldata.PassHours + 0.5f);
585 int currenttime = -1;
586 if (idx != -1)
587 {
588 if(ldata.ParcelAccessList[idx].Expires == 0)
589 {
590 remote_client.SendAgentAlertMessage("You already have access to parcel", false);
591 return;
592 }
593
594 currenttime = ldata.ParcelAccessList[idx].Expires - now;
595 if(currenttime > (int)(0.25f * expires + 0.5f))
596 {
597 if(currenttime > 3600)
598 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.###} hours",
599 currenttime/3600f), false);
600 else if(currenttime > 60)
601 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.##} minutes",
602 currenttime/60f), false);
603 else
604 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.#} seconds",
605 currenttime), false);
606 return;
607 }
608 }
609
610 LandAccessEntry entry = new LandAccessEntry();
611 entry.AgentID = targetID;
612 entry.Flags = AccessList.Access;
613 entry.Expires = now + expires;
614 if(currenttime > 0)
615 entry.Expires += currenttime;
616 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
617 if(cost != 0 && mm != null)
618 {
619 WorkManager.RunInThreadPool(
620 delegate
621 {
622 string regionName = m_scene.RegionInfo.RegionName;
623
624 if (!mm.AmountCovered(remote_client.AgentId, cost))
625 {
626 remote_client.SendAgentAlertMessage(String.Format("Insufficient funds in region '{0}' money system", regionName), true);
627 return;
628 }
629
630 string payDescription = String.Format("Parcel '{0}' at region '{1} {2:0.###} hours access pass", ldata.Name, regionName, ldata.PassHours);
631
632 if(!mm.MoveMoney(remote_client.AgentId, ldata.OwnerID, cost,MoneyTransactionType.LandPassSale, payDescription))
633 {
634 remote_client.SendAgentAlertMessage("Sorry pass payment processing failed, please try again later", true);
635 return;
636 }
637
638 if (idx != -1)
639 ldata.ParcelAccessList.RemoveAt(idx);
640 ldata.ParcelAccessList.Add(entry);
641 m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
642 return;
643 }, null, "ParcelBuyPass");
644 }
645 else
646 {
647 if (idx != -1)
648 ldata.ParcelAccessList.RemoveAt(idx);
649 ldata.ParcelAccessList.Add(entry);
650 m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
549 } 651 }
550 } 652 }
551 653
@@ -589,7 +691,7 @@ namespace OpenSim.Region.CoreModules.World.Land
589 requiredPowers = GroupPowers.LandManageBanned; 691 requiredPowers = GroupPowers.LandManageBanned;
590 692
591 if (m_scene.Permissions.CanEditParcelProperties(agentID, 693 if (m_scene.Permissions.CanEditParcelProperties(agentID,
592 land, requiredPowers)) 694 land, requiredPowers, false))
593 { 695 {
594 land.UpdateAccessList(flags, transactionID, sequenceID, 696 land.UpdateAccessList(flags, transactionID, sequenceID,
595 sections, entries, remote_client); 697 sections, entries, remote_client);
@@ -605,13 +707,11 @@ namespace OpenSim.Region.CoreModules.World.Land
605 /// Adds a land object to the stored list and adds them to the landIDList to what they own 707 /// Adds a land object to the stored list and adds them to the landIDList to what they own
606 /// </summary> 708 /// </summary>
607 /// <param name="new_land"> 709 /// <param name="new_land">
608 /// The land object being added. 710 /// The land object being added.
609 /// Will return null if this overlaps with an existing parcel that has not had its bitmap adjusted. 711 /// Will return null if this overlaps with an existing parcel that has not had its bitmap adjusted.
610 /// </param> 712 /// </param>
611 public ILandObject AddLandObject(ILandObject land) 713 public ILandObject AddLandObject(ILandObject new_land)
612 { 714 {
613 ILandObject new_land = land.Copy();
614
615 // Only now can we add the prim counts to the land object - we rely on the global ID which is generated 715 // Only now can we add the prim counts to the land object - we rely on the global ID which is generated
616 // as a random UUID inside LandData initialization 716 // as a random UUID inside LandData initialization
617 if (m_primCountModule != null) 717 if (m_primCountModule != null)
@@ -623,18 +723,15 @@ namespace OpenSim.Region.CoreModules.World.Land
623 new_land.LandData.LocalID = newLandLocalID; 723 new_land.LandData.LocalID = newLandLocalID;
624 724
625 bool[,] landBitmap = new_land.GetLandBitmap(); 725 bool[,] landBitmap = new_land.GetLandBitmap();
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)) 726 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
630 { 727 {
631 // Going to variable sized regions can cause mismatches 728 // 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})", 729 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) ); 730 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1));
634 } 731 }
635 else 732 else
636 { 733 {
637 // If other land objects still believe that they occupy any parts of the same space, 734 // If other land objects still believe that they occupy any parts of the same space,
638 // then do not allow the add to proceed. 735 // then do not allow the add to proceed.
639 for (int x = 0; x < landBitmap.GetLength(0); x++) 736 for (int x = 0; x < landBitmap.GetLength(0); x++)
640 { 737 {
@@ -652,7 +749,7 @@ namespace OpenSim.Region.CoreModules.World.Land
652 { 749 {
653 m_log.ErrorFormat( 750 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}", 751 "{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, 752 LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y,
656 lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name); 753 lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name);
657 754
658 return null; 755 return null;
@@ -668,10 +765,10 @@ namespace OpenSim.Region.CoreModules.World.Land
668 { 765 {
669 if (landBitmap[x, y]) 766 if (landBitmap[x, y])
670 { 767 {
671 // m_log.DebugFormat( 768 // m_log.DebugFormat(
672 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", 769 // "[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); 770 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
674 771
675 m_landIDList[x, y] = newLandLocalID; 772 m_landIDList[x, y] = newLandLocalID;
676 } 773 }
677 } 774 }
@@ -679,6 +776,7 @@ namespace OpenSim.Region.CoreModules.World.Land
679 } 776 }
680 777
681 m_landList.Add(newLandLocalID, new_land); 778 m_landList.Add(newLandLocalID, new_land);
779 m_landUUIDList[new_land.LandData.GlobalID] = newLandLocalID;
682 m_lastLandLocalID++; 780 m_lastLandLocalID++;
683 } 781 }
684 782
@@ -695,6 +793,7 @@ namespace OpenSim.Region.CoreModules.World.Land
695 public void removeLandObject(int local_id) 793 public void removeLandObject(int local_id)
696 { 794 {
697 ILandObject land; 795 ILandObject land;
796 UUID landGlobalID = UUID.Zero;
698 lock (m_landList) 797 lock (m_landList)
699 { 798 {
700 for (int x = 0; x < m_landIDList.GetLength(0); x++) 799 for (int x = 0; x < m_landIDList.GetLength(0); x++)
@@ -713,37 +812,47 @@ namespace OpenSim.Region.CoreModules.World.Land
713 812
714 land = m_landList[local_id]; 813 land = m_landList[local_id];
715 m_landList.Remove(local_id); 814 m_landList.Remove(local_id);
815 if(land != null && land.LandData != null)
816 {
817 landGlobalID = land.LandData.GlobalID;
818 m_landUUIDList.Remove(landGlobalID);
819 }
716 } 820 }
717 821
718 m_scene.EventManager.TriggerLandObjectRemoved(land.LandData.GlobalID); 822 if(landGlobalID != UUID.Zero)
823 {
824 m_scene.EventManager.TriggerLandObjectRemoved(landGlobalID);
825 land.Clear();
826 }
719 } 827 }
720 828
721 /// <summary> 829 /// <summary>
722 /// Clear the scene of all parcels 830 /// Clear the scene of all parcels
723 /// </summary> 831 /// </summary>
724 public void Clear(bool setupDefaultParcel) 832 public void Clear(bool setupDefaultParcel)
725 { 833 {
726 List<ILandObject> parcels; 834 Dictionary<int, ILandObject> landworkList;
835 // move to work pointer since we are deleting it all
727 lock (m_landList) 836 lock (m_landList)
728 { 837 {
729 parcels = new List<ILandObject>(m_landList.Values); 838 landworkList = m_landList;
839 m_landList = new Dictionary<int, ILandObject>();
730 } 840 }
731 841
732 foreach (ILandObject lo in parcels) 842 // this 2 methods have locks (now)
843 ResetSimLandObjects();
844
845 if (setupDefaultParcel)
846 CreateDefaultParcel();
847
848 // fire outside events unlocked
849 foreach (ILandObject lo in landworkList.Values)
733 { 850 {
734 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 851 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
735 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); 852 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
736 } 853 }
854 landworkList.Clear();
737 855
738 lock (m_landList)
739 {
740 m_landList.Clear();
741
742 ResetSimLandObjects();
743 }
744
745 if (setupDefaultParcel)
746 CreateDefaultParcel();
747 } 856 }
748 857
749 private void performFinalLandJoin(ILandObject master, ILandObject slave) 858 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -762,11 +871,29 @@ namespace OpenSim.Region.CoreModules.World.Land
762 } 871 }
763 } 872 }
764 } 873 }
765 874 master.LandData.Dwell += slave.LandData.Dwell;
766 removeLandObject(slave.LandData.LocalID); 875 removeLandObject(slave.LandData.LocalID);
767 UpdateLandObject(master.LandData.LocalID, master.LandData); 876 UpdateLandObject(master.LandData.LocalID, master.LandData);
768 } 877 }
769 878
879 public ILandObject GetLandObject(UUID globalID)
880 {
881 lock (m_landList)
882 {
883 int lid = -1;
884 if(m_landUUIDList.TryGetValue(globalID, out lid) && lid >= 0)
885 {
886 if (m_landList.ContainsKey(lid))
887 {
888 return m_landList[lid];
889 }
890 else
891 m_landUUIDList.Remove(globalID); // auto heal
892 }
893 }
894 return null;
895 }
896
770 public ILandObject GetLandObject(int parcelLocalID) 897 public ILandObject GetLandObject(int parcelLocalID)
771 { 898 {
772 lock (m_landList) 899 lock (m_landList)
@@ -787,58 +914,37 @@ namespace OpenSim.Region.CoreModules.World.Land
787 /// <returns>Land object at the point supplied</returns> 914 /// <returns>Land object at the point supplied</returns>
788 public ILandObject GetLandObject(float x_float, float y_float) 915 public ILandObject GetLandObject(float x_float, float y_float)
789 { 916 {
790 return GetLandObject((int)x_float, (int)y_float, true /* returnNullIfLandObjectNotFound */); 917 return GetLandObject((int)x_float, (int)y_float, true);
791 /* 918 }
792 int x;
793 int y;
794
795 if (x_float >= m_scene.RegionInfo.RegionSizeX || x_float < 0 || y_float >= m_scene.RegionInfo.RegionSizeX || y_float < 0)
796 return null;
797 919
798 try 920 // if x,y is off region this will return the parcel at cliped x,y
799 { 921 // as did code it replaces
800 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit)); 922 public ILandObject GetLandObjectClipedXY(float x, float y)
801 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit)); 923 {
802 } 924 //do clip inline
803 catch (OverflowException) 925 int avx = (int)x;
804 { 926 if (avx < 0)
805 return null; 927 avx = 0;
806 } 928 else if (avx >= m_scene.RegionInfo.RegionSizeX)
929 avx = (int)Constants.RegionSize - 1;
807 930
808 if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit) 931 int avy = (int)y;
809 || y >= (m_scene.RegionInfo.RegionSizeY / landUnit) 932 if (avy < 0)
810 || x < 0 933 avy = 0;
811 || y < 0) 934 else if (avy >= m_scene.RegionInfo.RegionSizeY)
812 { 935 avy = (int)Constants.RegionSize - 1;
813 return null;
814 }
815 936
816 lock (m_landList) 937 lock (m_landIDList)
817 { 938 {
818 // Corner case. If an autoreturn happens during sim startup
819 // we will come here with the list uninitialized
820 //
821// int landId = m_landIDList[x, y];
822
823// if (landId == 0)
824// m_log.DebugFormat(
825// "[LAND MANAGEMENT MODULE]: No land object found at ({0}, {1}) on {2}",
826// x, y, m_scene.RegionInfo.RegionName);
827
828 try 939 try
829 { 940 {
830 if (m_landList.ContainsKey(m_landIDList[x, y])) 941 return m_landList[m_landIDList[avx / LandUnit, avy / LandUnit]];
831 return m_landList[m_landIDList[x, y]];
832 } 942 }
833 catch (Exception e) 943 catch (IndexOutOfRangeException)
834 { 944 {
835 m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})", 945 return null;
836 LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
837 } 946 }
838
839 return null;
840 } 947 }
841 */
842 } 948 }
843 949
844 // Public entry. 950 // Public entry.
@@ -848,33 +954,32 @@ namespace OpenSim.Region.CoreModules.World.Land
848 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */); 954 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */);
849 } 955 }
850 956
851 /// <summary> 957 public ILandObject GetLandObject(int x, int y, bool returnNullIfLandObjectOutsideBounds)
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 { 958 {
864 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0) 959 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
865 { 960 {
866 // These exceptions here will cause a lot of complaints from the users specifically because 961 // These exceptions here will cause a lot of complaints from the users specifically because
867 // they happen every time at border crossings 962 // they happen every time at border crossings
868 if (returnNullIfLandObjectOutsideBounds) 963 if (returnNullIfLandObjectOutsideBounds)
869 return null; 964 return null;
870 else 965 else
871 throw new Exception( 966 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
872 String.Format("{0} GetLandObject for non-existent position. Region={1}, pos=<{2},{3}",
873 LogHeader, m_scene.RegionInfo.RegionName, x, y)
874 );
875 } 967 }
876 968
877 return m_landList[m_landIDList[x / 4, y / 4]]; 969 if(m_landList.Count == 0 || m_landIDList == null)
970 return null;
971
972 lock (m_landIDList)
973 {
974 try
975 {
976 return m_landList[m_landIDList[x / 4, y / 4]];
977 }
978 catch (IndexOutOfRangeException)
979 {
980 return null;
981 }
982 }
878 } 983 }
879 984
880 // Create a 'parcel is here' bitmap for the parcel identified by the passed landID 985 // Create a 'parcel is here' bitmap for the parcel identified by the passed landID
@@ -926,7 +1031,7 @@ namespace OpenSim.Region.CoreModules.World.Land
926 } 1031 }
927 } 1032 }
928 1033
929 public void FinalizeLandPrimCountUpdate() 1034 private void FinalizeLandPrimCountUpdate()
930 { 1035 {
931 //Get Simwide prim count for owner 1036 //Get Simwide prim count for owner
932 Dictionary<UUID, List<LandObject>> landOwnersAndParcels = new Dictionary<UUID, List<LandObject>>(); 1037 Dictionary<UUID, List<LandObject>> landOwnersAndParcels = new Dictionary<UUID, List<LandObject>>();
@@ -967,10 +1072,10 @@ namespace OpenSim.Region.CoreModules.World.Land
967 1072
968 public void EventManagerOnParcelPrimCountUpdate() 1073 public void EventManagerOnParcelPrimCountUpdate()
969 { 1074 {
970// m_log.DebugFormat( 1075 //m_log.DebugFormat(
971// "[LAND MANAGEMENT MODULE]: Triggered EventManagerOnParcelPrimCountUpdate() for {0}", 1076 // "[land management module]: triggered eventmanageronparcelprimcountupdate() for {0}",
972// m_scene.RegionInfo.RegionName); 1077 // m_scene.RegionInfo.RegionName);
973 1078
974 ResetOverMeRecords(); 1079 ResetOverMeRecords();
975 EntityBase[] entities = m_scene.Entities.GetEntities(); 1080 EntityBase[] entities = m_scene.Entities.GetEntities();
976 foreach (EntityBase obj in entities) 1081 foreach (EntityBase obj in entities)
@@ -1002,27 +1107,33 @@ namespace OpenSim.Region.CoreModules.World.Land
1002 /// <param name="end_y">North Point</param> 1107 /// <param name="end_y">North Point</param>
1003 /// <param name="attempting_user_id">UUID of user who is trying to subdivide</param> 1108 /// <param name="attempting_user_id">UUID of user who is trying to subdivide</param>
1004 /// <returns>Returns true if successful</returns> 1109 /// <returns>Returns true if successful</returns>
1005 private void subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) 1110 public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
1006 { 1111 {
1007 //First, lets loop through the points and make sure they are all in the same peice of land 1112 //First, lets loop through the points and make sure they are all in the same peice of land
1008 //Get the land object at start 1113 //Get the land object at start
1009 1114
1010 ILandObject startLandObject = GetLandObject(start_x, start_y); 1115 ILandObject startLandObject = GetLandObject(start_x, start_y);
1011 1116
1012 if (startLandObject == null) return; 1117 if (startLandObject == null)
1118 return;
1119
1120 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin, true))
1121 {
1122 return;
1123 }
1013 1124
1014 //Loop through the points 1125 //Loop through the points
1015 try 1126 try
1016 { 1127 {
1017 int totalX = end_x - start_x; 1128 for (int y = start_y; y < end_y; y++)
1018 int totalY = end_y - start_y;
1019 for (int y = 0; y < totalY; y++)
1020 { 1129 {
1021 for (int x = 0; x < totalX; x++) 1130 for (int x = start_x; x < end_x; x++)
1022 { 1131 {
1023 ILandObject tempLandObject = GetLandObject(start_x + x, start_y + y); 1132 ILandObject tempLandObject = GetLandObject(x, y);
1024 if (tempLandObject == null) return; 1133 if (tempLandObject == null)
1025 if (tempLandObject != startLandObject) return; 1134 return;
1135 if (tempLandObject != startLandObject)
1136 return;
1026 } 1137 }
1027 } 1138 }
1028 } 1139 }
@@ -1031,22 +1142,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1031 return; 1142 return;
1032 } 1143 }
1033 1144
1034 //If we are still here, then they are subdividing within one piece of land 1145 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
1035 //Check owner
1036 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin))
1037 {
1038 return;
1039 }
1040
1041 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
1042 ILandObject newLand = startLandObject.Copy(); 1146 ILandObject newLand = startLandObject.Copy();
1147
1043 newLand.LandData.Name = newLand.LandData.Name; 1148 newLand.LandData.Name = newLand.LandData.Name;
1044 newLand.LandData.GlobalID = UUID.Random(); 1149 newLand.LandData.GlobalID = UUID.Random();
1045 newLand.LandData.Dwell = 0; 1150 newLand.LandData.Dwell = 0;
1151 // Clear "Show in search" on the cut out parcel to prevent double-charging
1152 newLand.LandData.Flags &= ~(uint)ParcelFlags.ShowDirectory;
1153 // invalidate landing point
1154 newLand.LandData.LandingType = (byte)LandingType.Direct;
1155 newLand.LandData.UserLocation = Vector3.Zero;
1156 newLand.LandData.UserLookAt = Vector3.Zero;
1046 1157
1047 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); 1158 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));
1048 1159
1049 //Now, lets set the subdivision area of the original to false 1160 //lets set the subdivision area of the original to false
1050 int startLandObjectIndex = startLandObject.LandData.LocalID; 1161 int startLandObjectIndex = startLandObject.LandData.LocalID;
1051 lock (m_landList) 1162 lock (m_landList)
1052 { 1163 {
@@ -1055,65 +1166,85 @@ namespace OpenSim.Region.CoreModules.World.Land
1055 m_landList[startLandObjectIndex].ForceUpdateLandInfo(); 1166 m_landList[startLandObjectIndex].ForceUpdateLandInfo();
1056 } 1167 }
1057 1168
1058 //Now add the new land object 1169 //add the new land object
1059 ILandObject result = AddLandObject(newLand); 1170 ILandObject result = AddLandObject(newLand);
1060 1171
1061 if (result != null) 1172 UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData);
1173
1174 if(startLandObject.LandData.LandingType == (byte)LandingType.LandingPoint)
1062 { 1175 {
1063 UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); 1176 int x = (int)startLandObject.LandData.UserLocation.X;
1064 result.SendLandUpdateToAvatarsOverMe(); 1177 int y = (int)startLandObject.LandData.UserLocation.Y;
1065 } 1178 if(!startLandObject.ContainsPoint(x, y))
1179 {
1180 startLandObject.LandData.LandingType = (byte)LandingType.Direct;
1181 startLandObject.LandData.UserLocation = Vector3.Zero;
1182 startLandObject.LandData.UserLookAt = Vector3.Zero;
1183 }
1184 }
1185
1186 m_scene.EventManager.TriggerParcelPrimCountTainted();
1187
1188 result.SendLandUpdateToAvatarsOverMe();
1189 startLandObject.SendLandUpdateToAvatarsOverMe();
1190 m_scene.ForEachClient(SendParcelOverlay);
1191
1066 } 1192 }
1067 1193
1068 /// <summary> 1194 /// <summary>
1069 /// Join 2 land objects together 1195 /// Join 2 land objects together
1070 /// </summary> 1196 /// </summary>
1071 /// <param name="start_x">x value in first piece of land</param> 1197 /// <param name="start_x">start x of selection area</param>
1072 /// <param name="start_y">y value in first piece of land</param> 1198 /// <param name="start_y">start y of selection area</param>
1073 /// <param name="end_x">x value in second peice of land</param> 1199 /// <param name="end_x">end x of selection area</param>
1074 /// <param name="end_y">y value in second peice of land</param> 1200 /// <param name="end_y">end y of selection area</param>
1075 /// <param name="attempting_user_id">UUID of the avatar trying to join the land objects</param> 1201 /// <param name="attempting_user_id">UUID of the avatar trying to join the land objects</param>
1076 /// <returns>Returns true if successful</returns> 1202 /// <returns>Returns true if successful</returns>
1077 private void join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) 1203 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
1078 { 1204 {
1079 end_x -= 4; 1205 int index = 0;
1080 end_y -= 4; 1206 int maxindex = -1;
1207 int maxArea = 0;
1081 1208
1082 List<ILandObject> selectedLandObjects = new List<ILandObject>(); 1209 List<ILandObject> selectedLandObjects = new List<ILandObject>();
1083 int stepYSelected; 1210 for (int x = start_x; x < end_x; x += 4)
1084 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4)
1085 { 1211 {
1086 int stepXSelected; 1212 for (int y = start_y; y < end_y; y += 4)
1087 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4)
1088 { 1213 {
1089 ILandObject p = GetLandObject(stepXSelected, stepYSelected); 1214 ILandObject p = GetLandObject(x, y);
1090 1215
1091 if (p != null) 1216 if (p != null)
1092 { 1217 {
1093 if (!selectedLandObjects.Contains(p)) 1218 if (!selectedLandObjects.Contains(p))
1094 { 1219 {
1095 selectedLandObjects.Add(p); 1220 selectedLandObjects.Add(p);
1221 if(p.LandData.Area > maxArea)
1222 {
1223 maxArea = p.LandData.Area;
1224 maxindex = index;
1225 }
1226 index++;
1096 } 1227 }
1097 } 1228 }
1098 } 1229 }
1099 } 1230 }
1100 ILandObject masterLandObject = selectedLandObjects[0];
1101 selectedLandObjects.RemoveAt(0);
1102 1231
1103 if (selectedLandObjects.Count < 1) 1232 if(maxindex < 0 || selectedLandObjects.Count < 2)
1104 {
1105 return; 1233 return;
1106 } 1234
1107 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin)) 1235 ILandObject masterLandObject = selectedLandObjects[maxindex];
1236 selectedLandObjects.RemoveAt(maxindex);
1237
1238 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin, true))
1108 { 1239 {
1109 return; 1240 return;
1110 } 1241 }
1242
1243 UUID masterOwner = masterLandObject.LandData.OwnerID;
1111 foreach (ILandObject p in selectedLandObjects) 1244 foreach (ILandObject p in selectedLandObjects)
1112 { 1245 {
1113 if (p.LandData.OwnerID != masterLandObject.LandData.OwnerID) 1246 if (p.LandData.OwnerID != masterOwner)
1114 {
1115 return; 1247 return;
1116 }
1117 } 1248 }
1118 1249
1119 lock (m_landList) 1250 lock (m_landList)
@@ -1126,29 +1257,14 @@ namespace OpenSim.Region.CoreModules.World.Land
1126 } 1257 }
1127 } 1258 }
1128 1259
1260 m_scene.EventManager.TriggerParcelPrimCountTainted();
1129 masterLandObject.SendLandUpdateToAvatarsOverMe(); 1261 masterLandObject.SendLandUpdateToAvatarsOverMe();
1262 m_scene.ForEachClient(SendParcelOverlay);
1130 } 1263 }
1131
1132 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
1133 {
1134 join(start_x, start_y, end_x, end_y, attempting_user_id);
1135 }
1136
1137 public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
1138 {
1139 subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
1140 }
1141
1142 #endregion 1264 #endregion
1143 1265
1144 #region Parcel Updating 1266 #region Parcel Updating
1145 1267
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
1152 /// <summary> 1268 /// <summary>
1153 /// Send the parcel overlay blocks to the client. We send the overlay packets 1269 /// Send the parcel overlay blocks to the client. We send the overlay packets
1154 /// around a location and limited by the 'parcelLayerViewDistance'. This number 1270 /// around a location and limited by the 'parcelLayerViewDistance'. This number
@@ -1162,145 +1278,115 @@ namespace OpenSim.Region.CoreModules.World.Land
1162 /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param> 1278 /// <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> 1279 /// <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> 1280 /// <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) 1281 public void SendParcelOverlay(IClientAPI remote_client)
1166 { 1282 {
1283 if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
1284 return;
1285
1167 const int LAND_BLOCKS_PER_PACKET = 1024; 1286 const int LAND_BLOCKS_PER_PACKET = 1024;
1168 1287
1169 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1288 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1170 int byteArrayCount = 0; 1289 int byteArrayCount = 0;
1171 int sequenceID = 0; 1290 int sequenceID = 0;
1172 1291
1173 int xLow = 0; 1292 // Layer data is in LandUnit (4m) chunks
1174 int xHigh = (int)m_scene.RegionInfo.RegionSizeX; 1293 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += LandUnit)
1175 int yLow = 0;
1176 int yHigh = (int)m_scene.RegionInfo.RegionSizeY;
1177
1178 if (shouldLimitParcelLayerInfoToViewDistance)
1179 { 1294 {
1180 // Compute view distance around the given point 1295 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += LandUnit)
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 { 1296 {
1186 txLow = xLow; 1297 byte tempByte = 0; //This represents the byte for the current 4x4
1187 txHigh = Math.Min(yLow + (layerViewDistance * 2), xHigh);
1188 }
1189 if (txHigh > xHigh)
1190 {
1191 txLow = Math.Max(xLow, xHigh - (layerViewDistance * 2));
1192 txHigh = xHigh;
1193 }
1194 xLow = txLow;
1195 xHigh = txHigh;
1196 1298
1197 int tyLow = yPlace - layerViewDistance; 1299 ILandObject currentParcelBlock = GetLandObject(x, y);
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);
1214 1300
1215 // Layer data is in landUnit (4m) chunks 1301 if (currentParcelBlock != null)
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)
1223 { 1302 {
1224 // m_log.DebugFormat("{0} SendParcelOverlay, sending packet, bytes={1}", LogHeader, byteArray.Length); 1303 // types
1225 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1304 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
1226 byteArrayCount = 0; 1305 {
1227 sequenceID++; 1306 //Owner Flag
1228 byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1307 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
1229 } 1308 }
1309 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1310 {
1311 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP;
1312 }
1313 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1314 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1315 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1316 {
1317 //Sale type
1318 tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE;
1319 }
1320 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1321 {
1322 //Public type
1323 tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
1324 }
1325 // LAND_TYPE_IS_BEING_AUCTIONED still unsuported
1326 else
1327 {
1328 //Other Flag
1329 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER;
1330 }
1230 1331
1231 } 1332 // now flags
1232 } 1333 // border control
1233 1334
1234 if (byteArrayCount != 0) 1335 ILandObject westParcel = null;
1235 { 1336 ILandObject southParcel = null;
1236 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1337 if (x > 0)
1237 // m_log.DebugFormat("{0} SendParcelOverlay, complete sending packet, bytes={1}", LogHeader, byteArray.Length); 1338 {
1238 } 1339 westParcel = GetLandObject((x - 1), y);
1239 } 1340 }
1341 if (y > 0)
1342 {
1343 southParcel = GetLandObject(x, (y - 1));
1344 }
1240 1345
1241 private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client) 1346 if (x == 0)
1242 { 1347 {
1243 byte tempByte = 0; //This represents the byte for the current 4x4 1348 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
1349 }
1350 else if (westParcel != null && westParcel != currentParcelBlock)
1351 {
1352 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
1353 }
1244 1354
1245 if (currentParcelBlock != null) 1355 if (y == 0)
1246 { 1356 {
1247 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) 1357 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
1248 { 1358 }
1249 //Owner Flag 1359 else if (southParcel != null && southParcel != currentParcelBlock)
1250 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1360 {
1251 } 1361 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
1252 else if (currentParcelBlock.LandData.SalePrice > 0 && 1362 }
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 }
1269 1363
1270 //Now for border control 1364 // local sound
1365 if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
1366 tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
1271 1367
1272 ILandObject westParcel = null; 1368 // hide avatars
1273 ILandObject southParcel = null; 1369 if (!currentParcelBlock.LandData.SeeAVs)
1274 if (x > 0) 1370 tempByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS;
1275 {
1276 westParcel = GetLandObject((x - 1) * LandUnit, y * LandUnit);
1277 }
1278 if (y > 0)
1279 {
1280 southParcel = GetLandObject(x * LandUnit, (y - 1) * LandUnit);
1281 }
1282 1371
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);
1290 }
1291 1372
1292 if (y == 0) 1373 byteArray[byteArrayCount] = tempByte;
1293 { 1374 byteArrayCount++;
1294 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1375 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1295 } 1376 {
1296 else if (southParcel != null && southParcel != currentParcelBlock) 1377 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1297 { 1378 byteArrayCount = 0;
1298 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1379 sequenceID++;
1380 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1381 }
1382 }
1299 } 1383 }
1300
1301 } 1384 }
1302 1385
1303 return tempByte; 1386 if (byteArrayCount > 0)
1387 {
1388 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1389 }
1304 } 1390 }
1305 1391
1306 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 1392 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
@@ -1320,8 +1406,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1320 { 1406 {
1321 if (!temp.Contains(currentParcel)) 1407 if (!temp.Contains(currentParcel))
1322 { 1408 {
1323 currentParcel.ForceUpdateLandInfo(); 1409 if (!currentParcel.IsBannedFromLand(remote_client.AgentId))
1324 temp.Add(currentParcel); 1410 {
1411 currentParcel.ForceUpdateLandInfo();
1412 temp.Add(currentParcel);
1413 }
1325 } 1414 }
1326 } 1415 }
1327 } 1416 }
@@ -1338,8 +1427,44 @@ namespace OpenSim.Region.CoreModules.World.Land
1338 temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client); 1427 temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
1339 } 1428 }
1340 1429
1341 // Also send the layer data around the point of interest 1430// SendParcelOverlay(remote_client);
1342 SendParcelOverlay(remote_client, (start_x + end_x) / 2, (start_y + end_y) / 2, parcelLayerViewDistance); 1431 }
1432
1433 public void UpdateLandProperties(ILandObject land, LandUpdateArgs args, IClientAPI remote_client)
1434 {
1435 bool snap_selection = false;
1436 bool needOverlay = false;
1437 if (land.UpdateLandProperties(args, remote_client, out snap_selection, out needOverlay))
1438 {
1439 UUID parcelID = land.LandData.GlobalID;
1440 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
1441 {
1442 if (avatar.IsDeleted || avatar.IsNPC)
1443 return;
1444
1445 IClientAPI client = avatar.ControllingClient;
1446 if (needOverlay)
1447 SendParcelOverlay(client);
1448
1449 if (avatar.IsChildAgent)
1450 {
1451 if(client == remote_client)
1452 land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, client);
1453 return;
1454 }
1455
1456 ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
1457 if (aland != null)
1458 {
1459 if(client == remote_client && land != aland)
1460 land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, client);
1461 else if (land == aland)
1462 aland.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, client);
1463 }
1464 if (avatar.currentParcelUUID == parcelID)
1465 avatar.currentParcelUUID = parcelID; // force parcel flags review
1466 });
1467 }
1343 } 1468 }
1344 1469
1345 public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) 1470 public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client)
@@ -1352,19 +1477,19 @@ namespace OpenSim.Region.CoreModules.World.Land
1352 1477
1353 if (land != null) 1478 if (land != null)
1354 { 1479 {
1355 land.UpdateLandProperties(args, remote_client); 1480 UpdateLandProperties(land, args, remote_client);
1356 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client); 1481 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client);
1357 } 1482 }
1358 } 1483 }
1359 1484
1360 public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) 1485 public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
1361 { 1486 {
1362 subdivide(west, south, east, north, remote_client.AgentId); 1487 Subdivide(west, south, east, north, remote_client.AgentId);
1363 } 1488 }
1364 1489
1365 public void ClientOnParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) 1490 public void ClientOnParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client)
1366 { 1491 {
1367 join(west, south, east, north, remote_client.AgentId); 1492 Join(west, south, east, north, remote_client.AgentId);
1368 } 1493 }
1369 1494
1370 public void ClientOnParcelSelectObjects(int local_id, int request_type, 1495 public void ClientOnParcelSelectObjects(int local_id, int request_type,
@@ -1375,7 +1500,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1375 1500
1376 public void ClientOnParcelObjectOwnerRequest(int local_id, IClientAPI remote_client) 1501 public void ClientOnParcelObjectOwnerRequest(int local_id, IClientAPI remote_client)
1377 { 1502 {
1378 ILandObject land; 1503 ILandObject land = null;
1379 lock (m_landList) 1504 lock (m_landList)
1380 { 1505 {
1381 m_landList.TryGetValue(local_id, out land); 1506 m_landList.TryGetValue(local_id, out land);
@@ -1384,7 +1509,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1384 if (land != null) 1509 if (land != null)
1385 { 1510 {
1386 m_scene.EventManager.TriggerParcelPrimCountUpdate(); 1511 m_scene.EventManager.TriggerParcelPrimCountUpdate();
1387 m_landList[local_id].SendLandObjectOwners(remote_client); 1512 land.SendLandObjectOwners(remote_client);
1388 } 1513 }
1389 else 1514 else
1390 { 1515 {
@@ -1394,7 +1519,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1394 1519
1395 public void ClientOnParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client) 1520 public void ClientOnParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client)
1396 { 1521 {
1397 ILandObject land; 1522 ILandObject land = null;
1398 lock (m_landList) 1523 lock (m_landList)
1399 { 1524 {
1400 m_landList.TryGetValue(local_id, out land); 1525 m_landList.TryGetValue(local_id, out land);
@@ -1408,7 +1533,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1408 land.LandData.GroupID = UUID.Zero; 1533 land.LandData.GroupID = UUID.Zero;
1409 land.LandData.IsGroupOwned = false; 1534 land.LandData.IsGroupOwned = false;
1410 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1535 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1411
1412 m_scene.ForEachClient(SendParcelOverlay); 1536 m_scene.ForEachClient(SendParcelOverlay);
1413 land.SendLandUpdateToClient(true, remote_client); 1537 land.SendLandUpdateToClient(true, remote_client);
1414 UpdateLandObject(land.LandData.LocalID, land.LandData); 1538 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1418,7 +1542,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1418 1542
1419 public void ClientOnParcelAbandonRequest(int local_id, IClientAPI remote_client) 1543 public void ClientOnParcelAbandonRequest(int local_id, IClientAPI remote_client)
1420 { 1544 {
1421 ILandObject land; 1545 ILandObject land = null;
1422 lock (m_landList) 1546 lock (m_landList)
1423 { 1547 {
1424 m_landList.TryGetValue(local_id, out land); 1548 m_landList.TryGetValue(local_id, out land);
@@ -1432,7 +1556,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1432 land.LandData.GroupID = UUID.Zero; 1556 land.LandData.GroupID = UUID.Zero;
1433 land.LandData.IsGroupOwned = false; 1557 land.LandData.IsGroupOwned = false;
1434 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1558 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1435 1559
1436 m_scene.ForEachClient(SendParcelOverlay); 1560 m_scene.ForEachClient(SendParcelOverlay);
1437 land.SendLandUpdateToClient(true, remote_client); 1561 land.SendLandUpdateToClient(true, remote_client);
1438 UpdateLandObject(land.LandData.LocalID, land.LandData); 1562 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1442,7 +1566,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1442 1566
1443 public void ClientOnParcelReclaim(int local_id, IClientAPI remote_client) 1567 public void ClientOnParcelReclaim(int local_id, IClientAPI remote_client)
1444 { 1568 {
1445 ILandObject land; 1569 ILandObject land = null;
1446 lock (m_landList) 1570 lock (m_landList)
1447 { 1571 {
1448 m_landList.TryGetValue(local_id, out land); 1572 m_landList.TryGetValue(local_id, out land);
@@ -1458,8 +1582,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1458 land.LandData.IsGroupOwned = false; 1582 land.LandData.IsGroupOwned = false;
1459 land.LandData.SalePrice = 0; 1583 land.LandData.SalePrice = 0;
1460 land.LandData.AuthBuyerID = UUID.Zero; 1584 land.LandData.AuthBuyerID = UUID.Zero;
1585 land.LandData.SeeAVs = true;
1586 land.LandData.AnyAVSounds = true;
1587 land.LandData.GroupAVSounds = true;
1461 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1588 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1462
1463 m_scene.ForEachClient(SendParcelOverlay); 1589 m_scene.ForEachClient(SendParcelOverlay);
1464 land.SendLandUpdateToClient(true, remote_client); 1590 land.SendLandUpdateToClient(true, remote_client);
1465 UpdateLandObject(land.LandData.LocalID, land.LandData); 1591 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1526,17 +1652,16 @@ namespace OpenSim.Region.CoreModules.World.Land
1526 1652
1527 void ClientOnParcelDeedToGroup(int parcelLocalID, UUID groupID, IClientAPI remote_client) 1653 void ClientOnParcelDeedToGroup(int parcelLocalID, UUID groupID, IClientAPI remote_client)
1528 { 1654 {
1529 ILandObject land; 1655 ILandObject land = null;
1530 lock (m_landList) 1656 lock (m_landList)
1531 { 1657 {
1532 m_landList.TryGetValue(parcelLocalID, out land); 1658 m_landList.TryGetValue(parcelLocalID, out land);
1533 } 1659 }
1534 1660
1535 if (!m_scene.Permissions.CanDeedParcel(remote_client.AgentId, land))
1536 return;
1537
1538 if (land != null) 1661 if (land != null)
1539 { 1662 {
1663 if (!m_scene.Permissions.CanDeedParcel(remote_client.AgentId, land))
1664 return;
1540 land.DeedToGroup(groupID); 1665 land.DeedToGroup(groupID);
1541 } 1666 }
1542 } 1667 }
@@ -1545,17 +1670,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1545 1670
1546 private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1671 private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1547 { 1672 {
1548// m_log.DebugFormat(
1549// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name);
1550
1551 // Prevent race conditions from any auto-creation of new parcels for varregions whilst we are still loading
1552 // the existing parcels.
1553 lock (m_landList) 1673 lock (m_landList)
1554 { 1674 {
1555 for (int i = 0; i < data.Count; i++) 1675 for (int i = 0; i < data.Count; i++)
1556 IncomingLandObjectFromStorage(data[i]); 1676 IncomingLandObjectFromStorage(data[i]);
1557 1677
1558 // Layer data is in landUnit (4m) chunks 1678 // Layer data is in LandUnit (4m) chunks
1559 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) 1679 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
1560 { 1680 {
1561 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) 1681 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
@@ -1565,7 +1685,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1565 if (m_landList.Count == 1) 1685 if (m_landList.Count == 1)
1566 { 1686 {
1567 m_log.DebugFormat( 1687 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}", 1688 "[{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); 1689 LogHeader, x, y, m_scene.Name);
1570 1690
1571 int onlyParcelID = 0; 1691 int onlyParcelID = 0;
@@ -1588,11 +1708,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1588 else if (m_landList.Count > 1) 1708 else if (m_landList.Count > 1)
1589 { 1709 {
1590 m_log.DebugFormat( 1710 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}", 1711 "{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); 1712 LogHeader, x, y, m_scene.Name);
1593 1713
1594 // There are several other parcels so we must create a new one for the unassigned space 1714 // 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); 1715 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
1596 // Claim all the unclaimed "0" ids 1716 // Claim all the unclaimed "0" ids
1597 newLand.SetLandBitmap(CreateBitmapForID(0)); 1717 newLand.SetLandBitmap(CreateBitmapForID(0));
1598 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 1718 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@@ -1603,20 +1723,23 @@ namespace OpenSim.Region.CoreModules.World.Land
1603 { 1723 {
1604 // We should never reach this point as the separate code path when no land data exists should have fired instead. 1724 // We should never reach this point as the separate code path when no land data exists should have fired instead.
1605 m_log.WarnFormat( 1725 m_log.WarnFormat(
1606 "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present", 1726 "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present",
1607 LogHeader, m_scene.Name); 1727 LogHeader, m_scene.Name);
1608 } 1728 }
1609 } 1729 }
1610 } 1730 }
1611 } 1731 }
1732 FinalizeLandPrimCountUpdate(); // update simarea information
1612 } 1733 }
1613 } 1734 }
1614 1735
1615 private void IncomingLandObjectFromStorage(LandData data) 1736 private void IncomingLandObjectFromStorage(LandData data)
1616 { 1737 {
1617 ILandObject new_land = new LandObject(data, m_scene); 1738 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene, data);
1618 new_land.SetLandBitmapFromByteArray(); 1739
1740 new_land.SetLandBitmapFromByteArray();
1619 AddLandObject(new_land); 1741 AddLandObject(new_land);
1742// new_land.SendLandUpdateToAvatarsOverMe();
1620 } 1743 }
1621 1744
1622 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1745 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1629,7 +1752,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1629 m_landList.TryGetValue(localID, out selectedParcel); 1752 m_landList.TryGetValue(localID, out selectedParcel);
1630 } 1753 }
1631 1754
1632 if (selectedParcel == null) 1755 if (selectedParcel == null)
1633 return; 1756 return;
1634 1757
1635 selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient); 1758 selectedParcel.ReturnLandObjects(returnType, agentIDs, taskIDs, remoteClient);
@@ -1670,9 +1793,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1670 foreach (HashSet<SceneObjectGroup> objs in returns.Values) 1793 foreach (HashSet<SceneObjectGroup> objs in returns.Values)
1671 { 1794 {
1672 List<SceneObjectGroup> objs2 = new List<SceneObjectGroup>(objs); 1795 List<SceneObjectGroup> objs2 = new List<SceneObjectGroup>(objs);
1673 if (m_scene.Permissions.CanReturnObjects(null, remoteClient.AgentId, objs2)) 1796 if (m_scene.Permissions.CanReturnObjects(null, remoteClient, objs2))
1674 { 1797 {
1675 m_scene.returnObjects(objs2.ToArray(), remoteClient.AgentId); 1798 m_scene.returnObjects(objs2.ToArray(), remoteClient);
1676 } 1799 }
1677 else 1800 else
1678 { 1801 {
@@ -1710,12 +1833,13 @@ namespace OpenSim.Region.CoreModules.World.Land
1710 1833
1711 private void EventManagerOnRegisterCaps(UUID agentID, Caps caps) 1834 private void EventManagerOnRegisterCaps(UUID agentID, Caps caps)
1712 { 1835 {
1836 //string capsBase = "/CAPS/" + UUID.Random();
1713 string capsBase = "/CAPS/" + caps.CapsObjectPath; 1837 string capsBase = "/CAPS/" + caps.CapsObjectPath;
1714 caps.RegisterHandler( 1838 caps.RegisterHandler(
1715 "RemoteParcelRequest", 1839 "RemoteParcelRequest",
1716 new RestStreamHandler( 1840 new RestStreamHandler(
1717 "POST", 1841 "POST",
1718 capsBase + remoteParcelRequestPath, 1842 capsBase,
1719 (request, path, param, httpRequest, httpResponse) 1843 (request, path, param, httpRequest, httpResponse)
1720 => RemoteParcelRequest(request, path, param, agentID, caps), 1844 => RemoteParcelRequest(request, path, param, agentID, caps),
1721 "RemoteParcelRequest", 1845 "RemoteParcelRequest",
@@ -1735,7 +1859,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1735 private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps) 1859 private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps)
1736 { 1860 {
1737 IClientAPI client; 1861 IClientAPI client;
1738 if (!m_scene.TryGetClient(agentID, out client)) 1862 if (!m_scene.TryGetClient(agentID, out client))
1739 { 1863 {
1740 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to retrieve IClientAPI for {0}", agentID); 1864 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to retrieve IClientAPI for {0}", agentID);
1741 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); 1865 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
@@ -1759,7 +1883,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1759 land_update.MusicURL = properties.MusicURL; 1883 land_update.MusicURL = properties.MusicURL;
1760 land_update.Name = properties.Name; 1884 land_update.Name = properties.Name;
1761 land_update.ParcelFlags = (uint) properties.ParcelFlags; 1885 land_update.ParcelFlags = (uint) properties.ParcelFlags;
1762 land_update.PassHours = (int) properties.PassHours; 1886 land_update.PassHours = properties.PassHours;
1763 land_update.PassPrice = (int) properties.PassPrice; 1887 land_update.PassPrice = (int) properties.PassPrice;
1764 land_update.SalePrice = (int) properties.SalePrice; 1888 land_update.SalePrice = (int) properties.SalePrice;
1765 land_update.SnapshotID = properties.SnapshotID; 1889 land_update.SnapshotID = properties.SnapshotID;
@@ -1773,7 +1897,20 @@ namespace OpenSim.Region.CoreModules.World.Land
1773 land_update.ObscureMusic = properties.ObscureMusic; 1897 land_update.ObscureMusic = properties.ObscureMusic;
1774 land_update.ObscureMedia = properties.ObscureMedia; 1898 land_update.ObscureMedia = properties.ObscureMedia;
1775 1899
1776 ILandObject land; 1900 if (args.ContainsKey("see_avs"))
1901 {
1902 land_update.SeeAVs = args["see_avs"].AsBoolean();
1903 land_update.AnyAVSounds = args["any_av_sounds"].AsBoolean();
1904 land_update.GroupAVSounds = args["group_av_sounds"].AsBoolean();
1905 }
1906 else
1907 {
1908 land_update.SeeAVs = true;
1909 land_update.AnyAVSounds = true;
1910 land_update.GroupAVSounds = true;
1911 }
1912
1913 ILandObject land = null;
1777 lock (m_landList) 1914 lock (m_landList)
1778 { 1915 {
1779 m_landList.TryGetValue(parcelID, out land); 1916 m_landList.TryGetValue(parcelID, out land);
@@ -1781,13 +1918,14 @@ namespace OpenSim.Region.CoreModules.World.Land
1781 1918
1782 if (land != null) 1919 if (land != null)
1783 { 1920 {
1784 land.UpdateLandProperties(land_update, client); 1921 UpdateLandProperties(land,land_update, client);
1785 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client); 1922 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client);
1786 } 1923 }
1787 else 1924 else
1788 { 1925 {
1789 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID); 1926 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID);
1790 } 1927 }
1928
1791 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); 1929 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
1792 } 1930 }
1793 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the 1931 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the
@@ -1815,9 +1953,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1815 { 1953 {
1816 Hashtable hash = new Hashtable(); 1954 Hashtable hash = new Hashtable();
1817 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); 1955 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
1818 if (hash.ContainsKey("region_id") && hash.ContainsKey("location")) 1956 if (hash.ContainsKey("location"))
1819 { 1957 {
1820 UUID regionID = (UUID)hash["region_id"]; 1958 UUID scope = m_scene.RegionInfo.ScopeID;
1821 ArrayList list = (ArrayList)hash["location"]; 1959 ArrayList list = (ArrayList)hash["location"];
1822 uint x = (uint)(double)list[0]; 1960 uint x = (uint)(double)list[0];
1823 uint y = (uint)(double)list[1]; 1961 uint y = (uint)(double)list[1];
@@ -1826,19 +1964,46 @@ namespace OpenSim.Region.CoreModules.World.Land
1826 // if you do a "About Landmark" on a landmark a second time, the viewer sends the 1964 // if you do a "About Landmark" on a landmark a second time, the viewer sends the
1827 // region_handle it got earlier via RegionHandleRequest 1965 // region_handle it got earlier via RegionHandleRequest
1828 ulong regionHandle = Util.BytesToUInt64Big((byte[])hash["region_handle"]); 1966 ulong regionHandle = Util.BytesToUInt64Big((byte[])hash["region_handle"]);
1829 parcelID = Util.BuildFakeParcelID(regionHandle, x, y); 1967 if(regionHandle == m_scene.RegionInfo.RegionHandle)
1968 parcelID = Util.BuildFakeParcelID(regionHandle, x, y);
1969 else
1970 {
1971 uint wx;
1972 uint wy;
1973 Util.RegionHandleToWorldLoc(regionHandle, out wx, out wy);
1974 GridRegion info = m_scene.GridService.GetRegionByPosition(scope, (int)wx, (int)wy);
1975 if(info != null)
1976 {
1977 wx -= (uint)info.RegionLocX;
1978 wy -= (uint)info.RegionLocY;
1979 wx += x;
1980 wy += y;
1981 // Firestorm devs have no ideia how to do handlers math
1982 // on all cases
1983 if(wx > info.RegionSizeX || wy > info.RegionSizeY)
1984 {
1985 wx = x;
1986 wy = y;
1987 }
1988 parcelID = Util.BuildFakeParcelID(info.RegionHandle, wx, wy);
1989 }
1990 }
1830 } 1991 }
1831 else if (regionID == m_scene.RegionInfo.RegionID) 1992 else if(hash.ContainsKey("region_id"))
1832 { 1993 {
1994 UUID regionID = (UUID)hash["region_id"];
1995 if (regionID == m_scene.RegionInfo.RegionID)
1996 {
1833 // a parcel request for a local parcel => no need to query the grid 1997 // a parcel request for a local parcel => no need to query the grid
1834 parcelID = Util.BuildFakeParcelID(m_scene.RegionInfo.RegionHandle, x, y); 1998 parcelID = Util.BuildFakeParcelID(m_scene.RegionInfo.RegionHandle, x, y);
1835 } 1999 }
1836 else 2000 else
1837 { 2001 {
1838 // a parcel request for a parcel in another region. Ask the grid about the region 2002 // a parcel request for a parcel in another region. Ask the grid about the region
1839 GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, regionID); 2003 GridRegion info = m_scene.GridService.GetRegionByUUID(scope, regionID);
1840 if (info != null) 2004 if (info != null)
1841 parcelID = Util.BuildFakeParcelID(info.RegionHandle, x, y); 2005 parcelID = Util.BuildFakeParcelID(info.RegionHandle, x, y);
2006 }
1842 } 2007 }
1843 } 2008 }
1844 } 2009 }
@@ -1854,7 +2019,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1854 2019
1855 LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse(); 2020 LLSDRemoteParcelResponse response = new LLSDRemoteParcelResponse();
1856 response.parcel_id = parcelID; 2021 response.parcel_id = parcelID;
1857 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelID {0}", parcelID); 2022 //m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelID {0}", parcelID);
1858 2023
1859 return LLSDHelpers.SerialiseLLSDReply(response); 2024 return LLSDHelpers.SerialiseLLSDReply(response);
1860 } 2025 }
@@ -1871,17 +2036,25 @@ namespace OpenSim.Region.CoreModules.World.Land
1871 { 2036 {
1872 UUID parcel = UUID.Zero; 2037 UUID parcel = UUID.Zero;
1873 UUID.TryParse(id, out parcel); 2038 UUID.TryParse(id, out parcel);
2039
1874 // assume we've got the parcelID we just computed in RemoteParcelRequest 2040 // assume we've got the parcelID we just computed in RemoteParcelRequest
1875 ExtendedLandData extLandData = new ExtendedLandData(); 2041 ExtendedLandData extLandData = new ExtendedLandData();
1876 Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle, 2042 if(!Util.ParseFakeParcelID(parcel, out extLandData.RegionHandle,
1877 out extLandData.X, out extLandData.Y); 2043 out extLandData.X, out extLandData.Y))
1878 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: Got parcelinfo request for regionHandle {0}, x/y {1}/{2}", 2044 return null;
2045 m_log.DebugFormat("[LAND MANAGEMENT MODULE] : Got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
1879 extLandData.RegionHandle, extLandData.X, extLandData.Y); 2046 extLandData.RegionHandle, extLandData.X, extLandData.Y);
1880 2047
1881 // for this region or for somewhere else? 2048 // for this region or for somewhere else?
1882 if (extLandData.RegionHandle == m_scene.RegionInfo.RegionHandle) 2049 if (extLandData.RegionHandle == m_scene.RegionInfo.RegionHandle)
1883 { 2050 {
1884 extLandData.LandData = this.GetLandObject(extLandData.X, extLandData.Y).LandData; 2051 ILandObject extLandObject = this.GetLandObject(extLandData.X, extLandData.Y);
2052 if(extLandObject == null)
2053 {
2054 m_log.DebugFormat("[LAND MANAGEMENT MODULE]: ParcelInfoRequest: a FakeParcelID points to outside the region");
2055 return null;
2056 }
2057 extLandData.LandData = extLandObject.LandData;
1885 extLandData.RegionAccess = m_scene.RegionInfo.AccessLevel; 2058 extLandData.RegionAccess = m_scene.RegionInfo.AccessLevel;
1886 } 2059 }
1887 else 2060 else
@@ -1907,6 +2080,9 @@ namespace OpenSim.Region.CoreModules.World.Land
1907 if (data.RegionHandle == m_scene.RegionInfo.RegionHandle) 2080 if (data.RegionHandle == m_scene.RegionInfo.RegionHandle)
1908 { 2081 {
1909 info = new GridRegion(m_scene.RegionInfo); 2082 info = new GridRegion(m_scene.RegionInfo);
2083 IDwellModule dwellModule = m_scene.RequestModuleInterface<IDwellModule>();
2084 if (dwellModule != null)
2085 data.LandData.Dwell = dwellModule.GetDwell(data.LandData);
1910 } 2086 }
1911 else 2087 else
1912 { 2088 {
@@ -1932,7 +2108,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1932 2108
1933 public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) 2109 public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
1934 { 2110 {
1935 ILandObject land; 2111 ILandObject land = null;
1936 lock (m_landList) 2112 lock (m_landList)
1937 { 2113 {
1938 m_landList.TryGetValue(localID, out land); 2114 m_landList.TryGetValue(localID, out land);
@@ -1940,14 +2116,91 @@ namespace OpenSim.Region.CoreModules.World.Land
1940 2116
1941 if (land == null) return; 2117 if (land == null) return;
1942 2118
1943 if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions)) 2119 if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions, false))
1944 return; 2120 return;
1945 2121
1946 land.LandData.OtherCleanTime = otherCleanTime; 2122 land.LandData.OtherCleanTime = otherCleanTime;
1947 2123
1948 UpdateLandObject(localID, land.LandData); 2124 UpdateLandObject(localID, land.LandData);
1949 } 2125 }
1950 2126
2127 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
2128 {
2129 ILandObject land = null;
2130 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
2131 foreach (ILandObject landObject in Land)
2132 {
2133 if (landObject.LandData.LocalID == landID)
2134 {
2135 land = landObject;
2136 }
2137 }
2138 land.DeedToGroup(DefaultGodParcelGroup);
2139 land.LandData.Name = DefaultGodParcelName;
2140 land.SendLandUpdateToAvatarsOverMe();
2141 }
2142
2143 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
2144 {
2145 ScenePresence SP;
2146 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
2147 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
2148 if (SP.GodController.UserLevel != 0)
2149 {
2150 if (flags == 0) //All parcels, scripted or not
2151 {
2152 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
2153 {
2154 if (e.OwnerID == targetID)
2155 {
2156 returns.Add(e);
2157 }
2158 }
2159 );
2160 }
2161 if (flags == 4) //All parcels, scripted object
2162 {
2163 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
2164 {
2165 if (e.OwnerID == targetID)
2166 {
2167 if (e.ContainsScripts())
2168 {
2169 returns.Add(e);
2170 }
2171 }
2172 });
2173 }
2174 if (flags == 4) //not target parcel, scripted object
2175 {
2176 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
2177 {
2178 if (e.OwnerID == targetID)
2179 {
2180 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
2181 if (landobject.LandData.OwnerID != e.OwnerID)
2182 {
2183 if (e.ContainsScripts())
2184 {
2185 returns.Add(e);
2186 }
2187 }
2188 }
2189 });
2190 }
2191 foreach (SceneObjectGroup ol in returns)
2192 {
2193 ReturnObject(ol, client);
2194 }
2195 }
2196 }
2197 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
2198 {
2199 SceneObjectGroup[] objs = new SceneObjectGroup[1];
2200 objs[0] = obj;
2201 ((Scene)client.Scene).returnObjects(objs, client);
2202 }
2203
1951 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); 2204 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1952 2205
1953 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 2206 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
@@ -1958,12 +2211,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1958 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); 2211 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager);
1959 System.Threading.Timer Timer; 2212 System.Threading.Timer Timer;
1960 2213
1961 if (targetAvatar.UserLevel == 0) 2214 if (targetAvatar.GodController.UserLevel < 200)
1962 { 2215 {
1963 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); 2216 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)) 2217 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true))
1965 return; 2218 return;
1966 if (flags == 0) 2219 if ((flags & 1) == 0) // only lowest bit has meaning for now
1967 { 2220 {
1968 targetAvatar.AllowMovement = false; 2221 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."); 2222 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world.");
@@ -1983,7 +2236,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1983 } 2236 }
1984 } 2237 }
1985 } 2238 }
1986
1987 private void OnEndParcelFrozen(object avatar) 2239 private void OnEndParcelFrozen(object avatar)
1988 { 2240 {
1989 ScenePresence targetAvatar = (ScenePresence)avatar; 2241 ScenePresence targetAvatar = (ScenePresence)avatar;
@@ -2010,12 +2262,13 @@ namespace OpenSim.Region.CoreModules.World.Land
2010 2262
2011 // Check if you even have permission to do this 2263 // Check if you even have permission to do this
2012 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); 2264 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
2013 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && 2265 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true) &&
2014 !m_scene.Permissions.IsAdministrator(client.AgentId)) 2266 !m_scene.Permissions.IsAdministrator(client.AgentId))
2015 return; 2267 return;
2268
2016 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); 2269 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
2017 2270
2018 targetAvatar.TeleportWithMomentum(pos, null); 2271 targetAvatar.TeleportOnEject(pos);
2019 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); 2272 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
2020 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); 2273 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
2021 2274
@@ -2059,7 +2312,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2059 if (// Required: local user; foreign users cannot set home 2312 if (// Required: local user; foreign users cannot set home
2060 m_scene.UserManagementModule.IsLocalGridUser(remoteClient.AgentId) && 2313 m_scene.UserManagementModule.IsLocalGridUser(remoteClient.AgentId) &&
2061 (// (a) gods and land managers can set home 2314 (// (a) gods and land managers can set home
2062 m_scene.Permissions.IsAdministrator(remoteClient.AgentId) || 2315 m_scene.Permissions.IsAdministrator(remoteClient.AgentId) ||
2063 m_scene.Permissions.IsGod(remoteClient.AgentId) || 2316 m_scene.Permissions.IsGod(remoteClient.AgentId) ||
2064 // (b) land owners can set home 2317 // (b) land owners can set home
2065 remoteClient.AgentId == land.LandData.OwnerID || 2318 remoteClient.AgentId == land.LandData.OwnerID ||
@@ -2111,8 +2364,8 @@ namespace OpenSim.Region.CoreModules.World.Land
2111 "If no local land ID is given, then summary information about all the parcels is shown.\n" 2364 "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.", 2365 + "If a local land ID is given then full information about that parcel is shown.",
2113 HandleShowCommand); 2366 HandleShowCommand);
2114 } 2367 }
2115 2368
2116 protected void HandleClearCommand(string module, string[] args) 2369 protected void HandleClearCommand(string module, string[] args)
2117 { 2370 {
2118 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) 2371 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
@@ -2120,9 +2373,9 @@ namespace OpenSim.Region.CoreModules.World.Land
2120 2373
2121 string response = MainConsole.Instance.CmdPrompt( 2374 string response = MainConsole.Instance.CmdPrompt(
2122 string.Format( 2375 string.Format(
2123 "Are you sure that you want to clear all land parcels from {0} (y or n)", m_scene.Name), 2376 "Are you sure that you want to clear all land parcels from {0} (y or n)", m_scene.Name),
2124 "n"); 2377 "n");
2125 2378
2126 if (response.ToLower() == "y") 2379 if (response.ToLower() == "y")
2127 { 2380 {
2128 Clear(true); 2381 Clear(true);
@@ -2132,14 +2385,14 @@ namespace OpenSim.Region.CoreModules.World.Land
2132 { 2385 {
2133 MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.Name); 2386 MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.Name);
2134 } 2387 }
2135 } 2388 }
2136 2389
2137 protected void HandleShowCommand(string module, string[] args) 2390 protected void HandleShowCommand(string module, string[] args)
2138 { 2391 {
2139 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) 2392 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
2140 return; 2393 return;
2141 2394
2142 StringBuilder report = new StringBuilder(); 2395 StringBuilder report = new StringBuilder();
2143 2396
2144 if (args.Length <= 2) 2397 if (args.Length <= 2)
2145 { 2398 {
@@ -2152,10 +2405,10 @@ namespace OpenSim.Region.CoreModules.World.Land
2152 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[2], out landLocalId)) 2405 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[2], out landLocalId))
2153 return; 2406 return;
2154 2407
2155 ILandObject lo; 2408 ILandObject lo = null;
2156 2409
2157 lock (m_landList) 2410 lock (m_landList)
2158 { 2411 {
2159 if (!m_landList.TryGetValue(landLocalId, out lo)) 2412 if (!m_landList.TryGetValue(landLocalId, out lo))
2160 { 2413 {
2161 MainConsole.Instance.OutputFormat("No parcel found with local ID {0}", landLocalId); 2414 MainConsole.Instance.OutputFormat("No parcel found with local ID {0}", landLocalId);
@@ -2170,7 +2423,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2170 } 2423 }
2171 2424
2172 private void AppendParcelsSummaryReport(StringBuilder report) 2425 private void AppendParcelsSummaryReport(StringBuilder report)
2173 { 2426 {
2174 report.AppendFormat("Land information for {0}\n", m_scene.Name); 2427 report.AppendFormat("Land information for {0}\n", m_scene.Name);
2175 2428
2176 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 2429 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -2180,7 +2433,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2180 cdt.AddColumn("Starts", ConsoleDisplayUtil.VectorSize); 2433 cdt.AddColumn("Starts", ConsoleDisplayUtil.VectorSize);
2181 cdt.AddColumn("Ends", ConsoleDisplayUtil.VectorSize); 2434 cdt.AddColumn("Ends", ConsoleDisplayUtil.VectorSize);
2182 cdt.AddColumn("Owner", ConsoleDisplayUtil.UserNameSize); 2435 cdt.AddColumn("Owner", ConsoleDisplayUtil.UserNameSize);
2183 2436
2184 lock (m_landList) 2437 lock (m_landList)
2185 { 2438 {
2186 foreach (ILandObject lo in m_landList.Values) 2439 foreach (ILandObject lo in m_landList.Values)
@@ -2202,7 +2455,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2202 } 2455 }
2203 2456
2204 report.Append(cdt.ToString()); 2457 report.Append(cdt.ToString());
2205 } 2458 }
2206 2459
2207 private void AppendParcelReport(StringBuilder report, ILandObject lo) 2460 private void AppendParcelReport(StringBuilder report, ILandObject lo)
2208 { 2461 {
@@ -2214,8 +2467,6 @@ namespace OpenSim.Region.CoreModules.World.Land
2214 cdl.AddRow("Description", ld.Description); 2467 cdl.AddRow("Description", ld.Description);
2215 cdl.AddRow("Snapshot ID", ld.SnapshotID); 2468 cdl.AddRow("Snapshot ID", ld.SnapshotID);
2216 cdl.AddRow("Area", ld.Area); 2469 cdl.AddRow("Area", ld.Area);
2217 cdl.AddRow("Starts", lo.StartPoint);
2218 cdl.AddRow("Ends", lo.EndPoint);
2219 cdl.AddRow("AABB Min", ld.AABBMin); 2470 cdl.AddRow("AABB Min", ld.AABBMin);
2220 cdl.AddRow("AABB Max", ld.AABBMax); 2471 cdl.AddRow("AABB Max", ld.AABBMax);
2221 string ownerName; 2472 string ownerName;
@@ -2233,7 +2484,7 @@ namespace OpenSim.Region.CoreModules.World.Land
2233 cdl.AddRow("GroupID", ld.GroupID); 2484 cdl.AddRow("GroupID", ld.GroupID);
2234 2485
2235 cdl.AddRow("Status", ld.Status); 2486 cdl.AddRow("Status", ld.Status);
2236 cdl.AddRow("Flags", (ParcelFlags)ld.Flags); 2487 cdl.AddRow("Flags", (ParcelFlags)ld.Flags);
2237 2488
2238 cdl.AddRow("Landing Type", (LandingType)ld.LandingType); 2489 cdl.AddRow("Landing Type", (LandingType)ld.LandingType);
2239 cdl.AddRow("User Location", ld.UserLocation); 2490 cdl.AddRow("User Location", ld.UserLocation);
@@ -2242,12 +2493,14 @@ namespace OpenSim.Region.CoreModules.World.Land
2242 cdl.AddRow("Other clean time", ld.OtherCleanTime); 2493 cdl.AddRow("Other clean time", ld.OtherCleanTime);
2243 2494
2244 cdl.AddRow("Max Prims", lo.GetParcelMaxPrimCount()); 2495 cdl.AddRow("Max Prims", lo.GetParcelMaxPrimCount());
2496 cdl.AddRow("Simwide Max Prims (owner)", lo.GetSimulatorMaxPrimCount());
2245 IPrimCounts pc = lo.PrimCounts; 2497 IPrimCounts pc = lo.PrimCounts;
2246 cdl.AddRow("Owner Prims", pc.Owner); 2498 cdl.AddRow("Owner Prims", pc.Owner);
2247 cdl.AddRow("Group Prims", pc.Group); 2499 cdl.AddRow("Group Prims", pc.Group);
2248 cdl.AddRow("Other Prims", pc.Others); 2500 cdl.AddRow("Other Prims", pc.Others);
2249 cdl.AddRow("Selected Prims", pc.Selected); 2501 cdl.AddRow("Selected Prims", pc.Selected);
2250 cdl.AddRow("Total Prims", pc.Total); 2502 cdl.AddRow("Total Prims", pc.Total);
2503 cdl.AddRow("SimWide Prims (owner)", pc.Simulator);
2251 2504
2252 cdl.AddRow("Music URL", ld.MusicURL); 2505 cdl.AddRow("Music URL", ld.MusicURL);
2253 cdl.AddRow("Obscure Music", ld.ObscureMusic); 2506 cdl.AddRow("Obscure Music", ld.ObscureMusic);