From 6f3c905744e674f3cca555a4d36ede2139fcb9d7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Apr 2013 00:24:48 +0100 Subject: [PATCH] Add Avination's support for parcel eject and freeze --- .../World/Land/LandManagementModule.cs | 85 +++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 40 +++++---- 2 files changed, 110 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index dbf5138611..693de1dff4 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -210,6 +210,9 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelInfoRequest += ClientOnParcelInfoRequest; client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; client.OnPreAgentUpdate += ClientOnPreAgentUpdate; + client.OnParcelEjectUser += ClientOnParcelEjectUser; + client.OnParcelFreezeUser += ClientOnParcelFreezeUser; + EntityBase presenceEntity; if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) @@ -1738,6 +1741,88 @@ namespace OpenSim.Region.CoreModules.World.Land UpdateLandObject(localID, land.LandData); } + Dictionary Timers = new Dictionary(); + + public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) + { + ScenePresence targetAvatar = null; + ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar); + ScenePresence parcelManager = null; + ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); + System.Threading.Timer Timer; + + if (targetAvatar.UserLevel == 0) + { + ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); + if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) + return; + if (flags == 0) + { + targetAvatar.AllowMovement = false; + targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world."); + parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen."); + System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen); + Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0); + Timers.Add(targetAvatar.UUID, Timer); + } + else + { + targetAvatar.AllowMovement = true; + targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you."); + parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen."); + Timers.TryGetValue(targetAvatar.UUID, out Timer); + Timers.Remove(targetAvatar.UUID); + Timer.Dispose(); + } + } + } + + private void OnEndParcelFrozen(object avatar) + { + ScenePresence targetAvatar = (ScenePresence)avatar; + targetAvatar.AllowMovement = true; + System.Threading.Timer Timer; + Timers.TryGetValue(targetAvatar.UUID, out Timer); + Timers.Remove(targetAvatar.UUID); + targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); + } + + public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) + { + ScenePresence targetAvatar = null; + ScenePresence parcelManager = null; + + // Must have presences + if (!m_scene.TryGetScenePresence(target, out targetAvatar) || + !m_scene.TryGetScenePresence(client.AgentId, out parcelManager)) + return; + + // Cannot eject estate managers or gods + if (m_scene.Permissions.IsAdministrator(target)) + return; + + // Check if you even have permission to do this + ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); + if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && + !m_scene.Permissions.IsAdministrator(client.AgentId)) + return; + Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); + + targetAvatar.TeleportWithMomentum(pos, null); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); + + if ((flags & 1) != 0) // Ban TODO: Remove magic number + { + LandAccessEntry entry = new LandAccessEntry(); + entry.AgentID = targetAvatar.UUID; + entry.Flags = AccessList.Ban; + entry.Expires = 0; // Perm + + land.LandData.ParcelAccessList.Add(entry); + } + } + protected void InstallInterfaces() { Command clearCommand diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f50d3cd821..69fe137bcb 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5138,9 +5138,14 @@ namespace OpenSim.Region.Framework.Scenes get { return m_allowScriptCrossings; } } - public Vector3? GetNearestAllowedPosition(ScenePresence avatar) + public Vector3 GetNearestAllowedPosition(ScenePresence avatar) { - ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + return GetNearestAllowedPosition(avatar, null); + } + + public Vector3 GetNearestAllowedPosition(ScenePresence avatar, ILandObject excludeParcel) + { + ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, excludeParcel); if (nearestParcel != null) { @@ -5149,10 +5154,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); if (nearestPoint != null) { -// m_log.DebugFormat( -// "[SCENE]: Found a sane previous position based on velocity for {0}, sending them to {1} in {2}", -// avatar.Name, nearestPoint, nearestParcel.LandData.Name); - + Debug.WriteLine("Found a sane previous position based on velocity, sending them to: " + nearestPoint.ToString()); return nearestPoint.Value; } @@ -5162,24 +5164,27 @@ namespace OpenSim.Region.Framework.Scenes nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); if (nearestPoint != null) { -// m_log.DebugFormat( -// "[SCENE]: {0} had a zero velocity, sending them to {1}", avatar.Name, nearestPoint); - + Debug.WriteLine("They had a zero velocity, sending them to: " + nearestPoint.ToString()); return nearestPoint.Value; } - //Ultimate backup if we have no idea where they are -// m_log.DebugFormat( -// "[SCENE]: No idea where {0} is, sending them to {1}", avatar.Name, avatar.lastKnownAllowedPosition); + ILandObject dest = LandChannel.GetLandObject(avatar.lastKnownAllowedPosition.X, avatar.lastKnownAllowedPosition.Y); + if (dest != excludeParcel) + { + // Ultimate backup if we have no idea where they are and + // the last allowed position was in another parcel + Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString()); + return avatar.lastKnownAllowedPosition; + } - return avatar.lastKnownAllowedPosition; + // else fall through to region edge } //Go to the edge, this happens in teleporting to a region with no available parcels Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); - + return nearestRegionEdgePoint; } @@ -5205,6 +5210,11 @@ namespace OpenSim.Region.Framework.Scenes } public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y) + { + return GetNearestAllowedParcel(avatarId, x, y, null); + } + + public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y, ILandObject excludeParcel) { List all = AllParcels(); float minParcelDistance = float.MaxValue; @@ -5212,7 +5222,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (var parcel in all) { - if (!parcel.IsEitherBannedOrRestricted(avatarId)) + if (!parcel.IsEitherBannedOrRestricted(avatarId) && parcel != excludeParcel) { float parcelDistance = GetParcelDistancefromPoint(parcel, x, y); if (parcelDistance < minParcelDistance)