From 91b1d17e5bd3ff6ed006744bc529b53a67af1a64 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 18 May 2010 01:09:47 -0700 Subject: 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. --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 4 + .../Sirikata/ClientStack/SirikataClientView.cs | 4 + .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 4 + OpenSim/Framework/IClientAPI.cs | 1 + .../Region/ClientStack/LindenUDP/LLClientView.cs | 37 +++++++- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 4 + OpenSim/Region/Framework/Scenes/ScenePresence.cs | 102 +++++++++++---------- .../Server/IRCClientView.cs | 4 + .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 4 + OpenSim/Tests/Common/Mock/TestClient.cs | 4 + 10 files changed, 114 insertions(+), 54 deletions(-) diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 12989f5..39923cb 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -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(); diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index c4b5c87..7c8a979 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -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(); diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 39a16bc..5ad1643 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -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(); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index c597d62..ae2a80c 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -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); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 5670a78..df6a767 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -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 m_packetHandlers = new Dictionary(); protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers @@ -399,6 +400,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private Timer m_propertiesPacketTimer; private List m_propertiesBlocks = new List(); + private List 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; } @@ -11196,18 +11199,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP } /// + /// This processes packets which have accumulated while the presence was still in the process of initialising. + /// + public void ProcessPendingPackets() + { + m_IsPresenceReady = true; + foreach (Packet p in m_pendingPackets) + { + ProcessInPacket(p); + } + m_pendingPackets.Clear(); + } + + /// /// Entryway from the client to the simulator. All UDP packets from the client will end up here /// /// OpenMetaverse.packet 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(); + } + 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) diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 84385ad..c454d1f 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -825,6 +825,10 @@ namespace OpenSim.Region.Examples.SimpleModule { } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d76f029..0b644b9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -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; } - //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; + 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; diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 7c0fe4c..cab640b 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -878,6 +878,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 4323c94..b828357 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -839,6 +839,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 05a8ff0..815816a 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -882,6 +882,10 @@ namespace OpenSim.Tests.Common.Mock { } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { } -- cgit v1.1