Fix bumping into sim borders and check estate bans for walking crossings

viewer-2-initial-appearance
Melanie 2011-01-28 01:37:37 +01:00
parent 80bf95b7b4
commit d90b0c53ec
4 changed files with 113 additions and 33 deletions

View File

@ -53,6 +53,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected bool m_Enabled = false; protected bool m_Enabled = false;
protected Scene m_aScene; protected Scene m_aScene;
protected List<UUID> m_agentsInTransit; protected List<UUID> m_agentsInTransit;
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
#region ISharedRegionModule #region ISharedRegionModule
@ -575,7 +578,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Agent Crossings #region Agent Crossings
public void Cross(ScenePresence agent, bool isFlying) public bool Cross(ScenePresence agent, bool isFlying)
{ {
Scene scene = agent.Scene; Scene scene = agent.Scene;
Vector3 pos = agent.AbsolutePosition; Vector3 pos = agent.AbsolutePosition;
@ -611,6 +614,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
else else
{ {
agent.InTransit();
neighboury = b.TriggerRegionY; neighboury = b.TriggerRegionY;
neighbourx = b.TriggerRegionX; neighbourx = b.TriggerRegionX;
@ -620,7 +625,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.ControllingClient.SendAgentAlertMessage( agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return; return true;
} }
} }
@ -632,6 +637,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
else else
{ {
agent.InTransit();
neighboury = ba.TriggerRegionY; neighboury = ba.TriggerRegionY;
neighbourx = ba.TriggerRegionX; neighbourx = ba.TriggerRegionX;
@ -644,7 +651,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return; return true;
} }
} }
@ -664,6 +671,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
else else
{ {
agent.InTransit();
neighboury = ba.TriggerRegionY; neighboury = ba.TriggerRegionY;
neighbourx = ba.TriggerRegionX; neighbourx = ba.TriggerRegionX;
Vector3 newposition = pos; Vector3 newposition = pos;
@ -672,7 +681,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.ControllingClient.SendAgentAlertMessage( agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return; return true;
} }
} }
else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
@ -694,6 +703,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
else else
{ {
agent.InTransit();
neighboury = b.TriggerRegionY; neighboury = b.TriggerRegionY;
neighbourx = b.TriggerRegionX; neighbourx = b.TriggerRegionX;
Vector3 newposition = pos; Vector3 newposition = pos;
@ -702,7 +713,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.ControllingClient.SendAgentAlertMessage( agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return; return true;
} }
} }
else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
@ -738,9 +749,51 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
*/ */
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
d.BeginInvoke(agent, newpos, neighbourx, neighboury, isFlying, CrossAgentToNewRegionCompleted, d);
int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
ExpiringCache<ulong, DateTime> 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<ulong, DateTime>();
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) 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; InformClientToInitateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync;
d.BeginInvoke(agent, regionX, regionY, position, initiatingScene, d.BeginInvoke(agent, regionX, regionY, position, initiatingScene,
@ -795,21 +848,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
icon.EndInvoke(iar); 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);
/// <summary> /// <summary>
/// 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. /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary> /// </summary>
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); m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury);
Scene m_scene = agent.Scene; 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()) if (neighbourRegion != null && agent.ValidateAttachments())
{ {
@ -920,7 +971,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Enable Child Agent #region Enable Child Agent
/// <summary> /// <summary>
/// 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. /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary> /// </summary>
public void EnableChildAgent(ScenePresence sp, GridRegion region) 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); ScenePresence avatar, AgentCircuitData a, GridRegion reg, IPEndPoint endPoint, bool newAgent);
/// <summary> /// <summary>
/// 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. /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary> /// </summary>
public void EnableChildAgents(ScenePresence sp) public void EnableChildAgents(ScenePresence sp)
@ -1108,7 +1159,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
catch (ArgumentOutOfRangeException) catch (ArgumentOutOfRangeException)
{ {
m_log.ErrorFormat( 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.ExternalHostName,
neighbour.RegionHandle, neighbour.RegionHandle,
neighbour.RegionLocX, neighbour.RegionLocX,
@ -1188,7 +1239,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
} }
#endregion #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}", "and EstablishAgentCommunication with seed cap {4}",
m_scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); m_scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath);

View File

@ -42,7 +42,7 @@ namespace OpenSim.Region.Framework.Interfaces
void TeleportHome(UUID id, IClientAPI client); void TeleportHome(UUID id, IClientAPI client);
void Cross(ScenePresence agent, bool isFlying); bool Cross(ScenePresence agent, bool isFlying);
void AgentArrivedAtDestination(UUID agent); void AgentArrivedAtDestination(UUID agent);

View File

@ -3861,14 +3861,16 @@ namespace OpenSim.Region.Framework.Scenes
RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark)); 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) if (m_teleportModule != null)
m_teleportModule.Cross(agent, isFlying); return m_teleportModule.Cross(agent, isFlying);
else else
{ {
m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule"); 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) public void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence)

View File

@ -2725,29 +2725,57 @@ namespace OpenSim.Region.Framework.Scenes
// Makes sure avatar does not end up outside region // Makes sure avatar does not end up outside region
if (neighbor <= 0) if (neighbor <= 0)
{ {
if (!needsTransit) if (needsTransit)
{ {
if (m_requestedSitTargetUUID == UUID.Zero) if (m_requestedSitTargetUUID == UUID.Zero)
{ {
bool isFlying = m_physicsActor.Flying;
RemoveFromPhysicalScene();
Vector3 pos = AbsolutePosition; Vector3 pos = AbsolutePosition;
if (AbsolutePosition.X < 0) if (AbsolutePosition.X < 0)
pos.X += Velocity.X; pos.X += Velocity.X * 2;
else if (AbsolutePosition.X > Constants.RegionSize) else if (AbsolutePosition.X > Constants.RegionSize)
pos.X -= Velocity.X; pos.X -= Velocity.X * 2;
if (AbsolutePosition.Y < 0) if (AbsolutePosition.Y < 0)
pos.Y += Velocity.Y; pos.Y += Velocity.Y * 2;
else if (AbsolutePosition.Y > Constants.RegionSize) else if (AbsolutePosition.Y > Constants.RegionSize)
pos.Y -= Velocity.Y; pos.Y -= Velocity.Y * 2;
Velocity = Vector3.Zero;
AbsolutePosition = pos; AbsolutePosition = pos;
AddToPhysicalScene(isFlying);
} }
} }
} }
else if (neighbor > 0) 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 else
{ {
RemoveFromPhysicalScene();
// This constant has been inferred from experimentation // This constant has been inferred from experimentation
// I'm not sure what this value should be, so I tried a few values. // I'm not sure what this value should be, so I tried a few values.
timeStep = 0.04f; 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 /// If the neighbor accepts, remove the agent's viewable avatar from this scene
/// set them to a child agent. /// set them to a child agent.
/// </summary> /// </summary>
protected void CrossToNewRegion() protected bool CrossToNewRegion()
{ {
InTransit();
try try
{ {
m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); return m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying);
} }
catch catch
{ {
m_scene.CrossAgentToNewRegion(this, false); return m_scene.CrossAgentToNewRegion(this, false);
} }
} }