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.cs767
1 files changed, 409 insertions, 358 deletions
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;