diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 767 |
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; |