diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 441 |
1 files changed, 315 insertions, 126 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 7149aad..281c143 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -88,19 +88,21 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
88 | /// <value> | 88 | /// <value> |
89 | /// Land objects keyed by local id | 89 | /// Land objects keyed by local id |
90 | /// </value> | 90 | /// </value> |
91 | private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); | 91 | // private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); |
92 | |||
93 | //ubit: removed the readonly so i can move it around | ||
94 | private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); | ||
92 | 95 | ||
93 | private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; | 96 | private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; |
94 | 97 | ||
95 | private bool m_allowedForcefulBans = true; | 98 | private bool m_allowedForcefulBans = true; |
99 | private UUID DefaultGodParcelGroup; | ||
100 | private string DefaultGodParcelName; | ||
96 | 101 | ||
97 | // caches ExtendedLandData | 102 | // caches ExtendedLandData |
98 | private Cache parcelInfoCache; | 103 | private Cache parcelInfoCache; |
99 | 104 | private Dictionary<UUID, Vector3> forcedPosition = | |
100 | /// <summary> | 105 | new Dictionary<UUID, Vector3>(); |
101 | /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. | ||
102 | /// </summary> | ||
103 | private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); | ||
104 | 106 | ||
105 | #region INonSharedRegionModule Members | 107 | #region INonSharedRegionModule Members |
106 | 108 | ||
@@ -111,6 +113,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
111 | 113 | ||
112 | public void Initialise(IConfigSource source) | 114 | public void Initialise(IConfigSource source) |
113 | { | 115 | { |
116 | IConfig cnf = source.Configs["LandManagement"]; | ||
117 | if (cnf != null) | ||
118 | { | ||
119 | DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString())); | ||
120 | DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel"); | ||
121 | } | ||
114 | } | 122 | } |
115 | 123 | ||
116 | public void AddRegion(Scene scene) | 124 | public void AddRegion(Scene scene) |
@@ -162,13 +170,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
162 | m_scene.UnregisterModuleCommander(m_commander.Name); | 170 | m_scene.UnregisterModuleCommander(m_commander.Name); |
163 | } | 171 | } |
164 | 172 | ||
165 | // private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason) | ||
166 | // { | ||
167 | // ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y); | ||
168 | // reason = "You are not allowed to enter this sim."; | ||
169 | // return nearestParcel != null; | ||
170 | // } | ||
171 | |||
172 | /// <summary> | 173 | /// <summary> |
173 | /// Processes commandline input. Do not call directly. | 174 | /// Processes commandline input. Do not call directly. |
174 | /// </summary> | 175 | /// </summary> |
@@ -209,6 +210,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
209 | client.OnParcelInfoRequest += ClientOnParcelInfoRequest; | 210 | client.OnParcelInfoRequest += ClientOnParcelInfoRequest; |
210 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; | 211 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; |
211 | client.OnPreAgentUpdate += ClientOnPreAgentUpdate; | 212 | client.OnPreAgentUpdate += ClientOnPreAgentUpdate; |
213 | client.OnParcelEjectUser += ClientOnParcelEjectUser; | ||
214 | client.OnParcelFreezeUser += ClientOnParcelFreezeUser; | ||
212 | 215 | ||
213 | EntityBase presenceEntity; | 216 | EntityBase presenceEntity; |
214 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) | 217 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) |
@@ -220,48 +223,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
220 | 223 | ||
221 | void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 224 | void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
222 | { | 225 | { |
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 | } | 226 | } |
266 | 227 | ||
267 | public void Close() | 228 | public void Close() |
@@ -286,15 +247,19 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
286 | { | 247 | { |
287 | LandData newData = data.Copy(); | 248 | LandData newData = data.Copy(); |
288 | newData.LocalID = local_id; | 249 | newData.LocalID = local_id; |
250 | ILandObject landobj = null; | ||
289 | 251 | ||
290 | lock (m_landList) | 252 | lock (m_landList) |
291 | { | 253 | { |
292 | if (m_landList.ContainsKey(local_id)) | 254 | if (m_landList.ContainsKey(local_id)) |
293 | { | 255 | { |
294 | m_landList[local_id].LandData = newData; | 256 | m_landList[local_id].LandData = newData; |
295 | m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); | 257 | landobj = m_landList[local_id]; |
258 | // m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); | ||
296 | } | 259 | } |
297 | } | 260 | } |
261 | if(landobj != null) | ||
262 | m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landobj); | ||
298 | } | 263 | } |
299 | 264 | ||
300 | public bool AllowedForcefulBans | 265 | public bool AllowedForcefulBans |
@@ -324,14 +289,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
324 | protected ILandObject CreateDefaultParcel() | 289 | protected ILandObject CreateDefaultParcel() |
325 | { | 290 | { |
326 | m_log.DebugFormat( | 291 | m_log.DebugFormat( |
327 | "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); | 292 | "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); |
328 | 293 | ||
329 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); | 294 | ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); |
330 | fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); | 295 | fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); |
331 | fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 296 | fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
332 | fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | 297 | fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); |
333 | 298 | ||
334 | return AddLandObject(fullSimParcel); | 299 | return AddLandObject(fullSimParcel); |
335 | } | 300 | } |
336 | 301 | ||
337 | public List<ILandObject> AllParcels() | 302 | public List<ILandObject> AllParcels() |
@@ -380,10 +345,16 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
380 | private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) | 345 | private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) |
381 | { | 346 | { |
382 | if (m_scene.Permissions.IsGod(avatar.UUID)) return; | 347 | if (m_scene.Permissions.IsGod(avatar.UUID)) return; |
383 | if (position.HasValue) | 348 | |
384 | { | 349 | if (!position.HasValue) |
385 | forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; | 350 | return; |
386 | } | 351 | |
352 | bool isFlying = avatar.PhysicsActor.Flying; | ||
353 | avatar.RemoveFromPhysicalScene(); | ||
354 | |||
355 | avatar.AbsolutePosition = (Vector3)position; | ||
356 | |||
357 | avatar.AddToPhysicalScene(isFlying); | ||
387 | } | 358 | } |
388 | 359 | ||
389 | public void SendYouAreRestrictedNotice(ScenePresence avatar) | 360 | public void SendYouAreRestrictedNotice(ScenePresence avatar) |
@@ -403,29 +374,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
403 | } | 374 | } |
404 | 375 | ||
405 | if (parcelAvatarIsEntering != null) | 376 | if (parcelAvatarIsEntering != null) |
406 | { | 377 | EnforceBans(parcelAvatarIsEntering, avatar); |
407 | if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) | ||
408 | { | ||
409 | if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) | ||
410 | { | ||
411 | SendYouAreBannedNotice(avatar); | ||
412 | ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar)); | ||
413 | } | ||
414 | else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) | ||
415 | { | ||
416 | SendYouAreRestrictedNotice(avatar); | ||
417 | ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar)); | ||
418 | } | ||
419 | else | ||
420 | { | ||
421 | avatar.sentMessageAboutRestrictedParcelFlyingDown = true; | ||
422 | } | ||
423 | } | ||
424 | else | ||
425 | { | ||
426 | avatar.sentMessageAboutRestrictedParcelFlyingDown = true; | ||
427 | } | ||
428 | } | ||
429 | } | 378 | } |
430 | } | 379 | } |
431 | 380 | ||
@@ -454,30 +403,51 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
454 | 403 | ||
455 | public void SendLandUpdate(ScenePresence avatar, bool force) | 404 | public void SendLandUpdate(ScenePresence avatar, bool force) |
456 | { | 405 | { |
406 | |||
407 | /* stop sendind same data twice | ||
408 | ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), | ||
409 | (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); | ||
410 | |||
411 | if (over != null) | ||
412 | { | ||
413 | |||
414 | if (force) | ||
415 | { | ||
416 | if (!avatar.IsChildAgent) | ||
417 | { | ||
418 | over.SendLandUpdateToClient(avatar.ControllingClient); | ||
419 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, | ||
420 | m_scene.RegionInfo.RegionID); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | if (avatar.currentParcelUUID != over.LandData.GlobalID) | ||
425 | { | ||
426 | if (!avatar.IsChildAgent) | ||
427 | { | ||
428 | over.SendLandUpdateToClient(avatar.ControllingClient); | ||
429 | avatar.currentParcelUUID = over.LandData.GlobalID; | ||
430 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, | ||
431 | m_scene.RegionInfo.RegionID); | ||
432 | } | ||
433 | } | ||
434 | */ | ||
435 | if (avatar.IsChildAgent) | ||
436 | return; | ||
437 | |||
457 | ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), | 438 | ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), |
458 | (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); | 439 | (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); |
459 | 440 | ||
460 | if (over != null) | 441 | if (over != null) |
461 | { | 442 | { |
462 | if (force) | 443 | bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID); |
444 | if (force || NotsameID) | ||
463 | { | 445 | { |
464 | if (!avatar.IsChildAgent) | 446 | over.SendLandUpdateToClient(avatar.ControllingClient); |
465 | { | 447 | if (NotsameID) |
466 | over.SendLandUpdateToClient(avatar.ControllingClient); | ||
467 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, | ||
468 | m_scene.RegionInfo.RegionID); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | if (avatar.currentParcelUUID != over.LandData.GlobalID) | ||
473 | { | ||
474 | if (!avatar.IsChildAgent) | ||
475 | { | ||
476 | over.SendLandUpdateToClient(avatar.ControllingClient); | ||
477 | avatar.currentParcelUUID = over.LandData.GlobalID; | 448 | avatar.currentParcelUUID = over.LandData.GlobalID; |
478 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, | 449 | m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, |
479 | m_scene.RegionInfo.RegionID); | 450 | m_scene.RegionInfo.RegionID); |
480 | } | ||
481 | } | 451 | } |
482 | } | 452 | } |
483 | } | 453 | } |
@@ -529,6 +499,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
529 | //when we are finally in a safe place, lets release the forced position lock | 499 | //when we are finally in a safe place, lets release the forced position lock |
530 | forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); | 500 | forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); |
531 | } | 501 | } |
502 | EnforceBans(parcel, clientAvatar); | ||
532 | } | 503 | } |
533 | } | 504 | } |
534 | 505 | ||
@@ -676,21 +647,28 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
676 | /// </summary> | 647 | /// </summary> |
677 | public void Clear(bool setupDefaultParcel) | 648 | public void Clear(bool setupDefaultParcel) |
678 | { | 649 | { |
650 | Dictionary<int, ILandObject> landworkList; | ||
651 | // move to work pointer since we are deleting it all | ||
679 | lock (m_landList) | 652 | lock (m_landList) |
680 | { | 653 | { |
681 | foreach (ILandObject lo in m_landList.Values) | 654 | landworkList = m_landList; |
682 | { | 655 | m_landList = new Dictionary<int, ILandObject>(); |
683 | //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); | 656 | } |
684 | m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); | ||
685 | } | ||
686 | 657 | ||
687 | m_landList.Clear(); | 658 | // this 2 methods have locks (now) |
659 | ResetSimLandObjects(); | ||
688 | 660 | ||
689 | ResetSimLandObjects(); | 661 | if (setupDefaultParcel) |
662 | CreateDefaultParcel(); | ||
690 | 663 | ||
691 | if (setupDefaultParcel) | 664 | // fire outside events unlocked |
692 | CreateDefaultParcel(); | 665 | foreach (ILandObject lo in landworkList.Values) |
666 | { | ||
667 | //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); | ||
668 | m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); | ||
693 | } | 669 | } |
670 | landworkList.Clear(); | ||
671 | |||
694 | } | 672 | } |
695 | 673 | ||
696 | private void performFinalLandJoin(ILandObject master, ILandObject slave) | 674 | private void performFinalLandJoin(ILandObject master, ILandObject slave) |
@@ -737,7 +715,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
737 | int x; | 715 | int x; |
738 | int y; | 716 | int y; |
739 | 717 | ||
740 | if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) | 718 | if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0) |
741 | return null; | 719 | return null; |
742 | 720 | ||
743 | try | 721 | try |
@@ -787,14 +765,13 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
787 | { | 765 | { |
788 | try | 766 | try |
789 | { | 767 | { |
790 | return m_landList[m_landIDList[x / 4, y / 4]]; | 768 | //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4])) |
769 | return m_landList[m_landIDList[x / 4, y / 4]]; | ||
770 | //else | ||
771 | // return null; | ||
791 | } | 772 | } |
792 | catch (IndexOutOfRangeException) | 773 | catch (IndexOutOfRangeException) |
793 | { | 774 | { |
794 | // m_log.WarnFormat( | ||
795 | // "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}", | ||
796 | // x, y, m_scene.RegionInfo.RegionName); | ||
797 | |||
798 | return null; | 775 | return null; |
799 | } | 776 | } |
800 | } | 777 | } |
@@ -1078,6 +1055,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1078 | //Owner Flag | 1055 | //Owner Flag |
1079 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); | 1056 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); |
1080 | } | 1057 | } |
1058 | else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID)) | ||
1059 | { | ||
1060 | tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP); | ||
1061 | } | ||
1081 | else if (currentParcelBlock.LandData.SalePrice > 0 && | 1062 | else if (currentParcelBlock.LandData.SalePrice > 0 && |
1082 | (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || | 1063 | (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || |
1083 | currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) | 1064 | currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) |
@@ -1158,8 +1139,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1158 | { | 1139 | { |
1159 | if (!temp.Contains(currentParcel)) | 1140 | if (!temp.Contains(currentParcel)) |
1160 | { | 1141 | { |
1161 | currentParcel.ForceUpdateLandInfo(); | 1142 | if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId)) |
1162 | temp.Add(currentParcel); | 1143 | { |
1144 | currentParcel.ForceUpdateLandInfo(); | ||
1145 | temp.Add(currentParcel); | ||
1146 | } | ||
1163 | } | 1147 | } |
1164 | } | 1148 | } |
1165 | } | 1149 | } |
@@ -1378,8 +1362,26 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1378 | 1362 | ||
1379 | public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) | 1363 | public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) |
1380 | { | 1364 | { |
1381 | // m_log.DebugFormat( | 1365 | Dictionary<int, ILandObject> landworkList; |
1382 | // "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); | 1366 | // move to work pointer since we are deleting it all |
1367 | lock (m_landList) | ||
1368 | { | ||
1369 | landworkList = m_landList; | ||
1370 | m_landList = new Dictionary<int, ILandObject>(); | ||
1371 | } | ||
1372 | |||
1373 | //Remove all the land objects in the sim and then process our new data | ||
1374 | foreach (int n in landworkList.Keys) | ||
1375 | { | ||
1376 | m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID); | ||
1377 | } | ||
1378 | landworkList.Clear(); | ||
1379 | |||
1380 | lock (m_landList) | ||
1381 | { | ||
1382 | m_landIDList.Initialize(); | ||
1383 | m_landList.Clear(); | ||
1384 | } | ||
1383 | 1385 | ||
1384 | for (int i = 0; i < data.Count; i++) | 1386 | for (int i = 0; i < data.Count; i++) |
1385 | IncomingLandObjectFromStorage(data[i]); | 1387 | IncomingLandObjectFromStorage(data[i]); |
@@ -1387,10 +1389,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1387 | 1389 | ||
1388 | public void IncomingLandObjectFromStorage(LandData data) | 1390 | public void IncomingLandObjectFromStorage(LandData data) |
1389 | { | 1391 | { |
1392 | |||
1390 | ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); | 1393 | ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); |
1391 | new_land.LandData = data.Copy(); | 1394 | new_land.LandData = data.Copy(); |
1392 | new_land.SetLandBitmapFromByteArray(); | 1395 | new_land.SetLandBitmapFromByteArray(); |
1393 | AddLandObject(new_land); | 1396 | AddLandObject(new_land); |
1397 | new_land.SendLandUpdateToAvatarsOverMe(); | ||
1394 | } | 1398 | } |
1395 | 1399 | ||
1396 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) | 1400 | public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) |
@@ -1408,7 +1412,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1408 | 1412 | ||
1409 | public void EventManagerOnNoLandDataFromStorage() | 1413 | public void EventManagerOnNoLandDataFromStorage() |
1410 | { | 1414 | { |
1411 | lock (m_landList) | 1415 | // called methods already have locks |
1416 | // lock (m_landList) | ||
1412 | { | 1417 | { |
1413 | ResetSimLandObjects(); | 1418 | ResetSimLandObjects(); |
1414 | CreateDefaultParcel(); | 1419 | CreateDefaultParcel(); |
@@ -1673,6 +1678,168 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1673 | 1678 | ||
1674 | UpdateLandObject(localID, land.LandData); | 1679 | UpdateLandObject(localID, land.LandData); |
1675 | } | 1680 | } |
1681 | |||
1682 | public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID) | ||
1683 | { | ||
1684 | ILandObject land = null; | ||
1685 | List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels(); | ||
1686 | foreach (ILandObject landObject in Land) | ||
1687 | { | ||
1688 | if (landObject.LandData.LocalID == landID) | ||
1689 | { | ||
1690 | land = landObject; | ||
1691 | } | ||
1692 | } | ||
1693 | land.DeedToGroup(DefaultGodParcelGroup); | ||
1694 | land.LandData.Name = DefaultGodParcelName; | ||
1695 | land.SendLandUpdateToAvatarsOverMe(); | ||
1696 | } | ||
1697 | |||
1698 | private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID) | ||
1699 | { | ||
1700 | ScenePresence SP; | ||
1701 | ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP); | ||
1702 | List<SceneObjectGroup> returns = new List<SceneObjectGroup>(); | ||
1703 | if (SP.UserLevel != 0) | ||
1704 | { | ||
1705 | if (flags == 0) //All parcels, scripted or not | ||
1706 | { | ||
1707 | ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) | ||
1708 | { | ||
1709 | if (e.OwnerID == targetID) | ||
1710 | { | ||
1711 | returns.Add(e); | ||
1712 | } | ||
1713 | } | ||
1714 | ); | ||
1715 | } | ||
1716 | if (flags == 4) //All parcels, scripted object | ||
1717 | { | ||
1718 | ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) | ||
1719 | { | ||
1720 | if (e.OwnerID == targetID) | ||
1721 | { | ||
1722 | if (e.ContainsScripts()) | ||
1723 | { | ||
1724 | returns.Add(e); | ||
1725 | } | ||
1726 | } | ||
1727 | } | ||
1728 | ); | ||
1729 | } | ||
1730 | if (flags == 4) //not target parcel, scripted object | ||
1731 | { | ||
1732 | ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) | ||
1733 | { | ||
1734 | if (e.OwnerID == targetID) | ||
1735 | { | ||
1736 | ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y); | ||
1737 | if (landobject.LandData.OwnerID != e.OwnerID) | ||
1738 | { | ||
1739 | if (e.ContainsScripts()) | ||
1740 | { | ||
1741 | returns.Add(e); | ||
1742 | } | ||
1743 | } | ||
1744 | } | ||
1745 | } | ||
1746 | ); | ||
1747 | } | ||
1748 | foreach (SceneObjectGroup ol in returns) | ||
1749 | { | ||
1750 | ReturnObject(ol, client); | ||
1751 | } | ||
1752 | } | ||
1753 | } | ||
1754 | public void ReturnObject(SceneObjectGroup obj, IClientAPI client) | ||
1755 | { | ||
1756 | SceneObjectGroup[] objs = new SceneObjectGroup[1]; | ||
1757 | objs[0] = obj; | ||
1758 | ((Scene)client.Scene).returnObjects(objs, client.AgentId); | ||
1759 | } | ||
1760 | |||
1761 | Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); | ||
1762 | |||
1763 | public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) | ||
1764 | { | ||
1765 | ScenePresence targetAvatar = null; | ||
1766 | ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar); | ||
1767 | ScenePresence parcelManager = null; | ||
1768 | ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); | ||
1769 | System.Threading.Timer Timer; | ||
1770 | |||
1771 | if (targetAvatar.UserLevel == 0) | ||
1772 | { | ||
1773 | ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); | ||
1774 | if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) | ||
1775 | return; | ||
1776 | if (flags == 0) | ||
1777 | { | ||
1778 | targetAvatar.AllowMovement = false; | ||
1779 | targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world."); | ||
1780 | parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen."); | ||
1781 | System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen); | ||
1782 | Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0); | ||
1783 | Timers.Add(targetAvatar.UUID, Timer); | ||
1784 | } | ||
1785 | else | ||
1786 | { | ||
1787 | targetAvatar.AllowMovement = true; | ||
1788 | targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you."); | ||
1789 | parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen."); | ||
1790 | Timers.TryGetValue(targetAvatar.UUID, out Timer); | ||
1791 | Timers.Remove(targetAvatar.UUID); | ||
1792 | Timer.Dispose(); | ||
1793 | } | ||
1794 | } | ||
1795 | } | ||
1796 | private void OnEndParcelFrozen(object avatar) | ||
1797 | { | ||
1798 | ScenePresence targetAvatar = (ScenePresence)avatar; | ||
1799 | targetAvatar.AllowMovement = true; | ||
1800 | System.Threading.Timer Timer; | ||
1801 | Timers.TryGetValue(targetAvatar.UUID, out Timer); | ||
1802 | Timers.Remove(targetAvatar.UUID); | ||
1803 | targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); | ||
1804 | } | ||
1805 | |||
1806 | |||
1807 | public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) | ||
1808 | { | ||
1809 | ScenePresence targetAvatar = null; | ||
1810 | ScenePresence parcelManager = null; | ||
1811 | |||
1812 | // Must have presences | ||
1813 | if (!m_scene.TryGetScenePresence(target, out targetAvatar) || | ||
1814 | !m_scene.TryGetScenePresence(client.AgentId, out parcelManager)) | ||
1815 | return; | ||
1816 | |||
1817 | // Cannot eject estate managers or gods | ||
1818 | if (m_scene.Permissions.IsAdministrator(target)) | ||
1819 | return; | ||
1820 | |||
1821 | // Check if you even have permission to do this | ||
1822 | ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); | ||
1823 | if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && | ||
1824 | !m_scene.Permissions.IsAdministrator(client.AgentId)) | ||
1825 | return; | ||
1826 | |||
1827 | Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); | ||
1828 | |||
1829 | targetAvatar.TeleportWithMomentum(pos, null); | ||
1830 | targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); | ||
1831 | parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); | ||
1832 | |||
1833 | if ((flags & 1) != 0) // Ban TODO: Remove magic number | ||
1834 | { | ||
1835 | LandAccessEntry entry = new LandAccessEntry(); | ||
1836 | entry.AgentID = targetAvatar.UUID; | ||
1837 | entry.Flags = AccessList.Ban; | ||
1838 | entry.Expires = 0; // Perm | ||
1839 | |||
1840 | land.LandData.ParcelAccessList.Add(entry); | ||
1841 | } | ||
1842 | } | ||
1676 | 1843 | ||
1677 | protected void InstallInterfaces() | 1844 | protected void InstallInterfaces() |
1678 | { | 1845 | { |
@@ -1735,5 +1902,27 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1735 | 1902 | ||
1736 | MainConsole.Instance.Output(report.ToString()); | 1903 | MainConsole.Instance.Output(report.ToString()); |
1737 | } | 1904 | } |
1905 | |||
1906 | public void EnforceBans(ILandObject land, ScenePresence avatar) | ||
1907 | { | ||
1908 | if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT) | ||
1909 | return; | ||
1910 | |||
1911 | if (land.IsEitherBannedOrRestricted(avatar.UUID)) | ||
1912 | { | ||
1913 | if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y))) | ||
1914 | { | ||
1915 | Vector3? pos = m_scene.GetNearestAllowedPosition(avatar); | ||
1916 | if (pos == null) | ||
1917 | m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient); | ||
1918 | else | ||
1919 | ForceAvatarToPosition(avatar, (Vector3)pos); | ||
1920 | } | ||
1921 | else | ||
1922 | { | ||
1923 | ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition); | ||
1924 | } | ||
1925 | } | ||
1926 | } | ||
1738 | } | 1927 | } |
1739 | } | 1928 | } |