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