From d90b0c53ec747c512b1efccf6f25596dac9c3e41 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 28 Jan 2011 01:37:37 +0100 Subject: [PATCH] Fix bumping into sim borders and check estate bans for walking crossings --- .../EntityTransfer/EntityTransferModule.cs | 89 +++++++++++++++---- .../Interfaces/IEntityTransferModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +- .../Region/Framework/Scenes/ScenePresence.cs | 49 +++++++--- 4 files changed, 113 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 8bf2bf86dd..7804b7f779 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -53,6 +53,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected bool m_Enabled = false; protected Scene m_aScene; protected List m_agentsInTransit; + private ExpiringCache> m_bannedRegions = + new ExpiringCache>(); + #region ISharedRegionModule @@ -575,7 +578,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Crossings - public void Cross(ScenePresence agent, bool isFlying) + public bool Cross(ScenePresence agent, bool isFlying) { Scene scene = agent.Scene; Vector3 pos = agent.AbsolutePosition; @@ -611,6 +614,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { + agent.InTransit(); + neighboury = b.TriggerRegionY; neighbourx = b.TriggerRegionX; @@ -620,7 +625,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - return; + return true; } } @@ -632,6 +637,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { + agent.InTransit(); + neighboury = ba.TriggerRegionY; neighbourx = ba.TriggerRegionX; @@ -644,7 +651,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - return; + return true; } } @@ -664,6 +671,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { + agent.InTransit(); + neighboury = ba.TriggerRegionY; neighbourx = ba.TriggerRegionX; Vector3 newposition = pos; @@ -672,7 +681,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - return; + return true; } } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) @@ -694,6 +703,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { + agent.InTransit(); + neighboury = b.TriggerRegionY; neighbourx = b.TriggerRegionX; Vector3 newposition = pos; @@ -702,7 +713,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - return; + return true; } } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) @@ -738,9 +749,51 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } */ - CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; - d.BeginInvoke(agent, newpos, neighbourx, neighboury, isFlying, CrossAgentToNewRegionCompleted, d); + ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); + int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); + + ExpiringCache r; + DateTime banUntil; + + if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) + { + if (r.TryGetValue(neighbourHandle, out banUntil)) + { + if (DateTime.Now < banUntil) + return false; + r.Remove(neighbourHandle); + } + } + else + { + r = null; + } + + GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); + + if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId)) + { + if (r == null) + { + r = new ExpiringCache(); + r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); + + m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); + } + else + { + r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); + } + return false; + } + + agent.InTransit(); + + CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; + d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, CrossAgentToNewRegionCompleted, d); + + return true; } @@ -751,7 +804,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private void InformClientToInitateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) { - // This assumes that we know what our neighbors are. + // This assumes that we know what our neighbours are. InformClientToInitateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync; d.BeginInvoke(agent, regionX, regionY, position, initiatingScene, @@ -795,21 +848,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer icon.EndInvoke(iar); } - public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying); + public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying); /// - /// This Closes child agents on neighboring regions + /// This Closes child agents on neighbouring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// - protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying) + protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying) { + ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); Scene m_scene = agent.Scene; - ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - - int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); - GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); if (neighbourRegion != null && agent.ValidateAttachments()) { @@ -920,7 +971,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Enable Child Agent /// - /// This informs a single neighboring region about agent "avatar". + /// This informs a single neighbouring region about agent "avatar". /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// public void EnableChildAgent(ScenePresence sp, GridRegion region) @@ -977,7 +1028,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ScenePresence avatar, AgentCircuitData a, GridRegion reg, IPEndPoint endPoint, bool newAgent); /// - /// This informs all neighboring regions about agent "avatar". + /// This informs all neighbouring regions about agent "avatar". /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// public void EnableChildAgents(ScenePresence sp) @@ -1108,7 +1159,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer catch (ArgumentOutOfRangeException) { m_log.ErrorFormat( - "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbor list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", + "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", neighbour.ExternalHostName, neighbour.RegionHandle, neighbour.RegionLocX, @@ -1188,7 +1239,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } #endregion - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbor region {2} @ {3} " + + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + "and EstablishAgentCommunication with seed cap {4}", m_scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index e8738c465e..8b96de46fd 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.Framework.Interfaces void TeleportHome(UUID id, IClientAPI client); - void Cross(ScenePresence agent, bool isFlying); + bool Cross(ScenePresence agent, bool isFlying); void AgentArrivedAtDestination(UUID agent); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index dc08b4954c..4325ab8a49 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3861,14 +3861,16 @@ namespace OpenSim.Region.Framework.Scenes RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark)); } - public void CrossAgentToNewRegion(ScenePresence agent, bool isFlying) + public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) { if (m_teleportModule != null) - m_teleportModule.Cross(agent, isFlying); + return m_teleportModule.Cross(agent, isFlying); else { m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule"); } + + return false; } public void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1c276fa87f..cd70de8440 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2725,29 +2725,57 @@ namespace OpenSim.Region.Framework.Scenes // Makes sure avatar does not end up outside region if (neighbor <= 0) { - if (!needsTransit) + if (needsTransit) { if (m_requestedSitTargetUUID == UUID.Zero) { + bool isFlying = m_physicsActor.Flying; + RemoveFromPhysicalScene(); + Vector3 pos = AbsolutePosition; if (AbsolutePosition.X < 0) - pos.X += Velocity.X; + pos.X += Velocity.X * 2; else if (AbsolutePosition.X > Constants.RegionSize) - pos.X -= Velocity.X; + pos.X -= Velocity.X * 2; if (AbsolutePosition.Y < 0) - pos.Y += Velocity.Y; + pos.Y += Velocity.Y * 2; else if (AbsolutePosition.Y > Constants.RegionSize) - pos.Y -= Velocity.Y; + pos.Y -= Velocity.Y * 2; + Velocity = Vector3.Zero; AbsolutePosition = pos; + + AddToPhysicalScene(isFlying); } } } else if (neighbor > 0) - CrossToNewRegion(); + { + if (!CrossToNewRegion()) + { + if (m_requestedSitTargetUUID == UUID.Zero) + { + bool isFlying = m_physicsActor.Flying; + RemoveFromPhysicalScene(); + + Vector3 pos = AbsolutePosition; + if (AbsolutePosition.X < 0) + pos.X += Velocity.X * 2; + else if (AbsolutePosition.X > Constants.RegionSize) + pos.X -= Velocity.X * 2; + if (AbsolutePosition.Y < 0) + pos.Y += Velocity.Y * 2; + else if (AbsolutePosition.Y > Constants.RegionSize) + pos.Y -= Velocity.Y * 2; + Velocity = Vector3.Zero; + AbsolutePosition = pos; + + AddToPhysicalScene(isFlying); + } + } + } } else { - RemoveFromPhysicalScene(); // This constant has been inferred from experimentation // I'm not sure what this value should be, so I tried a few values. timeStep = 0.04f; @@ -2796,16 +2824,15 @@ namespace OpenSim.Region.Framework.Scenes /// If the neighbor accepts, remove the agent's viewable avatar from this scene /// set them to a child agent. /// - protected void CrossToNewRegion() + protected bool CrossToNewRegion() { - InTransit(); try { - m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); + return m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); } catch { - m_scene.CrossAgentToNewRegion(this, false); + return m_scene.CrossAgentToNewRegion(this, false); } }