From 41ae6f06e01e29ae4d9637d6682a47f6d4964f75 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 16 Dec 2015 22:16:51 +0000 Subject: several changes to parcels access control and scenepresence updates rates --- .../CoreModules/World/Land/LandManagementModule.cs | 221 ++++++++++----------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 119 +++++------ 2 files changed, 169 insertions(+), 171 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 7b4c724..65aabac 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -98,6 +98,7 @@ namespace OpenSim.Region.CoreModules.World.Land private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; private bool m_allowedForcefulBans = true; + private bool m_showBansLines = true; private UUID DefaultGodParcelGroup; private string DefaultGodParcelName; @@ -107,7 +108,7 @@ namespace OpenSim.Region.CoreModules.World.Land /// /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. /// - private Dictionary forcedPosition = new Dictionary(); + private HashSet forcedPosition = new HashSet(); // Enables limiting parcel layer info transmission when doing simple updates @@ -133,6 +134,9 @@ namespace OpenSim.Region.CoreModules.World.Land parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance); DefaultGodParcelGroup = new UUID(landManagementConfig.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString())); DefaultGodParcelName = landManagementConfig.GetString("DefaultAdministratorParcelName", "Default Parcel"); + bool disablebans = landManagementConfig.GetBoolean("DisableParcelBans", !m_allowedForcefulBans); + m_allowedForcefulBans = !disablebans; + m_showBansLines = landManagementConfig.GetBoolean("ShowParcelBansLines", m_showBansLines); } } @@ -212,15 +216,6 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelEjectUser += ClientOnParcelEjectUser; client.OnParcelFreezeUser += ClientOnParcelFreezeUser; client.OnSetStartLocationRequest += ClientOnSetHome; - -/* avatar is still a child here position is unknown - EntityBase presenceEntity; - if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) - { - SendLandUpdate((ScenePresence)presenceEntity, true); - SendParcelOverlay(client); - } -*/ } public void EventMakeChildAgent(ScenePresence avatar) @@ -316,9 +311,9 @@ namespace OpenSim.Region.CoreModules.World.Land public List ParcelsNearPoint(Vector3 position) { List parcelsNear = new List(); - for (int x = -4; x <= 4; x += 4) + for (int x = -8; x <= 8; x += 4) { - for (int y = -4; y <= 4; y += 4) + for (int y = -8; y <= 8; y += 4) { ILandObject check = GetLandObject(position.X + x, position.Y + y); if (check != null) @@ -334,17 +329,81 @@ namespace OpenSim.Region.CoreModules.World.Land return parcelsNear; } - public void SendYouAreBannedNotice(ScenePresence avatar) + // checks and enforces bans or restrictions + // returns true if enforced + public bool EnforceBans(ILandObject land, ScenePresence avatar) { - if (AllowedForcefulBans) + Vector3 agentpos = avatar.AbsolutePosition; + float h = m_scene.GetGroundHeight(agentpos.X, agentpos.Y) + LandChannel.BAN_LINE_SAFETY_HEIGHT; + float zdif = avatar.AbsolutePosition.Z - h; + if (zdif > 0 ) + { + forcedPosition.Remove(avatar.UUID); + avatar.lastKnownAllowedPosition = agentpos; + return false; + } + + bool ban = false; + string reason = ""; + if (land.IsRestrictedFromLand(avatar.UUID)) { - avatar.ControllingClient.SendAlertMessage( - "You are not allowed on this parcel because you are banned. Please go away."); + reason = "You do not have access to the parcel"; + ban = true; + } + + if (land.IsBannedFromLand(avatar.UUID)) + { + if ( m_allowedForcefulBans) + { + reason ="You are banned from parcel"; + ban = true; + } + else if(!ban) + { + if (forcedPosition.Contains(avatar.UUID)) + avatar.ControllingClient.SendAlertMessage("You are banned from parcel, please leave by your own will"); + forcedPosition.Remove(avatar.UUID); + avatar.lastKnownAllowedPosition = agentpos; + return false; + } + } + + if(ban) + { + if (!forcedPosition.Contains(avatar.UUID)) + avatar.ControllingClient.SendAlertMessage(reason); + + if(zdif > -4f) + { + + agentpos.Z = h + 4.0f; + ForceAvatarToPosition(avatar, agentpos); + return true; + } + + if (land.ContainsPoint((int)avatar.lastKnownAllowedPosition.X, + (int) avatar.lastKnownAllowedPosition.Y)) + { + Vector3? pos = m_scene.GetNearestAllowedPosition(avatar); + if (pos == null) + { + forcedPosition.Remove(avatar.UUID); + m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient); + } + else + ForceAvatarToPosition(avatar, (Vector3)pos); + } + else + { + ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition); + } + return true; } else { - avatar.ControllingClient.SendAlertMessage( - "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim!"); + forcedPosition.Remove(avatar.UUID); + avatar.lastKnownAllowedPosition = agentpos; + return false; } } @@ -360,12 +419,7 @@ namespace OpenSim.Region.CoreModules.World.Land avatar.Velocity = Vector3.Zero; if(avatar.IsSatOnObject) avatar.StandUp(); - } - - public void SendYouAreRestrictedNotice(ScenePresence avatar) - { - avatar.ControllingClient.SendAlertMessage( - "You are not allowed on this parcel because the land owner has restricted access."); + forcedPosition.Add(avatar.UUID); } public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID) @@ -378,15 +432,20 @@ namespace OpenSim.Region.CoreModules.World.Land parcelAvatarIsEntering = m_landList[localLandID]; } - if (parcelAvatarIsEntering != null) + if (parcelAvatarIsEntering != null && + avatar.currentParcelUUID != parcelAvatarIsEntering.LandData.GlobalID) + { + SendLandUpdate(avatar, parcelAvatarIsEntering); + avatar.currentParcelUUID = parcelAvatarIsEntering.LandData.GlobalID; EnforceBans(parcelAvatarIsEntering, avatar); + } } } public void SendOutNearestBanLine(IClientAPI client) { ScenePresence sp = m_scene.GetScenePresence(client.AgentId); - if (sp == null) + if (sp == null || sp.IsDeleted) return; List checkLandParcels = ParcelsNearPoint(sp.AbsolutePosition); @@ -413,7 +472,6 @@ namespace OpenSim.Region.CoreModules.World.Land if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out avatar)) return; - if (!avatar.IsChildAgent) { ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); @@ -426,77 +484,26 @@ namespace OpenSim.Region.CoreModules.World.Land SendParcelOverlay(remoteClient); } - public void SendLandUpdate(ScenePresence avatar, bool force) + public void SendLandUpdate(ScenePresence avatar, ILandObject over) { if (avatar.IsChildAgent) return; - ILandObject over = GetLandObjectClipedXY(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - if (over != null) { - bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID); - if (force || NotsameID) - { - over.SendLandUpdateToClient(avatar.ControllingClient); + over.SendLandUpdateToClient(avatar.ControllingClient); // sl doesnt seem to send this now, as it used 2 // SendParcelOverlay(avatar.ControllingClient); - avatar.currentParcelUUID = over.LandData.GlobalID; - m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, - m_scene.RegionInfo.RegionID); - } } } - public void SendLandUpdate(ScenePresence avatar) + public void EventManagerOnSignificantClientMovement(ScenePresence avatar) { - SendLandUpdate(avatar, false); - } + if (avatar.IsChildAgent) + return; - public void EventManagerOnSignificantClientMovement(ScenePresence clientAvatar) - { - SendLandUpdate(clientAvatar); - SendOutNearestBanLine(clientAvatar.ControllingClient); - ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); - if (parcel != null) - { - if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HEIGHT && - clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) - { - EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID, - m_scene.RegionInfo.RegionID); - //They are going under the safety line! - if (!parcel.IsBannedFromLand(clientAvatar.UUID)) - { - clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; - } - } - else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HEIGHT && - parcel.IsBannedFromLand(clientAvatar.UUID)) - { - //once we've sent the message once, keep going toward the target until we are done - if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) - { - SendYouAreBannedNotice(clientAvatar); - ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); - } - } - else if (parcel.IsRestrictedFromLand(clientAvatar.UUID)) - { - //once we've sent the message once, keep going toward the target until we are done - if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) - { - SendYouAreRestrictedNotice(clientAvatar); - ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); - } - } - else - { - //when we are finally in a safe place, lets release the forced position lock - forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); - } - EnforceBans(parcel, clientAvatar); - } + if ( m_allowedForcefulBans && m_showBansLines) + SendOutNearestBanLine(avatar.ControllingClient); } /// @@ -505,12 +512,22 @@ namespace OpenSim.Region.CoreModules.World.Land /// public void EventManagerOnClientMovement(ScenePresence avatar) { + if (avatar.IsChildAgent) + return; + Vector3 pos = avatar.AbsolutePosition; ILandObject over = GetLandObject(pos.X, pos.Y); if (over != null) { - if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || pos.Z >= LandChannel.BAN_LINE_SAFETY_HEIGHT)) - avatar.lastKnownAllowedPosition = pos; + EnforceBans(over, avatar); + pos = avatar.AbsolutePosition; + ILandObject newover = GetLandObject(pos.X, pos.Y); + if(over != newover || avatar.currentParcelUUID != newover.LandData.GlobalID) + { + avatar.currentParcelUUID = newover.LandData.GlobalID; + m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, + newover.LandData.LocalID, m_scene.RegionInfo.RegionID); + } } } @@ -1216,7 +1233,6 @@ namespace OpenSim.Region.CoreModules.World.Land } } } - } if (byteArrayCount > 0) @@ -1965,8 +1981,7 @@ namespace OpenSim.Region.CoreModules.World.Land returns.Add(e); } } - } - ); + }); } if (flags == 4) //not target parcel, scripted object { @@ -1983,8 +1998,7 @@ namespace OpenSim.Region.CoreModules.World.Land } } } - } - ); + }); } foreach (SceneObjectGroup ol in returns) { @@ -2044,7 +2058,6 @@ namespace OpenSim.Region.CoreModules.World.Land 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; @@ -2247,28 +2260,6 @@ namespace OpenSim.Region.CoreModules.World.Land } - public void EnforceBans(ILandObject land, ScenePresence avatar) - { - if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HEIGHT) - return; - - if (land.IsEitherBannedOrRestricted(avatar.UUID)) - { - if (land.ContainsPoint((int)avatar.lastKnownAllowedPosition.X, (int)avatar.lastKnownAllowedPosition.Y)) - { - Vector3? pos = m_scene.GetNearestAllowedPosition(avatar); - if (pos == null) - m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient); - else - ForceAvatarToPosition(avatar, (Vector3)pos); - } - else - { - ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition); - } - } - } - private void AppendParcelReport(StringBuilder report, ILandObject lo) { LandData ld = lo.LandData; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4c3bc67..4c62127 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -150,8 +150,12 @@ namespace OpenSim.Region.Framework.Scenes /// Movement updates for agents in neighboring regions are sent directly to clients. /// This value only affects how often agent positions are sent to neighbor regions /// for things such as distance-based update prioritization + /// this are the square of real distances /// - public static readonly float SIGNIFICANT_MOVEMENT = 2.0f; + public static readonly float MOVEMENT = .25f; + public static readonly float SIGNIFICANT_MOVEMENT = 16.0f; + public static readonly float CHILDUPDATES_MOVEMENT = 100.0f; + public static readonly float CHILDUPDATES_TIME = 10000f; // min time between child updates (ms) private UUID m_previusParcelUUID = UUID.Zero; private UUID m_currentParcelUUID = UUID.Zero; @@ -189,6 +193,7 @@ namespace OpenSim.Region.Framework.Scenes public void sitSOGmoved() { +/* if (IsDeleted || !IsSatOnObject) //what me? nahh return; @@ -201,6 +206,7 @@ namespace OpenSim.Region.Framework.Scenes UUID parcelID = land.LandData.GlobalID; if (m_currentParcelUUID != parcelID) currentParcelUUID = parcelID; +*/ } @@ -325,6 +331,8 @@ namespace OpenSim.Region.Framework.Scenes private float m_sitAvatarHeight = 2.0f; + private bool childUpdatesActive = false; + private int lastChildUpdatesTime; private Vector3 m_lastChildAgentUpdatePosition; // private Vector3 m_lastChildAgentUpdateCamPosition; @@ -417,6 +425,7 @@ namespace OpenSim.Region.Framework.Scenes /// Position at which a significant movement was made /// private Vector3 posLastSignificantMove; + private Vector3 posLastMove; #region For teleports and crossings callbacks @@ -1021,9 +1030,11 @@ namespace OpenSim.Region.Framework.Scenes m_scriptEngines = m_scene.RequestModuleInterfaces(); - AbsolutePosition = posLastSignificantMove = CameraPosition = + AbsolutePosition = posLastMove = posLastSignificantMove = CameraPosition = m_lastCameraPosition = ControllingClient.StartPos; + childUpdatesActive = true; // disable it for now + m_reprioritization_timer = new Timer(world.ReprioritizationInterval); m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); m_reprioritization_timer.AutoReset = false; @@ -2024,6 +2035,9 @@ namespace OpenSim.Region.Framework.Scenes { m_agentTransfer.EnableChildAgents(this); } + // let updates be sent, with some delay + lastChildUpdatesTime = Util.EnvironmentTickCount() + 10000; + childUpdatesActive = false; // allow them } } @@ -2502,7 +2516,7 @@ namespace OpenSim.Region.Framework.Scenes if ((State & (uint)AgentState.Editing) != 0) SendAgentTerseUpdate(this); - m_scene.EventManager.TriggerOnClientMovement(this); +// m_scene.EventManager.TriggerOnClientMovement(this); } @@ -3464,7 +3478,8 @@ namespace OpenSim.Region.Framework.Scenes if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn) SendAvatarDataToAllAgents(); - if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + if (!IsSatOnObject || + !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) { @@ -3865,63 +3880,55 @@ namespace OpenSim.Region.Framework.Scenes /// protected void CheckForSignificantMovement() { - if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) + Vector3 pos = AbsolutePosition; + + Vector3 diff = pos - posLastMove; + if (diff.LengthSquared() > MOVEMENT) { - posLastSignificantMove = AbsolutePosition; + posLastMove = pos; + m_scene.EventManager.TriggerOnClientMovement(this); + } + + diff = pos - posLastSignificantMove; + if (diff.LengthSquared() > SIGNIFICANT_MOVEMENT) + { + posLastSignificantMove = pos; m_scene.EventManager.TriggerSignificantClientMovement(this); } - // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m - if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) + if(!childUpdatesActive) { - m_lastChildAgentUpdatePosition = AbsolutePosition; -// m_lastChildAgentUpdateCamPosition = CameraPosition; - -/* cadu is not used - ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); - cadu.ActiveGroupID = UUID.Zero.Guid; - cadu.AgentID = UUID.Guid; - cadu.alwaysrun = SetAlwaysRun; - cadu.AVHeight = Appearance.AvatarHeight; - cadu.cameraPosition = CameraPosition; - cadu.drawdistance = DrawDistance; - cadu.GroupAccess = 0; - cadu.Position = AbsolutePosition; - cadu.regionHandle = RegionHandle; - - // Throttles - float multiplier = 1; - - int childRegions = KnownRegionCount; - if (childRegions != 0) - multiplier = 1f / childRegions; - - // Minimum throttle for a child region is 1/4 of the root region throttle - if (multiplier <= 0.25f) - multiplier = 0.25f; - - cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); - cadu.Velocity = Velocity; -*/ - AgentPosition agentpos = new AgentPosition(); -// agentpos.CopyFrom(cadu, ControllingClient.SessionId); - - agentpos.AgentID = new UUID(UUID.Guid); - agentpos.SessionID = ControllingClient.SessionId; - - agentpos.Size = Appearance.AvatarSize; - - agentpos.Center = CameraPosition; - agentpos.Far = DrawDistance; - agentpos.Position = AbsolutePosition; - agentpos.Velocity = Velocity; - agentpos.RegionHandle = RegionHandle; - agentpos.Throttles = ControllingClient.GetThrottlesPacked(1); - - - // Let's get this out of the update loop - Util.FireAndForget( - o => m_scene.SendOutChildAgentUpdates(agentpos, this), null, "ScenePresence.SendOutChildAgentUpdates"); + int tdiff = Util.EnvironmentTickCountSubtract(lastChildUpdatesTime); + if(tdiff > CHILDUPDATES_TIME) + { + diff = pos - m_lastChildAgentUpdatePosition; + if (diff.LengthSquared() > CHILDUPDATES_MOVEMENT) + { + childUpdatesActive = true; + m_lastChildAgentUpdatePosition = pos; +// m_lastChildAgentUpdateCamPosition = CameraPosition; + + AgentPosition agentpos = new AgentPosition(); + agentpos.AgentID = new UUID(UUID.Guid); + agentpos.SessionID = ControllingClient.SessionId; + agentpos.Size = Appearance.AvatarSize; + agentpos.Center = CameraPosition; + agentpos.Far = DrawDistance; + agentpos.Position = AbsolutePosition; + agentpos.Velocity = Velocity; + agentpos.RegionHandle = RegionHandle; + agentpos.Throttles = ControllingClient.GetThrottlesPacked(1); + + // Let's get this out of the update loop + Util.FireAndForget( + o => + { + m_scene.SendOutChildAgentUpdates(agentpos, this); + lastChildUpdatesTime = Util.EnvironmentTickCount(); + childUpdatesActive= false; + }, null, "ScenePresence.SendOutChildAgentUpdates"); + } + } } } -- cgit v1.1