Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready.

avinationmerge
Tom Grimshaw 2010-05-18 01:09:47 -07:00
parent ae7c30a0f3
commit 91b1d17e5b
10 changed files with 114 additions and 54 deletions

View File

@ -819,6 +819,10 @@ namespace OpenSim.Client.MXP.ClientStack
//throw new System.NotImplementedException();
}
public void ProcessPendingPackets()
{
}
public void ProcessInPacket(Packet NewPack)
{
//throw new System.NotImplementedException();

View File

@ -439,6 +439,10 @@ namespace OpenSim.Client.Sirikata.ClientStack
throw new System.NotImplementedException();
}
public void ProcessPendingPackets()
{
}
public void ProcessInPacket(Packet NewPack)
{
throw new System.NotImplementedException();

View File

@ -445,6 +445,10 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
throw new System.NotImplementedException();
}
public void ProcessPendingPackets()
{
}
public void ProcessInPacket(Packet NewPack)
{
throw new System.NotImplementedException();

View File

@ -1112,6 +1112,7 @@ namespace OpenSim.Framework
void SetDebugPacketLevel(int newDebug);
void InPacket(object NewPack);
void ProcessPendingPackets();
void ProcessInPacket(Packet NewPack);
void Close();
void Close(bool sendStop);

View File

@ -376,6 +376,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private AgentUpdateArgs lastarg;
private bool m_IsActive = true;
private bool m_IsLoggingOut = false;
private bool m_IsPresenceReady = false;
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@ -399,6 +400,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private Timer m_propertiesPacketTimer;
private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
private List<Packet> m_pendingPackets;
#endregion Class Members
@ -439,6 +441,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
get { return m_IsActive; }
set { m_IsActive = value; }
}
public bool IsLoggingOut
{
get { return m_IsLoggingOut; }
@ -11195,19 +11198,43 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
/// <summary>
/// This processes packets which have accumulated while the presence was still in the process of initialising.
/// </summary>
public void ProcessPendingPackets()
{
m_IsPresenceReady = true;
foreach (Packet p in m_pendingPackets)
{
ProcessInPacket(p);
}
m_pendingPackets.Clear();
}
/// <summary>
/// Entryway from the client to the simulator. All UDP packets from the client will end up here
/// </summary>
/// <param name="Pack">OpenMetaverse.packet</param>
public void ProcessInPacket(Packet Pack)
{
if (m_debugPacketLevel >= 255)
m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type);
if (!m_IsPresenceReady)
{
if (m_pendingPackets == null)
{
m_pendingPackets = new List<Packet>();
}
m_pendingPackets.Add(Pack);
}
else
{
if (m_debugPacketLevel >= 255)
m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type);
if (!ProcessPacketMethod(Pack))
m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type);
if (!ProcessPacketMethod(Pack))
m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type);
PacketPool.Instance.ReturnPacket(Pack);
PacketPool.Instance.ReturnPacket(Pack);
}
}
private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)

View File

@ -825,6 +825,10 @@ namespace OpenSim.Region.Examples.SimpleModule
{
}
public void ProcessPendingPackets()
{
}
public void ProcessInPacket(Packet NewPack)
{
}

View File

