aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Land
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land')
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs32
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs767
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs215
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs4
4 files changed, 603 insertions, 415 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index 73c592d..378826d 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -40,23 +40,33 @@ namespace OpenSim.Region.CoreModules.World.Land
40 //Land types set with flags in ParcelOverlay. 40 //Land types set with flags in ParcelOverlay.
41 //Only one of these can be used. 41 //Only one of these can be used.
42 public const float BAN_LINE_SAFETY_HIEGHT = 100; 42 public const float BAN_LINE_SAFETY_HIEGHT = 100;
43 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = 128; //Equals 10000000
44 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = 64; //Equals 01000000
45 43
46 //RequestResults (I think these are right, they seem to work): 44 //RequestResults (I think these are right, they seem to work):
47 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land 45 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land
48 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land 46 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land
49 47
50 //ParcelSelectObjects 48 //ParcelSelectObjects
49 public const int LAND_SELECT_OBJECTS_OWNER = 2;
51 public const int LAND_SELECT_OBJECTS_GROUP = 4; 50 public const int LAND_SELECT_OBJECTS_GROUP = 4;
52 public const int LAND_SELECT_OBJECTS_OTHER = 8; 51 public const int LAND_SELECT_OBJECTS_OTHER = 8;
53 public const int LAND_SELECT_OBJECTS_OWNER = 2; 52
54 public const byte LAND_TYPE_IS_BEING_AUCTIONED = 5; //Equals 00000101 53
55 public const byte LAND_TYPE_IS_FOR_SALE = 4; //Equals 00000100 54 public const byte LAND_TYPE_PUBLIC = 0; //Equals 00000000
56 public const byte LAND_TYPE_OWNED_BY_GROUP = 2; //Equals 00000010 55 // types 1 to 7 are exclusive
57 public const byte LAND_TYPE_OWNED_BY_OTHER = 1; //Equals 00000001 56 public const byte LAND_TYPE_OWNED_BY_OTHER = 1; //Equals 00000001
57 public const byte LAND_TYPE_OWNED_BY_GROUP = 2; //Equals 00000010
58 public const byte LAND_TYPE_OWNED_BY_REQUESTER = 3; //Equals 00000011 58 public const byte LAND_TYPE_OWNED_BY_REQUESTER = 3; //Equals 00000011
59 public const byte LAND_TYPE_PUBLIC = 0; //Equals 00000000 59 public const byte LAND_TYPE_IS_FOR_SALE = 4; //Equals 00000100
60 public const byte LAND_TYPE_IS_BEING_AUCTIONED = 5; //Equals 00000101
61 public const byte LAND_TYPE_unused6 = 6;
62 public const byte LAND_TYPE_unused7 = 7;
63 // next are flags
64 public const byte LAND_FLAG_unused8 = 0x08; // this may become excluside in future
65 public const byte LAND_FLAG_HIDEAVATARS = 0x10;
66 public const byte LAND_FLAG_LOCALSOUND = 0x20;
67 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = 0x40; //Equals 01000000
68 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = 0x80; //Equals 10000000
69
60 70
61 //These are other constants. Yay! 71 //These are other constants. Yay!
62 public const int START_LAND_LOCAL_ID = 1; 72 public const int START_LAND_LOCAL_ID = 1;
@@ -203,7 +213,13 @@ namespace OpenSim.Region.CoreModules.World.Land
203 m_landManagementModule.setParcelOtherCleanTime(remoteClient, localID, otherCleanTime); 213 m_landManagementModule.setParcelOtherCleanTime(remoteClient, localID, otherCleanTime);
204 } 214 }
205 } 215 }
206 216 public void sendClientInitialLandInfo(IClientAPI remoteClient)
217 {
218 if (m_landManagementModule != null)
219 {
220 m_landManagementModule.sendClientInitialLandInfo(remoteClient);
221 }
222 }
207 #endregion 223 #endregion
208 } 224 }
209} 225}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 92f6c1b..ad6793f 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -69,6 +69,7 @@ namespace OpenSim.Region.CoreModules.World.Land
69 /// <summary> 69 /// <summary>
70 /// Minimum land unit size in region co-ordinates. 70 /// Minimum land unit size in region co-ordinates.
71 /// </summary> 71 /// </summary>
72
72 public const int LandUnit = 4; 73 public const int LandUnit = 4;
73 74
74 private static readonly string remoteParcelRequestPath = "0009/"; 75 private static readonly string remoteParcelRequestPath = "0009/";
@@ -89,21 +90,26 @@ namespace OpenSim.Region.CoreModules.World.Land
89 /// <value> 90 /// <value>
90 /// Land objects keyed by local id 91 /// Land objects keyed by local id
91 /// </value> 92 /// </value>
92 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 93// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
94
95 //ubit: removed the readonly so i can move it around
96 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
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 UUID DefaultGodParcelGroup;
102 private string DefaultGodParcelName;
97 103
98 // caches ExtendedLandData 104 // caches ExtendedLandData
99 private Cache parcelInfoCache; 105 private Cache parcelInfoCache;
100 106
101
102 /// <summary> 107 /// <summary>
103 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. 108 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
104 /// </summary> 109 /// </summary>
105 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); 110 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>();
106 111
112
107 // Enables limiting parcel layer info transmission when doing simple updates 113 // Enables limiting parcel layer info transmission when doing simple updates
108 private bool shouldLimitParcelLayerInfoToViewDistance { get; set; } 114 private bool shouldLimitParcelLayerInfoToViewDistance { get; set; }
109 // "View distance" for sending parcel layer info if asked for from a view point in the region 115 // "View distance" for sending parcel layer info if asked for from a view point in the region
@@ -125,6 +131,8 @@ namespace OpenSim.Region.CoreModules.World.Land
125 { 131 {
126 shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance); 132 shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance);
127 parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance); 133 parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance);
134 DefaultGodParcelGroup = new UUID(landManagementConfig.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
135 DefaultGodParcelName = landManagementConfig.GetString("DefaultAdministratorParcelName", "Default Parcel");
128 } 136 }
129 } 137 }
130 138
@@ -132,6 +140,7 @@ namespace OpenSim.Region.CoreModules.World.Land
132 { 140 {
133 m_scene = scene; 141 m_scene = scene;
134 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; 142 m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit];
143
135 landChannel = new LandChannel(scene, this); 144 landChannel = new LandChannel(scene, this);
136 145
137 parcelInfoCache = new Cache(); 146 parcelInfoCache = new Cache();
@@ -154,7 +163,7 @@ namespace OpenSim.Region.CoreModules.World.Land
154 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; 163 m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage;
155 m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan; 164 m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan;
156 m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps; 165 m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps;
157 166
158 lock (m_scene) 167 lock (m_scene)
159 { 168 {
160 m_scene.LandChannel = (ILandChannel)landChannel; 169 m_scene.LandChannel = (ILandChannel)landChannel;
@@ -204,13 +213,14 @@ namespace OpenSim.Region.CoreModules.World.Land
204 client.OnParcelFreezeUser += ClientOnParcelFreezeUser; 213 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
205 client.OnSetStartLocationRequest += ClientOnSetHome; 214 client.OnSetStartLocationRequest += ClientOnSetHome;
206 215
207 216/* avatar is still a child here position is unknown
208 EntityBase presenceEntity; 217 EntityBase presenceEntity;
209 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 218 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
210 { 219 {
211 SendLandUpdate((ScenePresence)presenceEntity, true); 220 SendLandUpdate((ScenePresence)presenceEntity, true);
212 SendParcelOverlay(client); 221 SendParcelOverlay(client);
213 } 222 }
223*/
214 } 224 }
215 225
216 public void EventMakeChildAgent(ScenePresence avatar) 226 public void EventMakeChildAgent(ScenePresence avatar)
@@ -220,48 +230,6 @@ namespace OpenSim.Region.CoreModules.World.Land
220 230
221 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 231 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
222 { 232 {
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 } 233 }
266 234
267 public void Close() 235 public void Close()
@@ -314,6 +282,7 @@ namespace OpenSim.Region.CoreModules.World.Land
314 { 282 {
315 m_landList.Clear(); 283 m_landList.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 }
@@ -324,16 +293,16 @@ namespace OpenSim.Region.CoreModules.World.Land
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 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
334 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 303 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
335 304
336 return AddLandObject(fullSimParcel); 305 return AddLandObject(fullSimParcel);
337 } 306 }
338 307
339 public List<ILandObject> AllParcels() 308 public List<ILandObject> AllParcels()
@@ -382,10 +351,17 @@ namespace OpenSim.Region.CoreModules.World.Land
382 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 351 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
383 { 352 {
384 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 353 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
385 if (position.HasValue) 354
386 { 355 if (!position.HasValue)
387 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 356 return;
388 } 357
358// land should have no word on avatar physics
359// bool isFlying = avatar.PhysicsActor.Flying;
360// avatar.RemoveFromPhysicalScene();
361
362 avatar.AbsolutePosition = (Vector3)position;
363
364// avatar.AddToPhysicalScene(isFlying);
389 } 365 }
390 366
391 public void SendYouAreRestrictedNotice(ScenePresence avatar) 367 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -405,36 +381,14 @@ namespace OpenSim.Region.CoreModules.World.Land
405 } 381 }
406 382
407 if (parcelAvatarIsEntering != null) 383 if (parcelAvatarIsEntering != null)
408 { 384 EnforceBans(parcelAvatarIsEntering, avatar);
409 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
410 {
411 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
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 }
431 } 385 }
432 } 386 }
433 387
434 public void SendOutNearestBanLine(IClientAPI client) 388 public void SendOutNearestBanLine(IClientAPI client)
435 { 389 {
436 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 390 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
437 if (sp == null || sp.IsChildAgent) 391 if (sp == null)
438 return; 392 return;
439 393
440 List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition); 394 List<ILandObject> checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition);
@@ -454,32 +408,44 @@ namespace OpenSim.Region.CoreModules.World.Land
454 return; 408 return;
455 } 409 }
456 410
411 public void sendClientInitialLandInfo(IClientAPI remoteClient)
412 {
413 ScenePresence avatar;
414
415 if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out avatar))
416 return;
417
418
419 if (!avatar.IsChildAgent)
420 {
421 ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
422 if (over == null)
423 return;
424
425 avatar.currentParcelUUID = over.LandData.GlobalID;
426 over.SendLandUpdateToClient(avatar.ControllingClient);
427 }
428 SendParcelOverlay(remoteClient);
429 }
430
457 public void SendLandUpdate(ScenePresence avatar, bool force) 431 public void SendLandUpdate(ScenePresence avatar, bool force)
458 { 432 {
459 ILandObject over = GetLandObject((int)Math.Min(((int)m_scene.RegionInfo.RegionSizeX - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 433 if (avatar.IsChildAgent)
460 (int)Math.Min(((int)m_scene.RegionInfo.RegionSizeY - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 434 return;
435
436 ILandObject over = GetLandObjectClipedXY(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
461 437
462 if (over != null) 438 if (over != null)
463 { 439 {
464 if (force) 440 bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID);
465 { 441 if (force || NotsameID)
466 if (!avatar.IsChildAgent)
467 {
468 over.SendLandUpdateToClient(avatar.ControllingClient);
469 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
470 m_scene.RegionInfo.RegionID);
471 }
472 }
473
474 if (avatar.currentParcelUUID != over.LandData.GlobalID)
475 { 442 {
476 if (!avatar.IsChildAgent) 443 over.SendLandUpdateToClient(avatar.ControllingClient);
477 { 444// sl doesnt seem to send this now, as it used 2
478 over.SendLandUpdateToClient(avatar.ControllingClient); 445// SendParcelOverlay(avatar.ControllingClient);
479 avatar.currentParcelUUID = over.LandData.GlobalID; 446 avatar.currentParcelUUID = over.LandData.GlobalID;
480 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, 447 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
481 m_scene.RegionInfo.RegionID); 448 m_scene.RegionInfo.RegionID);
482 }
483 } 449 }
484 } 450 }
485 } 451 }
@@ -531,6 +497,7 @@ namespace OpenSim.Region.CoreModules.World.Land
531 //when we are finally in a safe place, lets release the forced position lock 497 //when we are finally in a safe place, lets release the forced position lock
532 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 498 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
533 } 499 }
500 EnforceBans(parcel, clientAvatar);
534 } 501 }
535 } 502 }
536 503
@@ -589,7 +556,7 @@ namespace OpenSim.Region.CoreModules.World.Land
589 requiredPowers = GroupPowers.LandManageBanned; 556 requiredPowers = GroupPowers.LandManageBanned;
590 557
591 if (m_scene.Permissions.CanEditParcelProperties(agentID, 558 if (m_scene.Permissions.CanEditParcelProperties(agentID,
592 land, requiredPowers)) 559 land, requiredPowers, false))
593 { 560 {
594 land.UpdateAccessList(flags, transactionID, sequenceID, 561 land.UpdateAccessList(flags, transactionID, sequenceID,
595 sections, entries, remote_client); 562 sections, entries, remote_client);
@@ -623,14 +590,11 @@ namespace OpenSim.Region.CoreModules.World.Land
623 new_land.LandData.LocalID = newLandLocalID; 590 new_land.LandData.LocalID = newLandLocalID;
624 591
625 bool[,] landBitmap = new_land.GetLandBitmap(); 592 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)) 593 if (landBitmap.GetLength(0) != m_landIDList.GetLength(0) || landBitmap.GetLength(1) != m_landIDList.GetLength(1))
630 { 594 {
631 // Going to variable sized regions can cause mismatches 595 // 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})", 596 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) ); 597 LogHeader, landBitmap.GetLength(0), landBitmap.GetLength(1), m_landIDList.GetLength(0), m_landIDList.GetLength(1));
634 } 598 }
635 else 599 else
636 { 600 {
@@ -652,7 +616,7 @@ namespace OpenSim.Region.CoreModules.World.Land
652 { 616 {
653 m_log.ErrorFormat( 617 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}", 618 "{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, 619 LogHeader, new_land.LandData.Name, new_land.LandData.LocalID, x, y,
656 lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name); 620 lastRecordedLo.LandData.Name, lastRecordedLo.LandData.LocalID, m_scene.Name);
657 621
658 return null; 622 return null;
@@ -668,10 +632,10 @@ namespace OpenSim.Region.CoreModules.World.Land
668 { 632 {
669 if (landBitmap[x, y]) 633 if (landBitmap[x, y])
670 { 634 {
671 // m_log.DebugFormat( 635 // m_log.DebugFormat(
672 // "[LAND MANAGEMENT MODULE]: Registering parcel {0} for land co-ord ({1}, {2}) on {3}", 636 // "[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); 637 // new_land.LandData.Name, x, y, m_scene.RegionInfo.RegionName);
674 638
675 m_landIDList[x, y] = newLandLocalID; 639 m_landIDList[x, y] = newLandLocalID;
676 } 640 }
677 } 641 }
@@ -723,27 +687,28 @@ namespace OpenSim.Region.CoreModules.World.Land
723 /// </summary> 687 /// </summary>
724 public void Clear(bool setupDefaultParcel) 688 public void Clear(bool setupDefaultParcel)
725 { 689 {
726 List<ILandObject> parcels; 690 Dictionary<int, ILandObject> landworkList;
691 // move to work pointer since we are deleting it all
727 lock (m_landList) 692 lock (m_landList)
728 { 693 {
729 parcels = new List<ILandObject>(m_landList.Values); 694 landworkList = m_landList;
695 m_landList = new Dictionary<int, ILandObject>();
730 } 696 }
731 697
732 foreach (ILandObject lo in parcels) 698 // this 2 methods have locks (now)
699 ResetSimLandObjects();
700
701 if (setupDefaultParcel)
702 CreateDefaultParcel();
703
704 // fire outside events unlocked
705 foreach (ILandObject lo in landworkList.Values)
733 { 706 {
734 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 707 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
735 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); 708 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
736 } 709 }
710 landworkList.Clear();
737 711
738 lock (m_landList)
739 {
740 m_landList.Clear();
741
742 ResetSimLandObjects();
743 }
744
745 if (setupDefaultParcel)
746 CreateDefaultParcel();
747 } 712 }
748 713
749 private void performFinalLandJoin(ILandObject master, ILandObject slave) 714 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -787,58 +752,37 @@ namespace OpenSim.Region.CoreModules.World.Land
787 /// <returns>Land object at the point supplied</returns> 752 /// <returns>Land object at the point supplied</returns>
788 public ILandObject GetLandObject(float x_float, float y_float) 753 public ILandObject GetLandObject(float x_float, float y_float)
789 { 754 {
790 return GetLandObject((int)x_float, (int)y_float, true /* returnNullIfLandObjectNotFound */); 755 return GetLandObject((int)x_float, (int)y_float, true);
791 /* 756 }
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 757
798 try 758 // if x,y is off region this will return the parcel at cliped x,y
799 { 759 // as did code it replaces
800 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / (float)landUnit)); 760 public ILandObject GetLandObjectClipedXY(float x, float y)
801 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / (float)landUnit)); 761 {
802 } 762 //do clip inline
803 catch (OverflowException) 763 int avx = (int)x;
804 { 764 if (avx < 0)
805 return null; 765 avx = 0;
806 } 766 else if (avx >= m_scene.RegionInfo.RegionSizeX)
767 avx = (int)Constants.RegionSize - 1;
807 768
808 if (x >= (m_scene.RegionInfo.RegionSizeX / landUnit) 769 int avy = (int)y;
809 || y >= (m_scene.RegionInfo.RegionSizeY / landUnit) 770 if (avy < 0)
810 || x < 0 771 avy = 0;
811 || y < 0) 772 else if (avy >= m_scene.RegionInfo.RegionSizeY)
812 { 773 avy = (int)Constants.RegionSize - 1;
813 return null;
814 }
815 774
816 lock (m_landList) 775 lock (m_landIDList)
817 { 776 {
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 777 try
829 { 778 {
830 if (m_landList.ContainsKey(m_landIDList[x, y])) 779 return m_landList[m_landIDList[avx / LandUnit, avy / LandUnit]];
831 return m_landList[m_landIDList[x, y]];
832 } 780 }
833 catch (Exception e) 781 catch (IndexOutOfRangeException)
834 { 782 {
835 m_log.DebugFormat("{0} GetLandObject exception. x={1}, y={2}, m_landIDList.len=({3},{4})", 783 return null;
836 LogHeader, x, y, m_landIDList.GetLength(0), m_landIDList.GetLength(1));
837 } 784 }
838
839 return null;
840 } 785 }
841 */
842 } 786 }
843 787
844 // Public entry. 788 // Public entry.
@@ -848,30 +792,28 @@ namespace OpenSim.Region.CoreModules.World.Land
848 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */); 792 return GetLandObject(x, y, false /* returnNullIfLandObjectNotFound */);
849 } 793 }
850 794
851 /// <summary> 795 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 { 796 {
864 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0) 797 if (x >= m_scene.RegionInfo.RegionSizeX || y >= m_scene.RegionInfo.RegionSizeY || x < 0 || y < 0)
865 { 798 {
866 // These exceptions here will cause a lot of complaints from the users specifically because 799 // These exceptions here will cause a lot of complaints from the users specifically because
867 // they happen every time at border crossings 800 // they happen every time at border crossings
868 if (returnNullIfLandObjectOutsideBounds) 801 if (returnNullIfLandObjectOutsideBounds)
869 return null; 802 return null;
870 else 803 else
871 throw new Exception( 804 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}", 805 }
873 LogHeader, m_scene.RegionInfo.RegionName, x, y) 806
874 ); 807 lock (m_landIDList)
808 {
809 try
810 {
811 return m_landList[m_landIDList[x / 4, y / 4]];
812 }
813 catch (IndexOutOfRangeException)
814 {
815 return null;
816 }
875 } 817 }
876 818
877 return m_landList[m_landIDList[x / 4, y / 4]]; 819 return m_landList[m_landIDList[x / 4, y / 4]];
@@ -1033,7 +975,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1033 975
1034 //If we are still here, then they are subdividing within one piece of land 976 //If we are still here, then they are subdividing within one piece of land
1035 //Check owner 977 //Check owner
1036 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin)) 978 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin, true))
1037 { 979 {
1038 return; 980 return;
1039 } 981 }
@@ -1043,6 +985,8 @@ namespace OpenSim.Region.CoreModules.World.Land
1043 newLand.LandData.Name = newLand.LandData.Name; 985 newLand.LandData.Name = newLand.LandData.Name;
1044 newLand.LandData.GlobalID = UUID.Random(); 986 newLand.LandData.GlobalID = UUID.Random();
1045 newLand.LandData.Dwell = 0; 987 newLand.LandData.Dwell = 0;
988 // Clear "Show in search" on the cut out parcel to prevent double-charging
989 newLand.LandData.Flags &= ~(uint)ParcelFlags.ShowDirectory;
1046 990
1047 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); 991 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));
1048 992
@@ -1058,11 +1002,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1058 //Now add the new land object 1002 //Now add the new land object
1059 ILandObject result = AddLandObject(newLand); 1003 ILandObject result = AddLandObject(newLand);
1060 1004
1061 if (result != null) 1005 UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData);
1062 { 1006 result.SendLandUpdateToAvatarsOverMe();
1063 UpdateLandObject(startLandObject.LandData.LocalID, startLandObject.LandData); 1007 startLandObject.SendLandUpdateToAvatarsOverMe();
1064 result.SendLandUpdateToAvatarsOverMe(); 1008 m_scene.ForEachClient(SendParcelOverlay);
1065 } 1009
1066 } 1010 }
1067 1011
1068 /// <summary> 1012 /// <summary>
@@ -1104,7 +1048,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1104 { 1048 {
1105 return; 1049 return;
1106 } 1050 }
1107 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin)) 1051 if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin, true))
1108 { 1052 {
1109 return; 1053 return;
1110 } 1054 }
@@ -1127,6 +1071,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1127 } 1071 }
1128 1072
1129 masterLandObject.SendLandUpdateToAvatarsOverMe(); 1073 masterLandObject.SendLandUpdateToAvatarsOverMe();
1074 m_scene.ForEachClient(SendParcelOverlay);
1130 } 1075 }
1131 1076
1132 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) 1077 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
@@ -1143,12 +1088,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1143 1088
1144 #region Parcel Updating 1089 #region Parcel Updating
1145 1090
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> 1091 /// <summary>
1153 /// Send the parcel overlay blocks to the client. We send the overlay packets 1092 /// Send the parcel overlay blocks to the client. We send the overlay packets
1154 /// around a location and limited by the 'parcelLayerViewDistance'. This number 1093 /// around a location and limited by the 'parcelLayerViewDistance'. This number
@@ -1162,145 +1101,116 @@ namespace OpenSim.Region.CoreModules.World.Land
1162 /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param> 1101 /// <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> 1102 /// <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> 1103 /// <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) 1104 public void SendParcelOverlay(IClientAPI remote_client)
1166 { 1105 {
1106 if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
1107 return;
1108
1167 const int LAND_BLOCKS_PER_PACKET = 1024; 1109 const int LAND_BLOCKS_PER_PACKET = 1024;
1168 1110
1169 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1111 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1170 int byteArrayCount = 0; 1112 int byteArrayCount = 0;
1171 int sequenceID = 0; 1113 int sequenceID = 0;
1172 1114
1173 int xLow = 0; 1115 // Layer data is in LandUnit (4m) chunks
1174 int xHigh = (int)m_scene.RegionInfo.RegionSizeX; 1116 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 { 1117 {
1180 // Compute view distance around the given point 1118 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 {
1186 txLow = xLow;
1187 txHigh = Math.Min(yLow + (layerViewDistance * 2), xHigh);
1188 }
1189 if (txHigh > xHigh)
1190 { 1119 {
1191 txLow = Math.Max(xLow, xHigh - (layerViewDistance * 2)); 1120 byte tempByte = 0; //This represents the byte for the current 4x4
1192 txHigh = xHigh;
1193 }
1194 xLow = txLow;
1195 xHigh = txHigh;
1196 1121
1197 int tyLow = yPlace - layerViewDistance; 1122 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 1123
1215 // Layer data is in landUnit (4m) chunks 1124 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 { 1125 {
1224 // m_log.DebugFormat("{0} SendParcelOverlay, sending packet, bytes={1}", LogHeader, byteArray.Length); 1126 // types
1225 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1127 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
1226 byteArrayCount = 0; 1128 {
1227 sequenceID++; 1129 //Owner Flag
1228 byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 1130 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
1229 } 1131 }
1132 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1133 {
1134 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP;
1135 }
1136 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1137 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1138 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
1139 {
1140 //Sale type
1141 tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE;
1142 }
1143 else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
1144 {
1145 //Public type
1146 tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
1147 }
1148 // LAND_TYPE_IS_BEING_AUCTIONED still unsuported
1149 else
1150 {
1151 //Other Flag
1152 tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER;
1153 }
1230 1154
1231 } 1155 // now flags
1232 } 1156 // border control
1233 1157
1234 if (byteArrayCount != 0) 1158 ILandObject westParcel = null;
1235 { 1159 ILandObject southParcel = null;
1236 remote_client.SendLandParcelOverlay(byteArray, sequenceID); 1160 if (x > 0)
1237 // m_log.DebugFormat("{0} SendParcelOverlay, complete sending packet, bytes={1}", LogHeader, byteArray.Length); 1161 {
1238 } 1162 westParcel = GetLandObject((x - 1), y);
1239 } 1163 }
1164 if (y > 0)
1165 {
1166 southParcel = GetLandObject(x, (y - 1));
1167 }
1240 1168
1241 private byte BuildLayerByte(ILandObject currentParcelBlock, int x, int y, IClientAPI remote_client) 1169 if (x == 0)
1242 { 1170 {
1243 byte tempByte = 0; //This represents the byte for the current 4x4 1171 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
1172 }
1173 else if (westParcel != null && westParcel != currentParcelBlock)
1174 {
1175 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
1176 }
1244 1177
1245 if (currentParcelBlock != null) 1178 if (y == 0)
1246 { 1179 {
1247 if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId) 1180 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
1248 { 1181 }
1249 //Owner Flag 1182 else if (southParcel != null && southParcel != currentParcelBlock)
1250 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1183 {
1251 } 1184 tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
1252 else if (currentParcelBlock.LandData.SalePrice > 0 && 1185 }
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 1186
1270 //Now for border control 1187 // local sound
1188 if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
1189 tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
1271 1190
1272 ILandObject westParcel = null; 1191 // hide avatars
1273 ILandObject southParcel = null; 1192 if (!currentParcelBlock.LandData.SeeAVs)
1274 if (x > 0) 1193 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 1194
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 1195
1292 if (y == 0) 1196 byteArray[byteArrayCount] = tempByte;
1293 { 1197 byteArrayCount++;
1294 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1198 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
1295 } 1199 {
1296 else if (southParcel != null && southParcel != currentParcelBlock) 1200 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1297 { 1201 byteArrayCount = 0;
1298 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH); 1202 sequenceID++;
1203 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
1204 }
1205 }
1299 } 1206 }
1300 1207
1301 } 1208 }
1302 1209
1303 return tempByte; 1210 if (byteArrayCount > 0)
1211 {
1212 remote_client.SendLandParcelOverlay(byteArray, sequenceID);
1213 }
1304 } 1214 }
1305 1215
1306 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 1216 public void ClientOnParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
@@ -1320,8 +1230,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1320 { 1230 {
1321 if (!temp.Contains(currentParcel)) 1231 if (!temp.Contains(currentParcel))
1322 { 1232 {
1323 currentParcel.ForceUpdateLandInfo(); 1233 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1324 temp.Add(currentParcel); 1234 {
1235 currentParcel.ForceUpdateLandInfo();
1236 temp.Add(currentParcel);
1237 }
1325 } 1238 }
1326 } 1239 }
1327 } 1240 }
@@ -1338,8 +1251,45 @@ namespace OpenSim.Region.CoreModules.World.Land
1338 temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client); 1251 temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
1339 } 1252 }
1340 1253
1341 // Also send the layer data around the point of interest 1254// SendParcelOverlay(remote_client);
1342 SendParcelOverlay(remote_client, (start_x + end_x) / 2, (start_y + end_y) / 2, parcelLayerViewDistance); 1255 }
1256
1257 public void UpdateLandProperties(ILandObject land, LandUpdateArgs args, IClientAPI remote_client)
1258 {
1259 bool snap_selection = false;
1260 bool needOverlay = false;
1261 if (land.UpdateLandProperties(args, remote_client, out snap_selection, out needOverlay))
1262 {
1263 //the proprieties to who changed them
1264 ScenePresence av = m_scene.GetScenePresence(remote_client.AgentId);
1265 if(av.IsChildAgent || land != GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y))
1266 land.SendLandProperties(-10000, false, LandChannel.LAND_RESULT_SINGLE, remote_client);
1267 else
1268 land.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, remote_client);
1269
1270 UUID parcelID = land.LandData.GlobalID;
1271 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
1272 {
1273 if (avatar.IsDeleted || avatar.isNPC)
1274 return;
1275
1276 IClientAPI client = avatar.ControllingClient;
1277 if (needOverlay)
1278 SendParcelOverlay(client);
1279
1280 if (avatar.IsChildAgent)
1281 return;
1282
1283 ILandObject aland = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
1284 if (aland != null)
1285 {
1286 if (client != remote_client && land == aland)
1287 aland.SendLandProperties(0, false, LandChannel.LAND_RESULT_SINGLE, client);
1288 }
1289 if (avatar.currentParcelUUID == parcelID)
1290 avatar.currentParcelUUID = parcelID; // force parcel flags review
1291 });
1292 }
1343 } 1293 }
1344 1294
1345 public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) 1295 public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client)
@@ -1352,7 +1302,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1352 1302
1353 if (land != null) 1303 if (land != null)
1354 { 1304 {
1355 land.UpdateLandProperties(args, remote_client); 1305 UpdateLandProperties(land, args, remote_client);
1356 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client); 1306 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client);
1357 } 1307 }
1358 } 1308 }
@@ -1408,7 +1358,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1408 land.LandData.GroupID = UUID.Zero; 1358 land.LandData.GroupID = UUID.Zero;
1409 land.LandData.IsGroupOwned = false; 1359 land.LandData.IsGroupOwned = false;
1410 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1360 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1411
1412 m_scene.ForEachClient(SendParcelOverlay); 1361 m_scene.ForEachClient(SendParcelOverlay);
1413 land.SendLandUpdateToClient(true, remote_client); 1362 land.SendLandUpdateToClient(true, remote_client);
1414 UpdateLandObject(land.LandData.LocalID, land.LandData); 1363 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1459,7 +1408,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1459 land.LandData.SalePrice = 0; 1408 land.LandData.SalePrice = 0;
1460 land.LandData.AuthBuyerID = UUID.Zero; 1409 land.LandData.AuthBuyerID = UUID.Zero;
1461 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 1410 land.LandData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
1462
1463 m_scene.ForEachClient(SendParcelOverlay); 1411 m_scene.ForEachClient(SendParcelOverlay);
1464 land.SendLandUpdateToClient(true, remote_client); 1412 land.SendLandUpdateToClient(true, remote_client);
1465 UpdateLandObject(land.LandData.LocalID, land.LandData); 1413 UpdateLandObject(land.LandData.LocalID, land.LandData);
@@ -1545,17 +1493,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1545 1493
1546 private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1494 private void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1547 { 1495 {
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) 1496 lock (m_landList)
1554 { 1497 {
1555 for (int i = 0; i < data.Count; i++) 1498 for (int i = 0; i < data.Count; i++)
1556 IncomingLandObjectFromStorage(data[i]); 1499 IncomingLandObjectFromStorage(data[i]);
1557 1500
1558 // Layer data is in landUnit (4m) chunks 1501 // Layer data is in LandUnit (4m) chunks
1559 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) 1502 for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++)
1560 { 1503 {
1561 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) 1504 for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++)
@@ -1565,7 +1508,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1565 if (m_landList.Count == 1) 1508 if (m_landList.Count == 1)
1566 { 1509 {
1567 m_log.DebugFormat( 1510 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}", 1511 "[{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); 1512 LogHeader, x, y, m_scene.Name);
1570 1513
1571 int onlyParcelID = 0; 1514 int onlyParcelID = 0;
@@ -1588,11 +1531,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1588 else if (m_landList.Count > 1) 1531 else if (m_landList.Count > 1)
1589 { 1532 {
1590 m_log.DebugFormat( 1533 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}", 1534 "{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); 1535 LogHeader, x, y, m_scene.Name);
1593 1536
1594 // There are several other parcels so we must create a new one for the unassigned space 1537 // 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); 1538 ILandObject newLand = new LandObject(UUID.Zero, false, m_scene);
1596 // Claim all the unclaimed "0" ids 1539 // Claim all the unclaimed "0" ids
1597 newLand.SetLandBitmap(CreateBitmapForID(0)); 1540 newLand.SetLandBitmap(CreateBitmapForID(0));
1598 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 1541 newLand.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@@ -1603,7 +1546,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1603 { 1546 {
1604 // We should never reach this point as the separate code path when no land data exists should have fired instead. 1547 // We should never reach this point as the separate code path when no land data exists should have fired instead.
1605 m_log.WarnFormat( 1548 m_log.WarnFormat(
1606 "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present", 1549 "{0}: Ignoring request to auto-create parcel in {1} as there are no other parcels present",
1607 LogHeader, m_scene.Name); 1550 LogHeader, m_scene.Name);
1608 } 1551 }
1609 } 1552 }
@@ -1614,9 +1557,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1614 1557
1615 private void IncomingLandObjectFromStorage(LandData data) 1558 private void IncomingLandObjectFromStorage(LandData data)
1616 { 1559 {
1617 ILandObject new_land = new LandObject(data, m_scene); 1560 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1561 new_land.LandData = data.Copy();
1562
1618 new_land.SetLandBitmapFromByteArray(); 1563 new_land.SetLandBitmapFromByteArray();
1619 AddLandObject(new_land); 1564 AddLandObject(new_land);
1565// new_land.SendLandUpdateToAvatarsOverMe();
1620 } 1566 }
1621 1567
1622 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1568 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1773,6 +1719,19 @@ namespace OpenSim.Region.CoreModules.World.Land
1773 land_update.ObscureMusic = properties.ObscureMusic; 1719 land_update.ObscureMusic = properties.ObscureMusic;
1774 land_update.ObscureMedia = properties.ObscureMedia; 1720 land_update.ObscureMedia = properties.ObscureMedia;
1775 1721
1722 if (args.ContainsKey("see_avs"))
1723 {
1724 land_update.SeeAVs = args["see_avs"].AsBoolean();
1725 land_update.AnyAVSounds = args["any_av_sounds"].AsBoolean();
1726 land_update.GroupAVSounds = args["group_av_sounds"].AsBoolean();
1727 }
1728 else
1729 {
1730 land_update.SeeAVs = true;
1731 land_update.AnyAVSounds = true;
1732 land_update.GroupAVSounds = true;
1733 }
1734
1776 ILandObject land; 1735 ILandObject land;
1777 lock (m_landList) 1736 lock (m_landList)
1778 { 1737 {
@@ -1781,13 +1740,14 @@ namespace OpenSim.Region.CoreModules.World.Land
1781 1740
1782 if (land != null) 1741 if (land != null)
1783 { 1742 {
1784 land.UpdateLandProperties(land_update, client); 1743 UpdateLandProperties(land,land_update, client);
1785 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client); 1744 m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client);
1786 } 1745 }
1787 else 1746 else
1788 { 1747 {
1789 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID); 1748 m_log.WarnFormat("[LAND MANAGEMENT MODULE]: Unable to find parcelID {0}", parcelID);
1790 } 1749 }
1750
1791 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); 1751 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
1792 } 1752 }
1793 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the 1753 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the
@@ -1940,14 +1900,93 @@ namespace OpenSim.Region.CoreModules.World.Land
1940 1900
1941 if (land == null) return; 1901 if (land == null) return;
1942 1902
1943 if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions)) 1903 if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions, false))
1944 return; 1904 return;
1945 1905
1946 land.LandData.OtherCleanTime = otherCleanTime; 1906 land.LandData.OtherCleanTime = otherCleanTime;
1947 1907
1948 UpdateLandObject(localID, land.LandData); 1908 UpdateLandObject(localID, land.LandData);
1949 } 1909 }
1950 1910
1911 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1912 {
1913 ILandObject land = null;
1914 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1915 foreach (ILandObject landObject in Land)
1916 {
1917 if (landObject.LandData.LocalID == landID)
1918 {
1919 land = landObject;
1920 }
1921 }
1922 land.DeedToGroup(DefaultGodParcelGroup);
1923 land.LandData.Name = DefaultGodParcelName;
1924 land.SendLandUpdateToAvatarsOverMe();
1925 }
1926
1927 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1928 {
1929 ScenePresence SP;
1930 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1931 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1932 if (SP.UserLevel != 0)
1933 {
1934 if (flags == 0) //All parcels, scripted or not
1935 {
1936 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1937 {
1938 if (e.OwnerID == targetID)
1939 {
1940 returns.Add(e);
1941 }
1942 }
1943 );
1944 }
1945 if (flags == 4) //All parcels, scripted object
1946 {
1947 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1948 {
1949 if (e.OwnerID == targetID)
1950 {
1951 if (e.ContainsScripts())
1952 {
1953 returns.Add(e);
1954 }
1955 }
1956 }
1957 );
1958 }
1959 if (flags == 4) //not target parcel, scripted object
1960 {
1961 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1962 {
1963 if (e.OwnerID == targetID)
1964 {
1965 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1966 if (landobject.LandData.OwnerID != e.OwnerID)
1967 {
1968 if (e.ContainsScripts())
1969 {
1970 returns.Add(e);
1971 }
1972 }
1973 }
1974 }
1975 );
1976 }
1977 foreach (SceneObjectGroup ol in returns)
1978 {
1979 ReturnObject(ol, client);
1980 }
1981 }
1982 }
1983 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1984 {
1985 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1986 objs[0] = obj;
1987 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1988 }
1989
1951 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); 1990 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1952 1991
1953 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 1992 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
@@ -1961,7 +2000,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1961 if (targetAvatar.UserLevel == 0) 2000 if (targetAvatar.UserLevel == 0)
1962 { 2001 {
1963 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); 2002 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)) 2003 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true))
1965 return; 2004 return;
1966 if (flags == 0) 2005 if (flags == 0)
1967 { 2006 {
@@ -1983,7 +2022,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1983 } 2022 }
1984 } 2023 }
1985 } 2024 }
1986
1987 private void OnEndParcelFrozen(object avatar) 2025 private void OnEndParcelFrozen(object avatar)
1988 { 2026 {
1989 ScenePresence targetAvatar = (ScenePresence)avatar; 2027 ScenePresence targetAvatar = (ScenePresence)avatar;
@@ -1994,6 +2032,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1994 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); 2032 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1995 } 2033 }
1996 2034
2035
1997 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 2036 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1998 { 2037 {
1999 ScenePresence targetAvatar = null; 2038 ScenePresence targetAvatar = null;
@@ -2010,15 +2049,16 @@ namespace OpenSim.Region.CoreModules.World.Land
2010 2049
2011 // Check if you even have permission to do this 2050 // Check if you even have permission to do this
2012 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); 2051 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
2013 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && 2052 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true) &&
2014 !m_scene.Permissions.IsAdministrator(client.AgentId)) 2053 !m_scene.Permissions.IsAdministrator(client.AgentId))
2015 return; 2054 return;
2055
2016 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); 2056 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
2017 2057
2018 targetAvatar.TeleportWithMomentum(pos, null); 2058 targetAvatar.TeleportWithMomentum(pos, null);
2019 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); 2059 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
2020 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); 2060 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
2021 2061
2022 if ((flags & 1) != 0) // Ban TODO: Remove magic number 2062 if ((flags & 1) != 0) // Ban TODO: Remove magic number
2023 { 2063 {
2024 LandAccessEntry entry = new LandAccessEntry(); 2064 LandAccessEntry entry = new LandAccessEntry();
@@ -2171,37 +2211,50 @@ namespace OpenSim.Region.CoreModules.World.Land
2171 2211
2172 private void AppendParcelsSummaryReport(StringBuilder report) 2212 private void AppendParcelsSummaryReport(StringBuilder report)
2173 { 2213 {
2174 report.AppendFormat("Land information for {0}\n", m_scene.Name); 2214 report.AppendFormat("Land information for {0}\n", m_scene.RegionInfo.RegionName);
2175 2215 report.AppendFormat(
2176 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 2216 "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n",
2177 cdt.AddColumn("Parcel Name", ConsoleDisplayUtil.ParcelNameSize); 2217 "Parcel Name",
2178 cdt.AddColumn("ID", 3); 2218 "Local ID",
2179 cdt.AddColumn("Area", 6); 2219 "Area",
2180 cdt.AddColumn("Starts", ConsoleDisplayUtil.VectorSize); 2220 "AABBMin",
2181 cdt.AddColumn("Ends", ConsoleDisplayUtil.VectorSize); 2221 "AABBMax",
2182 cdt.AddColumn("Owner", ConsoleDisplayUtil.UserNameSize); 2222 "Owner");
2183 2223
2184 lock (m_landList) 2224 lock (m_landList)
2185 { 2225 {
2186 foreach (ILandObject lo in m_landList.Values) 2226 foreach (ILandObject lo in m_landList.Values)
2187 { 2227 {
2188 LandData ld = lo.LandData; 2228 LandData ld = lo.LandData;
2189 string ownerName; 2229
2190 if (ld.IsGroupOwned) 2230 report.AppendFormat(
2191 { 2231 "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n",
2192 GroupRecord rec = m_groupManager.GetGroupRecord(ld.GroupID); 2232 ld.Name, ld.LocalID, ld.Area, ld.AABBMin, ld.AABBMax, m_userManager.GetUserName(ld.OwnerID));
2193 ownerName = (rec != null) ? rec.GroupName : "Unknown Group";
2194 }
2195 else
2196 {
2197 ownerName = m_userManager.GetUserName(ld.OwnerID);
2198 }
2199 cdt.AddRow(
2200 ld.Name, ld.LocalID, ld.Area, lo.StartPoint, lo.EndPoint, ownerName);
2201 } 2233 }
2202 } 2234 }
2235
2236 }
2237
2238 public void EnforceBans(ILandObject land, ScenePresence avatar)
2239 {
2240 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
2241 return;
2203 2242
2204 report.Append(cdt.ToString()); 2243 if (land.IsEitherBannedOrRestricted(avatar.UUID))
2244 {
2245 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
2246 {
2247 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
2248 if (pos == null)
2249 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
2250 else
2251 ForceAvatarToPosition(avatar, (Vector3)pos);
2252 }
2253 else
2254 {
2255 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
2256 }
2257 }
2205 } 2258 }
2206 2259
2207 private void AppendParcelReport(StringBuilder report, ILandObject lo) 2260 private void AppendParcelReport(StringBuilder report, ILandObject lo)
@@ -2214,8 +2267,6 @@ namespace OpenSim.Region.CoreModules.World.Land
2214 cdl.AddRow("Description", ld.Description); 2267 cdl.AddRow("Description", ld.Description);
2215 cdl.AddRow("Snapshot ID", ld.SnapshotID); 2268 cdl.AddRow("Snapshot ID", ld.SnapshotID);
2216 cdl.AddRow("Area", ld.Area); 2269 cdl.AddRow("Area", ld.Area);
2217 cdl.AddRow("Starts", lo.StartPoint);
2218 cdl.AddRow("Ends", lo.EndPoint);
2219 cdl.AddRow("AABB Min", ld.AABBMin); 2270 cdl.AddRow("AABB Min", ld.AABBMin);
2220 cdl.AddRow("AABB Max", ld.AABBMax); 2271 cdl.AddRow("AABB Max", ld.AABBMax);
2221 string ownerName; 2272 string ownerName;
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index a0c1b9d..040c90b 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -50,7 +50,8 @@ namespace OpenSim.Region.CoreModules.World.Land
50 private readonly int landUnit = 4; 50 private readonly int landUnit = 4;
51 51
52 private int m_lastSeqId = 0; 52 private int m_lastSeqId = 0;
53 53 private int m_expiryCounter = 0;
54
54 protected Scene m_scene; 55 protected Scene m_scene;
55 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
56 protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); 57 protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
@@ -58,7 +59,12 @@ namespace OpenSim.Region.CoreModules.World.Land
58 protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>(); 59 protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
59 protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds 60 protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
60 61
61 public bool[,] LandBitmap { get; set; } 62 private bool[,] m_landBitmap;
63 public bool[,] LandBitmap
64 {
65 get { return m_landBitmap; }
66 set { m_landBitmap = value; }
67 }
62 68
63 #endregion 69 #endregion
64 70
@@ -69,7 +75,13 @@ namespace OpenSim.Region.CoreModules.World.Land
69 return free; 75 return free;
70 } 76 }
71 77
72 public LandData LandData { get; set; } 78 protected LandData m_landData;
79 public LandData LandData
80 {
81 get { return m_landData; }
82
83 set { m_landData = value; }
84 }
73 85
74 public IPrimCounts PrimCounts { get; set; } 86 public IPrimCounts PrimCounts { get; set; }
75 87
@@ -141,6 +153,8 @@ namespace OpenSim.Region.CoreModules.World.Land
141 else 153 else
142 LandData.GroupID = UUID.Zero; 154 LandData.GroupID = UUID.Zero;
143 LandData.IsGroupOwned = is_group_owned; 155 LandData.IsGroupOwned = is_group_owned;
156
157 m_scene.EventManager.OnFrame += OnFrame;
144 } 158 }
145 159
146 #endregion 160 #endregion
@@ -195,10 +209,27 @@ namespace OpenSim.Region.CoreModules.World.Land
195 else 209 else
196 { 210 {
197 // Normal Calculations 211 // Normal Calculations
198 int parcelMax = (int)(((float)LandData.Area / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)) 212 int parcelMax = (int)( (long)LandData.Area
199 * (float)m_scene.RegionInfo.ObjectCapacity 213 * (long)m_scene.RegionInfo.ObjectCapacity
200 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 214 * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus
201 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! 215 / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) );
216 //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
217 return parcelMax;
218 }
219 }
220
221 private int GetParcelBasePrimCount()
222 {
223 if (overrideParcelMaxPrimCount != null)
224 {
225 return overrideParcelMaxPrimCount(this);
226 }
227 else
228 {
229 // Normal Calculations
230 int parcelMax = (int)((long)LandData.Area
231 * (long)m_scene.RegionInfo.ObjectCapacity
232 / 65536L);
202 return parcelMax; 233 return parcelMax;
203 } 234 }
204 } 235 }
@@ -212,8 +243,10 @@ namespace OpenSim.Region.CoreModules.World.Land
212 else 243 else
213 { 244 {
214 //Normal Calculations 245 //Normal Calculations
215 int simMax = (int)(((float)LandData.SimwideArea / (m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY)) 246 int simMax = (int)( (long)LandData.SimwideArea
216 * (float)m_scene.RegionInfo.ObjectCapacity); 247 * (long)m_scene.RegionInfo.ObjectCapacity
248 / (long)(m_scene.RegionInfo.RegionSizeX * m_scene.RegionInfo.RegionSizeY) );
249 // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax);
217 return simMax; 250 return simMax;
218 } 251 }
219 } 252 }
@@ -224,6 +257,9 @@ namespace OpenSim.Region.CoreModules.World.Land
224 257
225 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) 258 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
226 { 259 {
260 if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
261 return;
262
227 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 263 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
228 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); 264 // uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
229 uint regionFlags = (uint)(RegionFlags.PublicAllowed 265 uint regionFlags = (uint)(RegionFlags.PublicAllowed
@@ -248,14 +284,15 @@ namespace OpenSim.Region.CoreModules.World.Land
248 remote_client.SendLandProperties(seq_id, 284 remote_client.SendLandProperties(seq_id,
249 snap_selection, request_result, this, 285 snap_selection, request_result, this,
250 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 286 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
251 GetParcelMaxPrimCount(), 287 GetParcelBasePrimCount(),
252 GetSimulatorMaxPrimCount(), regionFlags); 288 GetSimulatorMaxPrimCount(), regionFlags);
253 } 289 }
254 290
255 public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) 291 public bool UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client, out bool snap_selection, out bool needOverlay)
256 { 292 {
257 //Needs later group support 293 //Needs later group support
258 bool snap_selection = false; 294 snap_selection = false;
295 needOverlay = false;
259 LandData newData = LandData.Copy(); 296 LandData newData = LandData.Copy();
260 297
261 uint allowedDelta = 0; 298 uint allowedDelta = 0;
@@ -264,7 +301,7 @@ namespace OpenSim.Region.CoreModules.World.Land
264 // ParcelFlags.ForSaleObjects 301 // ParcelFlags.ForSaleObjects
265 // ParcelFlags.LindenHome 302 // ParcelFlags.LindenHome
266 303
267 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 304 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, false))
268 { 305 {
269 allowedDelta |= (uint)(ParcelFlags.AllowLandmark | 306 allowedDelta |= (uint)(ParcelFlags.AllowLandmark |
270 ParcelFlags.AllowTerraform | 307 ParcelFlags.AllowTerraform |
@@ -277,9 +314,12 @@ namespace OpenSim.Region.CoreModules.World.Land
277 ParcelFlags.AllowAPrimitiveEntry | 314 ParcelFlags.AllowAPrimitiveEntry |
278 ParcelFlags.AllowGroupObjectEntry | 315 ParcelFlags.AllowGroupObjectEntry |
279 ParcelFlags.AllowFly); 316 ParcelFlags.AllowFly);
317 newData.SeeAVs = args.SeeAVs;
318 newData.AnyAVSounds = args.AnyAVSounds;
319 newData.GroupAVSounds = args.GroupAVSounds;
280 } 320 }
281 321
282 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale)) 322 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale, true))
283 { 323 {
284 if (args.AuthBuyerID != newData.AuthBuyerID || 324 if (args.AuthBuyerID != newData.AuthBuyerID ||
285 args.SalePrice != newData.SalePrice) 325 args.SalePrice != newData.SalePrice)
@@ -302,30 +342,30 @@ namespace OpenSim.Region.CoreModules.World.Land
302 allowedDelta |= (uint)ParcelFlags.ForSale; 342 allowedDelta |= (uint)ParcelFlags.ForSale;
303 } 343 }
304 344
305 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces)) 345 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces, false))
306 { 346 {
307 newData.Category = args.Category; 347 newData.Category = args.Category;
308 348
309 allowedDelta |= (uint)(ParcelFlags.ShowDirectory | 349 allowedDelta |= (uint)(ParcelFlags.ShowDirectory |
310 ParcelFlags.AllowPublish | 350 ParcelFlags.AllowPublish |
311 ParcelFlags.MaturePublish); 351 ParcelFlags.MaturePublish) | (uint)(1 << 23);
312 } 352 }
313 353
314 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) 354 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity, false))
315 { 355 {
316 newData.Description = args.Desc; 356 newData.Description = args.Desc;
317 newData.Name = args.Name; 357 newData.Name = args.Name;
318 newData.SnapshotID = args.SnapshotID; 358 newData.SnapshotID = args.SnapshotID;
319 } 359 }
320 360
321 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint)) 361 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint, false))
322 { 362 {
323 newData.LandingType = args.LandingType; 363 newData.LandingType = args.LandingType;
324 newData.UserLocation = args.UserLocation; 364 newData.UserLocation = args.UserLocation;
325 newData.UserLookAt = args.UserLookAt; 365 newData.UserLookAt = args.UserLookAt;
326 } 366 }
327 367
328 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia)) 368 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia, false))
329 { 369 {
330 newData.MediaAutoScale = args.MediaAutoScale; 370 newData.MediaAutoScale = args.MediaAutoScale;
331 newData.MediaID = args.MediaID; 371 newData.MediaID = args.MediaID;
@@ -346,7 +386,7 @@ namespace OpenSim.Region.CoreModules.World.Land
346 ParcelFlags.UseEstateVoiceChan); 386 ParcelFlags.UseEstateVoiceChan);
347 } 387 }
348 388
349 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses)) 389 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false))
350 { 390 {
351 newData.PassHours = args.PassHours; 391 newData.PassHours = args.PassHours;
352 newData.PassPrice = args.PassPrice; 392 newData.PassPrice = args.PassPrice;
@@ -354,13 +394,13 @@ namespace OpenSim.Region.CoreModules.World.Land
354 allowedDelta |= (uint)ParcelFlags.UsePassList; 394 allowedDelta |= (uint)ParcelFlags.UsePassList;
355 } 395 }
356 396
357 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed)) 397 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed, false))
358 { 398 {
359 allowedDelta |= (uint)(ParcelFlags.UseAccessGroup | 399 allowedDelta |= (uint)(ParcelFlags.UseAccessGroup |
360 ParcelFlags.UseAccessList); 400 ParcelFlags.UseAccessList);
361 } 401 }
362 402
363 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned)) 403 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned, false))
364 { 404 {
365 allowedDelta |= (uint)(ParcelFlags.UseBanList | 405 allowedDelta |= (uint)(ParcelFlags.UseBanList |
366 ParcelFlags.DenyAnonymous | 406 ParcelFlags.DenyAnonymous |
@@ -372,9 +412,16 @@ namespace OpenSim.Region.CoreModules.World.Land
372 uint preserve = LandData.Flags & ~allowedDelta; 412 uint preserve = LandData.Flags & ~allowedDelta;
373 newData.Flags = preserve | (args.ParcelFlags & allowedDelta); 413 newData.Flags = preserve | (args.ParcelFlags & allowedDelta);
374 414
415 uint curdelta = LandData.Flags ^ newData.Flags;
416 curdelta &= (uint)(ParcelFlags.SoundLocal);
417
418 if(curdelta != 0 || newData.SeeAVs != LandData.SeeAVs)
419 needOverlay = true;
420
375 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 421 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
376 SendLandUpdateToAvatarsOverMe(snap_selection); 422 return true;
377 } 423 }
424 return false;
378 } 425 }
379 426
380 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) 427 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
@@ -395,7 +442,7 @@ namespace OpenSim.Region.CoreModules.World.Land
395 UUID previousOwner = LandData.OwnerID; 442 UUID previousOwner = LandData.OwnerID;
396 443
397 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 444 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
398 m_scene.EventManager.TriggerParcelPrimCountUpdate(); 445// m_scene.EventManager.TriggerParcelPrimCountUpdate();
399 SendLandUpdateToAvatarsOverMe(true); 446 SendLandUpdateToAvatarsOverMe(true);
400 447
401 if (sellObjects) SellLandObjects(previousOwner); 448 if (sellObjects) SellLandObjects(previousOwner);
@@ -568,6 +615,7 @@ namespace OpenSim.Region.CoreModules.World.Land
568 615
569 public void SendLandUpdateToAvatarsOverMe(bool snap_selection) 616 public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
570 { 617 {
618 m_scene.EventManager.TriggerParcelPrimCountUpdate();
571 m_scene.ForEachRootScenePresence(delegate(ScenePresence avatar) 619 m_scene.ForEachRootScenePresence(delegate(ScenePresence avatar)
572 { 620 {
573 ILandObject over = null; 621 ILandObject over = null;
@@ -594,6 +642,7 @@ namespace OpenSim.Region.CoreModules.World.Land
594 avatar.Invulnerable = true; 642 avatar.Invulnerable = true;
595 643
596 SendLandUpdateToClient(snap_selection, avatar.ControllingClient); 644 SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
645 avatar.currentParcelUUID = LandData.GlobalID;
597 } 646 }
598 } 647 }
599 }); 648 });
@@ -722,10 +771,11 @@ namespace OpenSim.Region.CoreModules.World.Land
722 /// </summary> 771 /// </summary>
723 private void UpdateAABBAndAreaValues() 772 private void UpdateAABBAndAreaValues()
724 { 773 {
725 int min_x = 10000; 774
726 int min_y = 10000; 775 int min_x = Int32.MaxValue;
727 int max_x = 0; 776 int min_y = Int32.MaxValue;
728 int max_y = 0; 777 int max_x = Int32.MinValue;
778 int max_y = Int32.MinValue;
729 int tempArea = 0; 779 int tempArea = 0;
730 int x, y; 780 int x, y;
731 for (x = 0; x < LandBitmap.GetLength(0); x++) 781 for (x = 0; x < LandBitmap.GetLength(0); x++)
@@ -734,10 +784,14 @@ namespace OpenSim.Region.CoreModules.World.Land
734 { 784 {
735 if (LandBitmap[x, y] == true) 785 if (LandBitmap[x, y] == true)
736 { 786 {
737 if (min_x > x) min_x = x; 787 if (min_x > x)
738 if (min_y > y) min_y = y; 788 min_x = x;
739 if (max_x < x) max_x = x; 789 if (min_y > y)
740 if (max_y < y) max_y = y; 790 min_y = y;
791 if (max_x < x)
792 max_x = x;
793 if (max_y < y)
794 max_y = y;
741 tempArea += landUnit * landUnit; //16sqm peice of land 795 tempArea += landUnit * landUnit; //16sqm peice of land
742 } 796 }
743 } 797 }
@@ -745,24 +799,42 @@ namespace OpenSim.Region.CoreModules.World.Land
745 int tx = min_x * landUnit; 799 int tx = min_x * landUnit;
746 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) 800 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1))
747 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); 801 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1);
802 int htx;
803 if (tx >= ((int)m_scene.RegionInfo.RegionSizeX))
804 htx = (int)m_scene.RegionInfo.RegionSizeX - 1;
805 else
806 htx = tx;
807
748 int ty = min_y * landUnit; 808 int ty = min_y * landUnit;
749 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1)) 809 int hty;
750 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1); 810
811 if (ty >= ((int)m_scene.RegionInfo.RegionSizeY))
812 hty = (int)m_scene.RegionInfo.RegionSizeY - 1;
813 else
814 hty = ty;
751 815
752 LandData.AABBMin = 816 LandData.AABBMin =
753 new Vector3( 817 new Vector3(
754 (float)(min_x * landUnit), (float)(min_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 818 (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0);
755 819
820 max_x++;
756 tx = max_x * landUnit; 821 tx = max_x * landUnit;
757 if (tx > ((int)m_scene.RegionInfo.RegionSizeX - 1)) 822 if (tx >= ((int)m_scene.RegionInfo.RegionSizeX))
758 tx = ((int)m_scene.RegionInfo.RegionSizeX - 1); 823 htx = (int)m_scene.RegionInfo.RegionSizeX - 1;
759 ty = max_y * landUnit; 824 else
760 if (ty > ((int)m_scene.RegionInfo.RegionSizeY - 1)) 825 htx = tx;
761 ty = ((int)m_scene.RegionInfo.RegionSizeY - 1); 826
827 max_y++;
828 ty = max_y * 4;
829
830 if (ty >= ((int)m_scene.RegionInfo.RegionSizeY))
831 hty = (int)m_scene.RegionInfo.RegionSizeY - 1;
832 else
833 hty = ty;
762 834
763 LandData.AABBMax 835 LandData.AABBMax
764 = new Vector3( 836 = new Vector3(
765 (float)(max_x * landUnit), (float)(max_y * landUnit), m_scene != null ? (float)m_scene.Heightmap[tx, ty] : 0); 837 (float)(tx), (float)(ty), m_scene != null ? (float)m_scene.Heightmap[htx, hty] : 0);
766 838
767 LandData.Area = tempArea; 839 LandData.Area = tempArea;
768 } 840 }
@@ -778,7 +850,6 @@ namespace OpenSim.Region.CoreModules.World.Land
778 public void SetLandBitmap(bool[,] bitmap) 850 public void SetLandBitmap(bool[,] bitmap)
779 { 851 {
780 LandBitmap = bitmap; 852 LandBitmap = bitmap;
781 // m_log.DebugFormat("{0} SetLandBitmap. BitmapSize=<{1},{2}>", LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
782 ForceUpdateLandInfo(); 853 ForceUpdateLandInfo();
783 } 854 }
784 855
@@ -879,13 +950,32 @@ namespace OpenSim.Region.CoreModules.World.Land
879 private byte[] ConvertLandBitmapToBytes() 950 private byte[] ConvertLandBitmapToBytes()
880 { 951 {
881 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8]; 952 byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8];
882 byte tempByte = 0; 953
883 int byteNum = 0; 954 int tempByte = 0;
884 int i = 0; 955 int i, byteNum = 0;
956 int mask = 1;
957 i = 0;
885 for (int y = 0; y < LandBitmap.GetLength(1); y++) 958 for (int y = 0; y < LandBitmap.GetLength(1); y++)
886 { 959 {
887 for (int x = 0; x < LandBitmap.GetLength(0); x++) 960 for (int x = 0; x < LandBitmap.GetLength(0); x++)
888 { 961 {
962 if (LandBitmap[x, y])
963 tempByte |= mask;
964 mask = mask << 1;
965 if (mask == 0x100)
966 {
967 mask = 1;
968 tempConvertArr[byteNum++] = (byte)tempByte;
969 tempByte = 0;
970 }
971 }
972 }
973
974 if(tempByte != 0 && byteNum < 512)
975 tempConvertArr[byteNum] = (byte)tempByte;
976
977
978/*
889 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); 979 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
890 if (i % 8 == 0) 980 if (i % 8 == 0)
891 { 981 {
@@ -894,10 +984,13 @@ namespace OpenSim.Region.CoreModules.World.Land
894 i = 0; 984 i = 0;
895 byteNum++; 985 byteNum++;
896 } 986 }
987<<<<<<< HEAD
897 } 988 }
898 } 989 }
899 // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>", 990 // m_log.DebugFormat("{0} ConvertLandBitmapToBytes. BitmapSize=<{1},{2}>",
900 // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1)); 991 // LogHeader, LandBitmap.GetLength(0), LandBitmap.GetLength(1));
992=======
993 */
901 return tempConvertArr; 994 return tempConvertArr;
902 } 995 }
903 996
@@ -951,7 +1044,7 @@ namespace OpenSim.Region.CoreModules.World.Land
951 1044
952 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client) 1045 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client)
953 { 1046 {
954 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 1047 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
955 { 1048 {
956 List<uint> resultLocalIDs = new List<uint>(); 1049 List<uint> resultLocalIDs = new List<uint>();
957 try 1050 try
@@ -1001,7 +1094,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1001 /// </param> 1094 /// </param>
1002 public void SendLandObjectOwners(IClientAPI remote_client) 1095 public void SendLandObjectOwners(IClientAPI remote_client)
1003 { 1096 {
1004 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) 1097 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions, true))
1005 { 1098 {
1006 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>(); 1099 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>();
1007 List<UUID> groups = new List<UUID>(); 1100 List<UUID> groups = new List<UUID>();
@@ -1233,6 +1326,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1233 public void SetMediaUrl(string url) 1326 public void SetMediaUrl(string url)
1234 { 1327 {
1235 LandData.MediaURL = url; 1328 LandData.MediaURL = url;
1329 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData);
1236 SendLandUpdateToAvatarsOverMe(); 1330 SendLandUpdateToAvatarsOverMe();
1237 } 1331 }
1238 1332
@@ -1243,6 +1337,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1243 public void SetMusicUrl(string url) 1337 public void SetMusicUrl(string url)
1244 { 1338 {
1245 LandData.MusicURL = url; 1339 LandData.MusicURL = url;
1340 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, LandData);
1246 SendLandUpdateToAvatarsOverMe(); 1341 SendLandUpdateToAvatarsOverMe();
1247 } 1342 }
1248 1343
@@ -1257,6 +1352,17 @@ namespace OpenSim.Region.CoreModules.World.Land
1257 1352
1258 #endregion 1353 #endregion
1259 1354
1355 private void OnFrame()
1356 {
1357 m_expiryCounter++;
1358
1359 if (m_expiryCounter >= 50)
1360 {
1361 ExpireAccessList();
1362 m_expiryCounter = 0;
1363 }
1364 }
1365
1260 private void ExpireAccessList() 1366 private void ExpireAccessList()
1261 { 1367 {
1262 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1368 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1267,7 +1373,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1267 delete.Add(entry); 1373 delete.Add(entry);
1268 } 1374 }
1269 foreach (LandAccessEntry entry in delete) 1375 foreach (LandAccessEntry entry in delete)
1376 {
1270 LandData.ParcelAccessList.Remove(entry); 1377 LandData.ParcelAccessList.Remove(entry);
1378 ScenePresence presence;
1379
1380 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1381 {
1382 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1383 if (land.LandData.LocalID == LandData.LocalID)
1384 {
1385 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1386 presence.TeleportWithMomentum(pos, null);
1387 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1388 }
1389 }
1390 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1391 }
1271 1392
1272 if (delete.Count > 0) 1393 if (delete.Count > 0)
1273 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1394 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this);
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 9b51cc8..771fdd2 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -207,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Land
207 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) 207 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
208 { 208 {
209 UUID landOwner = landData.OwnerID; 209 UUID landOwner = landData.OwnerID;
210 int partCount = obj.Parts.Length; 210 int partCount = obj.GetPartCount();
211 211
212 m_SimwideCounts[landOwner] += partCount; 212 m_SimwideCounts[landOwner] += partCount;
213 if (parcelCounts.Users.ContainsKey(obj.OwnerID)) 213 if (parcelCounts.Users.ContainsKey(obj.OwnerID))
@@ -597,4 +597,4 @@ namespace OpenSim.Region.CoreModules.World.Land
597 } 597 }
598 } 598 }
599 } 599 }
600} \ No newline at end of file 600}