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 Scene m_aScene;
protected List<UUID> m_agentsInTransit;
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
#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<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)
{
// 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);
/// <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.
/// </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);
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
/// <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.
/// </summary>
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);
/// <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.
/// </summary>
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);

View File

@ -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);

View File

@ -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)

View File

@ -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.
/// </summary>
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);
}
}