Browse Source

* Applying dalien's patches from bug#177 and #179

Adam Frisby 17 năm trước cách đây
mục cha
commit
561b87b303

+ 5 - 0
OpenSim/Framework/General/ClientManager.cs

@@ -23,6 +23,11 @@ namespace OpenSim.Framework
             m_clients = new Dictionary<uint, IClientAPI>();
         }
 
+	public void Remove(uint id)
+	{
+            m_clients.Remove(id);
+	}
+
         public void Add(uint id, IClientAPI client )
         {
             m_clients.Add( id, client );

+ 2 - 0
OpenSim/Framework/General/Interfaces/IClientAPI.cs

@@ -147,6 +147,8 @@ namespace OpenSim.Framework.Interfaces
 
         void OutPacket(Packet newPack);
         void SendWearables(AvatarWearable[] wearables);
+        void SendStartPingCheck(byte seq);
+        void SendKillObject(ulong regionHandle, uint avatarLocalID);
         void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId);
         void SendRegionHandshake(RegionInfo regionInfo);
         void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID);

+ 17 - 0
OpenSim/Region/ClientStack/ClientView.API.cs

@@ -476,6 +476,23 @@ namespace OpenSim.Region.ClientStack
             OutPacket(money);
         }
 
+        public void SendStartPingCheck(byte seq)
+        {
+            StartPingCheckPacket pc = new StartPingCheckPacket();
+            pc.PingID.PingID = seq;
+            OutPacket(pc);
+        }
+
+        public void SendKillObject(ulong regionHandle, uint avatarLocalID)
+        {
+            KillObjectPacket kill = new KillObjectPacket();
+            kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
+            kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
+            kill.ObjectData[0].ID = avatarLocalID;
+            OutPacket(kill);
+        }
+
+
         #region Appearance/ Wearables Methods
 
         /// <summary>

+ 2 - 23
OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs

@@ -51,29 +51,8 @@ namespace OpenSim.Region.ClientStack
             logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock();
             logReply.InventoryData[0].ItemID = LLUUID.Zero;
             OutPacket(logReply);
-            //tell all clients to kill our object
-            KillObjectPacket kill = new KillObjectPacket();
-            kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
-            kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
-            // kill.ObjectData[0].ID = this.ClientAvatar.localid;
-            foreach (ClientView client in m_clientThreads.Values)
-            {
-                client.OutPacket(kill);
-            }
-
-            this.m_inventoryCache.ClientLeaving(this.AgentID, null);
-
-
-           // m_gridServer.LogoutSession(this.SessionID, this.AgentID, this.CircuitCode);
-            /*lock (m_world.Entities)
-            {
-                m_world.Entities.Remove(this.AgentID);
-            }*/
-            // m_world.RemoveViewerAgent(this);
-            //need to do other cleaning up here too
-            m_clientThreads.Remove(this.CircuitCode);
-            m_networkServer.RemoveClientCircuit(this.CircuitCode);
-            this.ClientThread.Abort();
+	    //
+	    this.KillClient();
             return true;
         }
 

+ 1 - 1
OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs

@@ -45,7 +45,7 @@ namespace OpenSim.Region.ClientStack
             {
                 if (Pack.Type != PacketType.AgentUpdate)
                 {
-                    Console.WriteLine("IN: " + Pack.Type.ToString());
+                    Console.WriteLine(CircuitCode + ":IN: " + Pack.Type.ToString());
                 }
             }
 

+ 31 - 9
OpenSim/Region/ClientStack/ClientView.cs

@@ -25,6 +25,7 @@
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */
+using System;
 using System.Collections.Generic;
 using System.Net;
 using System.Text;
@@ -77,6 +78,11 @@ namespace OpenSim.Region.ClientStack
         private int cachedtextureserial = 0;
         protected AuthenticateSessionsBase m_authenticateSessionsHandler;
         private Encoding enc = Encoding.ASCII;