@ -129,7 +129,7 @@ namespace OpenSim.Region.Framework.Scenes
private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
private Vector3 m_lastPosition;
private Vector3 m_lastPosition;
private Vector3 m_lastWorldPosition;
private Quaternion m_lastRotation;
private Vector3 m_lastVelocity;
@ -715,8 +715,11 @@ namespace OpenSim.Region.Framework.Scenes
// Request info about all the (root) agents in this region
// Note: This won't send data *to* other clients in that region (children don't send)
SendInitialFullUpdateToAllClients();
RegisterToEvents();
if (m_controllingClient != null)
{
m_controllingClient.ProcessPendingPackets();
}
SetDirectionVectors();
}
@ -858,7 +861,6 @@ namespace OpenSim.Region.Framework.Scenes
m_grouptitle = gm.GetGroupTitle(m_uuid);
m_rootRegionHandle = m_scene.RegionInfo.RegionHandle;
m_scene.SetRootAgentScene(m_uuid);
// Moved this from SendInitialData to ensure that m_appearance is initialized
@ -875,22 +877,22 @@ namespace OpenSim.Region.Framework.Scenes
{
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
pos.Y = crossedBorder.BorderLine.Z - 1;
}
//If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
//This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
//they'll bypass the landing point. But I can't think of any decent way of fixing this.
if (KnownChildRegionHandles.Count == 0)
{
ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
if (land != null)
{
//Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
{
pos = land.LandData.UserLocation;
}
}
}
//If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
//This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
//they'll bypass the landing point. But I can't think of any decent way of fixing this.
if (KnownChildRegionHandles.Count == 0)
{
ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
if (land != null)
{
//Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
{
pos = land.LandData.UserLocation;
}
}
}
if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
@ -1027,8 +1029,8 @@ namespace OpenSim.Region.Framework.Scenes
bool isFlying = false;
if (m_physicsActor != null)
isFlying = m_physicsActor.Flying;
isFlying = m_physicsActor.Flying;
RemoveFromPhysicalScene();
Velocity = Vector3.Zero;
AbsolutePosition = pos;
@ -1039,7 +1041,7 @@ namespace OpenSim.Region.Framework.Scenes
SetHeight(m_appearance.AvatarHeight);
}
SendTerseUpdateToAllClients();
SendTerseUpdateToAllClients();
}
@ -1173,7 +1175,6 @@ namespace OpenSim.Region.Framework.Scenes
pos.Z = ground + 1.5f;
AbsolutePosition = pos;
}
m_isChildAgent = false;
bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
MakeRootAgent(AbsolutePosition, m_flying);
@ -1745,14 +1746,14 @@ namespace OpenSim.Region.Framework.Scenes
// else
// { // single or child prim
// }
if (part == null) //CW: Part may be gone. llDie() for example.
{
partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
}
else
{
partRot = part.GetWorldRotation();
// }
if (part == null) //CW: Part may be gone. llDie() for example.
{
partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
}
else
{
partRot = part.GetWorldRotation();
}
Quaternion partIRot = Quaternion.Inverse(partRot);
@ -1760,22 +1761,22 @@ namespace OpenSim.Region.Framework.Scenes
Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
if (m_physicsActor == null)
{
AddToPhysicalScene(false);
if (m_physicsActor == null)
{
AddToPhysicalScene(false);
}
//CW: If the part isn't null then we can set the current position
if (part != null)
{
Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
part.IsOccupied = false;
}
else
{
//CW: Since the part doesn't exist, a coarse standup position isn't an issue
AbsolutePosition = m_lastWorldPosition;
//CW: If the part isn't null then we can set the current position
if (part != null)
{
Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
part.IsOccupied = false;
}
else
{
//CW: Since the part doesn't exist, a coarse standup position isn't an issue
AbsolutePosition = m_lastWorldPosition;
}
m_parentPosition = Vector3.Zero;
@ -1930,7 +1931,7 @@ namespace OpenSim.Region.Framework.Scenes
// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
{
autopilot = false; // close enough
autopilot = false; // close enough
m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
Not using the part's position because returning the AV to the last known standing
position is likely to be more friendly, isn't it? */
@ -1939,7 +1940,7 @@ namespace OpenSim.Region.Framework.Scenes
} // else the autopilot will get us close
}
else
{ // its a scripted sit
{ // its a scripted sit
m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
I *am* using the part's position this time because we have no real idea how far away
the avatar is from the sit target. */
@ -3744,7 +3745,10 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos);
m_scene = scene;
RegisterToEvents();
if (m_controllingClient != null)
{
m_controllingClient.ProcessPendingPackets();
}
/*
AbsolutePosition = client.StartPos;

View File

@ -878,6 +878,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
}
public void ProcessPendingPackets()
{
}
public void ProcessInPacket(Packet NewPack)
{

View File

@ -839,6 +839,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
}
public void ProcessPendingPackets()
{
}
public void ProcessInPacket(Packet NewPack)
{
}

View File

@ -882,6 +882,10 @@ namespace OpenSim.Tests.Common.Mock
{
}
public void ProcessPendingPackets()
{
}
public void ProcessInPacket(Packet NewPack)
{
}