diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land')
3 files changed, 373 insertions, 134 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 8b7406d..aae6603 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -86,19 +86,21 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
86 | /// <value> | 86 | /// <value> |
87 | /// Land objects keyed by local id | 87 | /// Land objects keyed by local id |
88 | /// </value> | 88 | /// </value> |
89 | private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); | 89 | // private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); |
90 | |||
91 | //ubit: removed the readonly so i can move it around | ||
92 | private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); | ||
90 | 93 | ||
91 | private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; | 94 | private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; |
92 | 95 | ||
93 | private bool m_allowedForcefulBans = true; | 96 | private bool m_allowedForcefulBans = true; |
97 | private UUID DefaultGodParcelGroup; | ||
98 | private string DefaultGodParcelName; | ||
94 | 99 | ||
95 | // caches ExtendedLandData | 100 | // caches ExtendedLandData |
96 | private Cache parcelInfoCache; | 101 | private Cache parcelInfoCache; |
97 | 102 | private Dictionary<UUID, Vector3> forcedPosition = | |
98 | /// <summary> | 103 | new Dictionary<UUID, Vector3>(); |
99 | /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. | ||
100 | /// </summary> | ||
101 | private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); | ||
102 | 104 | ||
103 | #region INonSharedRegionModule Members | 105 | #region INonSharedRegionModule Members |
104 | 106 | ||
@@ -109,6 +111,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
109 | 111 | ||
110 | public void Initialise(IConfigSource source) | 112 | public void Initialise(IConfigSource source) |
111 | { | 113 | { |
114 | IConfig cnf = source.Configs["LandManagement"]; | ||
115 | if (cnf != null) | ||
116 | { | ||
117 | DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString())); | ||
118 | DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel"); | ||
119 | } | ||
112 | } | 120 | } |
113 | 121 | ||
114 | public void AddRegion(Scene scene) | 122 | public void AddRegion(Scene scene) |
@@ -160,13 +168,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
160 | m_scene.UnregisterModuleCommander(m_commander.Name); | 168 | m_scene.UnregisterModuleCommander(m_commander.Name); |
161 | } | 169 | } |
162 | 170 | ||
163 | // private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason) | ||
164 | // { | ||
165 | // ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y); | ||
166 | // reason = "You are not allowed to enter this sim."; | ||
167 | // return nearestParcel != null; | ||
168 | // } | ||
169 | |||
170 | /// <summary> | 171 | /// <summary> |
171 | /// Processes commandline input. Do not call directly. | 172 | /// Processes commandline input. Do not call directly. |
172 | /// </summary> | 173 | /// </summary> |
@@ -207,6 +208,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
207 | client.OnParcelInfoRequest += ClientOnParcelInfoRequest; | 208 | client.OnParcelInfoRequest += ClientOnParcelInfoRequest; |
208 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; | 209 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; |
209 | client.OnPreAgentUpdate += ClientOnPreAgentUpdate; | 210 | client.OnPreAgentUpdate += ClientOnPreAgentUpdate; |
211 | client.OnParcelEjectUser += ClientOnParcelEjectUser; | ||
212 | client.OnParcelFreezeUser += ClientOnParcelFreezeUser; | ||
210 | 213 | ||
211 | EntityBase presenceEntity; | 214 | EntityBase presenceEntity; |
212 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) | 215 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) |
@@ -218,48 +221,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
218 | 221 | ||
219 | void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 222 | void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
220 | { | 223 | { |
221 | //If we are forcing a position for them to go | ||
222 | if (forcedPosition.ContainsKey(remoteClient.AgentId)) | ||
223 | { | ||
224 | ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId); | ||
225 | |||
226 | //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND | ||
227 | //When the avatar walks into a ban line on the ground, it prevents getting stuck | ||
228 | agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | ||
229 | |||
230 | //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines | ||
231 | if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2) | ||
232 | { | ||
233 | // m_log.DebugFormat( | ||
234 | // "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}", | ||
235 | // clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]); | ||
236 | |||
237 | forcedPosition.Remove(remoteClient.AgentId); | ||
238 | } | ||
239 | //if we are far away, teleport | ||
240 | else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3) | ||
241 | { | ||
242 | Vector3 forcePosition = forcedPosition[remoteClient.AgentId]; | ||
243 | // m_log.DebugFormat( | ||
244 | // "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}", | ||
245 | // clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition); | ||
246 | |||
247 | m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle, | ||
248 | forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect); | ||
249 | |||
250 | forcedPosition.Remove(remoteClient.AgentId); | ||
251 | } | ||
252 | else | ||
253 | { | ||
254 | // m_log.DebugFormat( | ||
255 | // "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}", | ||
256 | // clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]); | ||
257 | |||
258 | //Forces them toward the forced position we want if they aren't there yet | ||
259 | agentData.UseClientAgentPosition = true; | ||
260 | agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId]; | ||
261 | } | ||
262 | } | ||
263 | } | 224 | } |
264 | 225 | ||
265 | public void Close() | 226 | public void Close() |
@@ -284,15 +245,19 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
284 | { | 245 | { |
285 | LandData newData = data.Copy(); | 246 | LandData newData = data.Copy(); |
286 | newData.LocalID = local_id; | 247 | newData.LocalID = local_id; |
248 | ILandObject landobj = null; | ||
287 | 249 | ||
288 | lock (m_landList) | 250 | lock (m_landList) |
289 | { | 251 | { |
290 | if (m_landList.ContainsKey(local_id)) | 252 | if (m_landList.ContainsKey(local_id)) |
291 | { | 253 | { |
292 | m_landList[local_id].LandData = newData; | 254 | m_landList[local_id].LandData = newData; |
293 | m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); | 255 | landobj = m_landList[local_id]; |
256 | // m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); | ||
294 | } | 257 | } |
295 | } | 258 | } |
259 | if(landobj != null) | ||
260 | m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landobj); | ||
296 | } | 261 | } |
297 | 262 | ||
298 | public bool AllowedForcefulBans | 263 | public bool AllowedForcefulBans |
@@ -322,14 +287,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
322 | protected ILandObject CreateDefaultParcel() | 287 | protected ILandObject CreateDefaultParcel() |
323 | { | 288 | { |
324 | m_log.DebugFormat( | 289 | m_log.DebugFormat( |
325 | "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); | 290 | "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); |
326 | 291 | ||
327 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); | 292 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); |
328 | fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); | 293 | fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); |
329 | fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 294 | fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
330 | fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | 295 | fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); |
331 | 296 | ||
332 | return AddLandObject(fullSimParcel); | 297 | return AddLandObject(fullSimParcel); |
333 | } | 298 | } |
334 | 299 | ||
335 | public List<ILandObject> AllParcels() | 300 | public List<ILandObject> AllParcels() |
@@ -378,10 +343,16 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
378 | private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) | 343 | private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) |
379 | { | 344 | { |
380 | if (m_scene.Permissions.IsGod(avatar.UUID)) return; | 345 | if (m_scene.Permissions.IsGod(avatar.UUID)) return; |
381 | if (position.HasValue) | 346 | |
382 | { | 347 | if (!position.HasValue) |
383 | forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; | 348 | return; |
384 | } | 349 | |
350 | bool isFlying = avatar.PhysicsActor.Flying; | ||
351 | avatar.RemoveFromPhysicalScene(); | ||
352 | |||
353 | avatar.AbsolutePosition = (Vector3)position; | ||
354 | |||
355 | avatar.AddToPhysicalScene(isFlying); | ||
385 | } | 356 | } |
386 | 357 | ||
387 | public void SendYouAreRestrictedNotice(ScenePresence avatar) | 358 | public void SendYouAreRestrictedNotice(ScenePresence avatar) |
@@ -401,29 +372,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
401 | } | 372 | } |
402 | 373 | ||
403 | if (parcelAvatarIsEntering != null) | 374 | if (parcelAvatarIsEntering != null) |
404 | { | 375 | EnforceBans(parcelAvatarIsEntering, avatar); |
405 | if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) | ||
406 | { | ||
407 | if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) | ||
408 | { | ||
409 | SendYouAreBannedNotice(avatar); | ||
410 | ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar)); | ||
411 | } | ||
412 | else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) | ||
413 | { | ||
414 | SendYouAreRestrictedNotice(avatar); | ||
415 | ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar)); | ||
416 | } | ||
417 | else | ||
418 | { | ||
419 | avatar.sentMessageAboutRestrictedParcelFlyingDown = true; | ||
420 | } | ||
421 | } | ||
422 | else | ||
423 | { | ||
424 | avatar.sentMessageAboutRestrictedParcelFlyingDown = true; | ||
425 | } | ||
426 | } | ||
427 | } | 376 | } |
428 | } | 377 | } |
429 | 378 | ||
@@ -452,30 +401,51 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
452 | 401 | ||
453 | public void SendLandUpdate(ScenePresence avatar, bool force) | 402 | public void SendLandUpdate(ScenePresence avatar, bool force) |
454 | { | 403 | { |
404 | |||
405 | /* stop sendind same data twice | ||
406 | ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), | ||
407 | (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); | ||
408 | |||
409 | if (over != null) | ||
410 | { | ||
411 | |||
412 | if (force) | ||
413 | { | ||
414 | if (!avatar.IsChildAgent) | ||
415 | { | ||
416 | over.SendLandUpdateToClient(avatar.ControllingClient); | ||
417 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, | ||
418 | m_scene.RegionInfo.RegionID); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | if (avatar.currentParcelUUID != over.LandData.GlobalID) | ||
423 | { | ||
424 | if (!avatar.IsChildAgent) | ||
425 | { | ||
426 | over.SendLandUpdateToClient(avatar.ControllingClient); | ||
427 | avatar.currentParcelUUID = over.LandData.GlobalID; | ||
428 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, | ||
429 | m_scene.RegionInfo.RegionID); | ||
430 | } | ||
431 | } | ||
432 | */ | ||
433 | if (avatar.IsChildAgent) | ||
434 | return; | ||
435 | |||
455 | ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), | 436 | ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), |
456 | (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); | 437 | (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); |
457 | 438 | ||
458 | if (over != null) | 439 | if (over != null) |
459 | { | 440 | { |
460 | if (force) | 441 | bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID); |
442 | if (force || NotsameID) | ||
461 | { | 443 | { |
462 | if (!avatar.IsChildAgent) | 444 | over.SendLandUpdateToClient(avatar.ControllingClient); |
463 | { | 445 | if (NotsameID) |
464 | over.SendLandUpdateToClient(avatar.ControllingClient); | ||
465 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, | ||
466 | m_scene.RegionInfo.RegionID); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | if (avatar.currentParcelUUID != over.LandData.GlobalID) | ||
471 | { | ||
472 | if (!avatar.IsChildAgent) | ||
473 | { | ||
474 | over.SendLandUpdateToClient(avatar.ControllingClient); | ||
475 | avatar.currentParcelUUID = over.LandData.GlobalID; | 446 | avatar.currentParcelUUID = over.LandData.GlobalID; |
476 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, | 447 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, |
477 | m_scene.RegionInfo.RegionID); | 448 | m_scene.RegionInfo.RegionID); |
478 | } | ||
479 | } | 449 | } |
480 | } | 450 | } |
481 | } | 451 | } |
@@ -527,6 +497,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
527 | //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 |
528 | forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); | 498 | forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); |
529 | } | 499 | } |
500 | EnforceBans(parcel, clientAvatar); | ||
530 | } | 501 | } |
531 | } | 502 | } |
532 | 503 | ||
@@ -674,21 +645,28 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
674 | /// </summary> | 645 | /// </summary> |
675 | public void Clear(bool setupDefaultParcel) | 646 | public void Clear(bool setupDefaultParcel) |
676 | { | 647 | { |
648 | Dictionary<int, ILandObject> landworkList; | ||
649 | // move to work pointer since we are deleting it all | ||
677 | lock (m_landList) | 650 | lock (m_landList) |
678 | { | 651 | { |
679 | foreach (ILandObject lo in m_landList.Values) | 652 | landworkList = m_landList; |
680 | { | 653 | m_landList = new Dictionary<int, ILandObject>(); |
681 | //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); | 654 | } |
682 | m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); | ||
683 | } | ||
684 | 655 | ||
685 | m_landList.Clear(); | 656 | // this 2 methods have locks (now) |
657 | ResetSimLandObjects(); | ||
686 | 658 | ||
687 | ResetSimLandObjects(); | 659 | if (setupDefaultParcel) |
660 | CreateDefaultParcel(); | ||
688 | 661 | ||
689 | if (setupDefaultParcel) | 662 | // fire outside events unlocked |
690 | CreateDefaultParcel(); | 663 | foreach (ILandObject lo in landworkList.Values) |
664 | { | ||
665 | //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); | ||
666 | m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); | ||
691 | } | 667 | } |
668 | landworkList.Clear(); | ||
669 | |||
692 | } | 670 | } |
693 | 671 | ||
694 | private void performFinalLandJoin(ILandObject master, ILandObject slave) | 672 | private void performFinalLandJoin(ILandObject master, ILandObject slave) |
@@ -735,7 +713,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
735 | int x; | 713 | int x; |
736 | int y; | 714 | int y; |
737 | 715 | ||
738 | if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) | 716 | if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0) |
739 | return null; | 717 | return null; |
740 | 718 | ||
741 | try | 719 | try |
@@ -785,14 +763,13 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
785 | { | 763 | { |
786 | try | 764 | try |
787 | { | 765 | { |
788 | return m_landList[m_landIDList[x / 4, y / 4]]; | 766 | //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4])) |
767 | return m_landList[m_landIDList[x / 4, y / 4]]; | ||
768 | //else | ||
769 | // return null; | ||
789 | } | 770 | } |
790 | catch (IndexOutOfRangeException) | 771 | catch (IndexOutOfRangeException) |
791 | { | 772 | { |
792 | // m_log.WarnFormat( | ||
793 | // "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}", | ||
794 | // x, y, m_scene.RegionInfo.RegionName); | ||
795 | |||
796 | return null; | 773 | return null; |
797 | } | 774 | } |
798 | } | 775 | } |
@@ -1075,6 +1052,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1075 | //Owner Flag | 1052 | //Owner Flag |
1076 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); | 1053 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); |
1077 | } | 1054 | } |
1055 | else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID)) | ||
1056 | { | ||
1057 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP); | ||
1058 | } | ||
1078 | else if (currentParcelBlock.LandData.SalePrice > 0 && | 1059 | else if (currentParcelBlock.LandData.SalePrice > 0 && |
1079 | (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || | 1060 | (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || |
1080 | currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) | 1061 | currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) |
@@ -1155,8 +1136,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1155 | { | 1136 | { |
1156 | if (!temp.Contains(currentParcel)) | 1137 | if (!temp.Contains(currentParcel)) |
1157 | { | 1138 | { |
1158 | currentParcel.ForceUpdateLandInfo(); | 1139 | if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId)) |
1159 | temp.Add(currentParcel); | 1140 | { |
1141 | currentParcel.ForceUpdateLandInfo(); | ||
1142 | temp.Add(currentParcel); | ||
1143 | } | ||
1160 | } | 1144 | } |
1161 | } | 1145 | } |
1162 | } | 1146 | } |
@@ -1375,6 +1359,27 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1375 | 1359 | ||
1376 | public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) | 1360 | public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) |
1377 | { | 1361 | { |
1362 | Dictionary<int, ILandObject> landworkList; | ||
1363 | // move to work pointer since we are deleting it all | ||
1364 | lock (m_landList) | ||
1365 | { | ||
1366 | landworkList = m_landList; | ||
1367 | m_landList = new Dictionary<int, ILandObject>(); | ||
1368 | } | ||
1369 | |||
1370 | //Remove all the land objects in the sim and then process our new data | ||
1371 | foreach (int n in landworkList.Keys) | ||
1372 | { | ||
1373 | m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID); | ||
1374 | } | ||
1375 | landworkList.Clear(); | ||
1376 | |||
1377 | lock (m_landList) | ||
1378 | { | ||
1379 | m_landIDList.Initialize(); | ||
1380 | m_landList.Clear(); | ||
1381 | } | ||
1382 | |||
1378 | for (int i = 0; i < data.Count; i++) | 1383 | for (int i = 0; i < data.Count; i++) |
1379 | { | 1384 | { |
1380 | IncomingLandObjectFromStorage(data[i]); | 1385 | IncomingLandObjectFromStorage(data[i]); |
@@ -1383,10 +1388,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1383 | 1388 | ||
1384 | public void IncomingLandObjectFromStorage(LandData data) | 1389 | public void IncomingLandObjectFromStorage(LandData data) |
1385 | { | 1390 | { |
1391 | |||
1386 | ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); | 1392 | ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); |
1387 | new_land.LandData = data.Copy(); | 1393 | new_land.LandData = data.Copy(); |
1388 | new_land.SetLandBitmapFromByteArray(); | 1394 | new_land.SetLandBitmapFromByteArray(); |
1389 | AddLandObject(new_land); | 1395 | AddLandObject(new_land); |
1396 | new_land.SendLandUpdateToAvatarsOverMe(); | ||
1390 | } | 1397 | } |
1391 | 1398 | ||
1392 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) | 1399 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) |
@@ -1404,7 +1411,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1404 | 1411 | ||
1405 | public void EventManagerOnNoLandDataFromStorage() | 1412 | public void EventManagerOnNoLandDataFromStorage() |
1406 | { | 1413 | { |
1407 | lock (m_landList) | 1414 | // called methods already have locks |
1415 | // lock (m_landList) | ||
1408 | { | 1416 | { |
1409 | ResetSimLandObjects(); | 1417 | ResetSimLandObjects(); |
1410 | CreateDefaultParcel(); | 1418 | CreateDefaultParcel(); |
@@ -1669,6 +1677,168 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1669 | 1677 | ||
1670 | UpdateLandObject(localID, land.LandData); | 1678 | UpdateLandObject(localID, land.LandData); |
1671 | } | 1679 | } |
1680 | |||
1681 | public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID) | ||
1682 | { | ||
1683 | ILandObject land = null; | ||
1684 | List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels(); | ||
1685 | foreach (ILandObject landObject in Land) | ||
1686 | { | ||
1687 | if (landObject.LandData.LocalID == landID) | ||
1688 | { | ||
1689 | land = landObject; | ||
1690 | } | ||
1691 | } | ||
1692 | land.DeedToGroup(DefaultGodParcelGroup); | ||
1693 | land.LandData.Name = DefaultGodParcelName; | ||
1694 | land.SendLandUpdateToAvatarsOverMe(); | ||
1695 | } | ||
1696 | |||
1697 | private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID) | ||
1698 | { | ||
1699 | ScenePresence SP; | ||
1700 | ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP); | ||
1701 | List<SceneObjectGroup> returns = new List<SceneObjectGroup>(); | ||
1702 | if (SP.UserLevel != 0) | ||
1703 | { | ||
1704 | if (flags == 0) //All parcels, scripted or not | ||
1705 | { | ||
1706 | ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) | ||
1707 | { | ||
1708 | if (e.OwnerID == targetID) | ||
1709 | { | ||
1710 | returns.Add(e); | ||
1711 | } | ||
1712 | } | ||
1713 | ); | ||
1714 | } | ||
1715 | if (flags == 4) //All parcels, scripted object | ||
1716 | { | ||
1717 | ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) | ||
1718 | { | ||
1719 | if (e.OwnerID == targetID) | ||
1720 | { | ||
1721 | if (e.ContainsScripts()) | ||
1722 | { | ||
1723 | returns.Add(e); | ||
1724 | } | ||
1725 | } | ||
1726 | } | ||
1727 | ); | ||
1728 | } | ||
1729 | if (flags == 4) //not target parcel, scripted object | ||
1730 | { | ||
1731 | ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) | ||
1732 | { | ||
1733 | if (e.OwnerID == targetID) | ||
1734 | { | ||
1735 | ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y); | ||
1736 | if (landobject.LandData.OwnerID != e.OwnerID) | ||
1737 | { | ||
1738 | if (e.ContainsScripts()) | ||
1739 | { | ||
1740 | returns.Add(e); | ||
1741 | } | ||
1742 | } | ||
1743 | } | ||
1744 | } | ||
1745 | ); | ||
1746 | } | ||
1747 | foreach (SceneObjectGroup ol in returns) | ||
1748 | { | ||
1749 | ReturnObject(ol, client); | ||
1750 | } | ||
1751 | } | ||
1752 | } | ||
1753 | public void ReturnObject(SceneObjectGroup obj, IClientAPI client) | ||
1754 | { | ||
1755 | SceneObjectGroup[] objs = new SceneObjectGroup[1]; | ||
1756 | objs[0] = obj; | ||
1757 | ((Scene)client.Scene).returnObjects(objs, client.AgentId); | ||
1758 | } | ||
1759 | |||
1760 | Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); | ||
1761 | |||
1762 | public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) | ||
1763 | { | ||
1764 | ScenePresence targetAvatar = null; | ||
1765 | ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar); | ||
1766 | ScenePresence parcelManager = null; | ||
1767 | ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); | ||
1768 | System.Threading.Timer Timer; | ||
1769 | |||
1770 | if (targetAvatar.UserLevel == 0) | ||
1771 | { | ||
1772 | ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); | ||
1773 | if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) | ||
1774 | return; | ||
1775 | if (flags == 0) | ||
1776 | { | ||
1777 | targetAvatar.AllowMovement = false; | ||
1778 | targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world."); | ||
1779 | parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen."); | ||
1780 | System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen); | ||
1781 | Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0); | ||
1782 | Timers.Add(targetAvatar.UUID, Timer); | ||
1783 | } | ||
1784 | else | ||
1785 | { | ||
1786 | targetAvatar.AllowMovement = true; | ||
1787 | targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you."); | ||
1788 | parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen."); | ||
1789 | Timers.TryGetValue(targetAvatar.UUID, out Timer); | ||
1790 | Timers.Remove(targetAvatar.UUID); | ||
1791 | Timer.Dispose(); | ||
1792 | } | ||
1793 | } | ||
1794 | } | ||
1795 | private void OnEndParcelFrozen(object avatar) | ||
1796 | { | ||
1797 | ScenePresence targetAvatar = (ScenePresence)avatar; | ||
1798 | targetAvatar.AllowMovement = true; | ||
1799 | System.Threading.Timer Timer; | ||
1800 | Timers.TryGetValue(targetAvatar.UUID, out Timer); | ||
1801 | Timers.Remove(targetAvatar.UUID); | ||
1802 | targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); | ||
1803 | } | ||
1804 | |||
1805 | |||
1806 | public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) | ||
1807 | { | ||
1808 | ScenePresence targetAvatar = null; | ||
1809 | ScenePresence parcelManager = null; | ||
1810 | |||
1811 | // Must have presences | ||
1812 | if (!m_scene.TryGetScenePresence(target, out targetAvatar) || | ||
1813 | !m_scene.TryGetScenePresence(client.AgentId, out parcelManager)) | ||
1814 | return; | ||
1815 | |||
1816 | // Cannot eject estate managers or gods | ||
1817 | if (m_scene.Permissions.IsAdministrator(target)) | ||
1818 | return; | ||
1819 | |||
1820 | // Check if you even have permission to do this | ||
1821 | ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); | ||
1822 | if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && | ||
1823 | !m_scene.Permissions.IsAdministrator(client.AgentId)) | ||
1824 | return; | ||
1825 | |||
1826 | Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); | ||
1827 | |||
1828 | targetAvatar.TeleportWithMomentum(pos, null); | ||
1829 | targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); | ||
1830 | parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); | ||
1831 | |||
1832 | if ((flags & 1) != 0) // Ban TODO: Remove magic number | ||
1833 | { | ||
1834 | LandAccessEntry entry = new LandAccessEntry(); | ||
1835 | entry.AgentID = targetAvatar.UUID; | ||
1836 | entry.Flags = AccessList.Ban; | ||
1837 | entry.Expires = 0; // Perm | ||
1838 | |||
1839 | land.LandData.ParcelAccessList.Add(entry); | ||
1840 | } | ||
1841 | } | ||
1672 | 1842 | ||
1673 | protected void InstallInterfaces() | 1843 | protected void InstallInterfaces() |
1674 | { | 1844 | { |
@@ -1731,5 +1901,27 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1731 | 1901 | ||
1732 | MainConsole.Instance.Output(report.ToString()); | 1902 | MainConsole.Instance.Output(report.ToString()); |
1733 | } | 1903 | } |
1904 | |||
1905 | public void EnforceBans(ILandObject land, ScenePresence avatar) | ||
1906 | { | ||
1907 | if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT) | ||
1908 | return; | ||
1909 | |||
1910 | if (land.IsEitherBannedOrRestricted(avatar.UUID)) | ||
1911 | { | ||
1912 | if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y))) | ||
1913 | { | ||
1914 | Vector3? pos = m_scene.GetNearestAllowedPosition(avatar); | ||
1915 | if (pos == null) | ||
1916 | m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient); | ||
1917 | else | ||
1918 | ForceAvatarToPosition(avatar, (Vector3)pos); | ||
1919 | } | ||
1920 | else | ||
1921 | { | ||
1922 | ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition); | ||
1923 | } | ||
1924 | } | ||
1925 | } | ||
1734 | } | 1926 | } |
1735 | } | 1927 | } |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 8829f27..d5b2adb 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -51,6 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
51 | private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; | 51 | private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; |
52 | 52 | ||
53 | private int m_lastSeqId = 0; | 53 | private int m_lastSeqId = 0; |
54 | private int m_expiryCounter = 0; | ||
54 | 55 | ||
55 | protected LandData m_landData = new LandData(); | 56 | protected LandData m_landData = new LandData(); |
56 | protected Scene m_scene; | 57 | protected Scene m_scene; |
@@ -136,6 +137,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
136 | else | 137 | else |
137 | LandData.GroupID = UUID.Zero; | 138 | LandData.GroupID = UUID.Zero; |
138 | LandData.IsGroupOwned = is_group_owned; | 139 | LandData.IsGroupOwned = is_group_owned; |
140 | |||
141 | m_scene.EventManager.OnFrame += OnFrame; | ||
139 | } | 142 | } |
140 | 143 | ||
141 | #endregion | 144 | #endregion |
@@ -194,10 +197,27 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
194 | else | 197 | else |
195 | { | 198 | { |
196 | // Normal Calculations | 199 | // Normal Calculations |
197 | int parcelMax = (int)(((float)LandData.Area / 65536.0f) | 200 | int parcelMax = (int)((long)LandData.Area |
198 | * (float)m_scene.RegionInfo.ObjectCapacity | 201 | * (long)m_scene.RegionInfo.ObjectCapacity |
199 | * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); | 202 | * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus |
200 | // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! | 203 | / 65536L); |
204 | //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax); | ||
205 | return parcelMax; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private int GetParcelBasePrimCount() | ||
210 | { | ||
211 | if (overrideParcelMaxPrimCount != null) | ||
212 | { | ||
213 | return overrideParcelMaxPrimCount(this); | ||
214 | } | ||
215 | else | ||
216 | { | ||
217 | // Normal Calculations | ||
218 | int parcelMax = (int)((long)LandData.Area | ||
219 | * (long)m_scene.RegionInfo.ObjectCapacity | ||
220 | / 65536L); | ||
201 | return parcelMax; | 221 | return parcelMax; |
202 | } | 222 | } |
203 | } | 223 | } |
@@ -211,8 +231,9 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
211 | else | 231 | else |
212 | { | 232 | { |
213 | //Normal Calculations | 233 | //Normal Calculations |
214 | int simMax = (int)(((float)LandData.SimwideArea / 65536.0f) | 234 | int simMax = (int)((long)LandData.SimwideArea |
215 | * (float)m_scene.RegionInfo.ObjectCapacity); | 235 | * (long)m_scene.RegionInfo.ObjectCapacity / 65536L); |
236 | // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax); | ||
216 | return simMax; | 237 | return simMax; |
217 | } | 238 | } |
218 | } | 239 | } |
@@ -249,7 +270,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
249 | remote_client.SendLandProperties(seq_id, | 270 | remote_client.SendLandProperties(seq_id, |
250 | snap_selection, request_result, this, | 271 | snap_selection, request_result, this, |
251 | (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, | 272 | (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, |
252 | GetParcelMaxPrimCount(), | 273 | GetParcelBasePrimCount(), |
253 | GetSimulatorMaxPrimCount(), regionFlags); | 274 | GetSimulatorMaxPrimCount(), regionFlags); |
254 | } | 275 | } |
255 | 276 | ||
@@ -309,7 +330,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
309 | 330 | ||
310 | allowedDelta |= (uint)(ParcelFlags.ShowDirectory | | 331 | allowedDelta |= (uint)(ParcelFlags.ShowDirectory | |
311 | ParcelFlags.AllowPublish | | 332 | ParcelFlags.AllowPublish | |
312 | ParcelFlags.MaturePublish); | 333 | ParcelFlags.MaturePublish) | (uint)(1 << 23); |
313 | } | 334 | } |
314 | 335 | ||
315 | if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) | 336 | if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) |
@@ -1182,6 +1203,17 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1182 | 1203 | ||
1183 | #endregion | 1204 | #endregion |
1184 | 1205 | ||
1206 | private void OnFrame() | ||
1207 | { | ||
1208 | m_expiryCounter++; | ||
1209 | |||
1210 | if (m_expiryCounter >= 50) | ||
1211 | { | ||
1212 | ExpireAccessList(); | ||
1213 | m_expiryCounter = 0; | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1185 | private void ExpireAccessList() | 1217 | private void ExpireAccessList() |
1186 | { | 1218 | { |
1187 | List<LandAccessEntry> delete = new List<LandAccessEntry>(); | 1219 | List<LandAccessEntry> delete = new List<LandAccessEntry>(); |
@@ -1192,7 +1224,22 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1192 | delete.Add(entry); | 1224 | delete.Add(entry); |
1193 | } | 1225 | } |
1194 | foreach (LandAccessEntry entry in delete) | 1226 | foreach (LandAccessEntry entry in delete) |
1227 | { | ||
1195 | LandData.ParcelAccessList.Remove(entry); | 1228 | LandData.ParcelAccessList.Remove(entry); |
1229 | ScenePresence presence; | ||
1230 | |||
1231 | if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent)) | ||
1232 | { | ||
1233 | ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); | ||
1234 | if (land.LandData.LocalID == LandData.LocalID) | ||
1235 | { | ||
1236 | Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land); | ||
1237 | presence.TeleportWithMomentum(pos, null); | ||
1238 | presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); | ||
1239 | } | ||
1240 | } | ||
1241 | m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID); | ||
1242 | } | ||
1196 | 1243 | ||
1197 | if (delete.Count > 0) | 1244 | if (delete.Count > 0) |
1198 | m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); | 1245 | 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 665875f..cbb3abe 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs | |||
@@ -205,7 +205,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
205 | if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) | 205 | if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) |
206 | { | 206 | { |
207 | UUID landOwner = landData.OwnerID; | 207 | UUID landOwner = landData.OwnerID; |
208 | int partCount = obj.Parts.Length; | 208 | int partCount = obj.GetPartCount(); |
209 | 209 | ||
210 | m_SimwideCounts[landOwner] += partCount; | 210 | m_SimwideCounts[landOwner] += partCount; |
211 | if (parcelCounts.Users.ContainsKey(obj.OwnerID)) | 211 | if (parcelCounts.Users.ContainsKey(obj.OwnerID)) |
@@ -592,4 +592,4 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
592 | } | 592 | } |
593 | } | 593 | } |
594 | } | 594 | } |
595 | } \ No newline at end of file | 595 | } |