+        // Dead client detection vars
+        private Timer clientPingTimer;
+        private int packetsReceived = 0;
+        private int probesWithNoIngressPackets = 0;
+        private int lastPacketsReceived = 0;
 
         public ClientView(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, Dictionary<uint, ClientView> clientThreads, IWorld world, AssetCache assetCache, PacketServer packServer, InventoryCache inventoryCache, AuthenticateSessionsBase authenSessions )
         {
@@ -112,15 +118,7 @@ namespace OpenSim.Region.ClientStack
 
         public void KillClient()
         {
-            KillObjectPacket kill = new KillObjectPacket();
-            kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
-            kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
-            //kill.ObjectData[0].ID = this.ClientAvatar.localid;
-            foreach (ClientView client in m_clientThreads.Values)
-            {
-                client.OutPacket(kill);
-            }
-
+            clientPingTimer.Stop();
             this.m_inventoryCache.ClientLeaving(this.AgentID, null);
             m_world.RemoveClient(this.AgentId);
 
@@ -193,6 +191,9 @@ namespace OpenSim.Region.ClientStack
                 if (nextPacket.Incoming)
                 {
                     //is a incoming packet
+                    if (nextPacket.Packet.Type != PacketType.AgentUpdate) {
+                        packetsReceived++;
+                    }
                     ProcessInPacket(nextPacket.Packet);
                 }
                 else
@@ -204,10 +205,31 @@ namespace OpenSim.Region.ClientStack
         }
         # endregion
 
+        protected void CheckClientConnectivity(object sender, ElapsedEventArgs e)
+        {
+            if (packetsReceived == lastPacketsReceived) {
+                probesWithNoIngressPackets++;
+                if (probesWithNoIngressPackets > 30) {
+                    this.KillClient();
+                 } else {
+                    // this will normally trigger at least one packet (ping response)
+                    SendStartPingCheck(0);
+                 }
+            } else {
+                // Something received in the meantime - we can reset the counters
+                probesWithNoIngressPackets = 0;
+                lastPacketsReceived = packetsReceived;
+            }
+        }
+
         # region Setup
 
         protected virtual void InitNewClient()
         {
+            clientPingTimer = new Timer(1000);
+            clientPingTimer.Elapsed += new ElapsedEventHandler(CheckClientConnectivity);
+            clientPingTimer.Enabled = true;
+
             MainLog.Instance.Verbose( "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
             this.m_world.AddNewClient(this, false);
         }

+ 1 - 2
OpenSim/Region/ClientStack/ClientViewBase.cs

@@ -71,8 +71,7 @@ namespace OpenSim.Region.ClientStack
             // Keep track of when this packet was sent out
             Pack.TickCount = Environment.TickCount;
 
-          
-          //  Console.WriteLine("OUT: " + Pack.Type.ToString());
+            Console.WriteLine(CircuitCode + ":OUT: " + Pack.Type.ToString());
 
             if (!Pack.Header.Resent)
             {

+ 1 - 0
OpenSim/Region/ClientStack/PacketServer.cs

@@ -178,6 +178,7 @@ namespace OpenSim.Region.ClientStack
         public virtual void RemoveClientCircuit(uint circuitcode)
         {
             this._networkHandler.RemoveClientCircuit(circuitcode);
+            this.m_clientManager.Remove(circuitcode);
         }
     }
 }

+ 22 - 0
OpenSim/Region/Environment/Scenes/Scene.cs

@@ -546,6 +546,28 @@ namespace OpenSim.Region.Environment.Scenes
         {
             eventManager.TriggerOnRemovePresence(agentID);
 
+	    ScenePresence avatar = this.RequestAvatar(agentID);
+
+            m_clientManager.ForEachClient(
+	        delegate(IClientAPI client)
+                {
+                    client.SendKillObject(avatar.RegionHandle, avatar.LocalId);
+                });
+ 
+            lock (Avatars) {
+                 if (Avatars.ContainsKey(agentID)) {
+                    Avatars.Remove(agentID);
+                }
+            }
+             lock (Entities) {
+                 if (Entities.ContainsKey(agentID)) {
+                    Entities.Remove(agentID);
+                }
+            }
+            // TODO: Add the removal from physics ?
+ 
+
+
             return;
         }
         #endregion

+ 24 - 7
OpenSim/Region/Environment/Scenes/ScenePresence.cs

@@ -91,6 +91,12 @@ namespace OpenSim.Region.Environment.Scenes
                 return _physActor;
             }
         }
+
+	public ulong RegionHandle
+	{
+	    get { return m_regionHandle; }
+	}
+
         #endregion
 
         #region Constructor(s)
@@ -390,6 +396,16 @@ namespace OpenSim.Region.Environment.Scenes
             remoteAvatar.ControllingClient.SendAvatarData(m_regionInfo.RegionHandle, this.firstname, this.lastname, this.uuid, this.LocalId, this.Pos, DefaultTexture);
         }
 
+        public void SendFullUpdateToALLClients()
+        {
+            List<ScenePresence> avatars = this.m_world.RequestAvatarList();
+            foreach (ScenePresence avatar in this.m_world.RequestAvatarList())
+            {
+                this.SendFullUpdateToOtherClient(avatar);
+                avatar.SendFullUpdateToOtherClient(this);
+            }
+        }
+
         /// <summary>
         /// 
         /// </summary>
@@ -410,6 +426,7 @@ namespace OpenSim.Region.Environment.Scenes
         public void SendOurAppearance(IClientAPI OurClient)
         {
             this.ControllingClient.SendWearables(this.Wearables);
+            this.SendFullUpdateToALLClients();
             this.m_world.SendAllSceneObjectsToClient(this.ControllingClient);
         }
 
@@ -429,13 +446,13 @@ namespace OpenSim.Region.Environment.Scenes
         /// <param name="seq"></param>
         public void SendAnimPack(LLUUID animID, int seq)
         {
-            this.current_anim = animID;
-            this.anim_seq = anim_seq;
-            List<ScenePresence> avatars = this.m_world.RequestAvatarList();
-            for (int i = 0; i < avatars.Count; i++)
-            {
-                avatars[i].ControllingClient.SendAnimation(animID, seq, this.ControllingClient.AgentId);
-            }
+	    this.current_anim = animID;
+	    this.anim_seq = seq;
+	    List<ScenePresence> avatars = this.m_world.RequestAvatarList();
+	    for (int i = 0; i < avatars.Count; i++)
+	    {
+	    	avatars[i].ControllingClient.SendAnimation(animID, seq, this.ControllingClient.AgentId);
+	    }
         }
 
         /// <summary>

BIN
bin/avatar-texture.dat