From ffb4f97a664e8b80e209ccf0f89ad56a20a401fd Mon Sep 17 00:00:00 2001 From: lbsa71 Date: Tue, 18 Sep 2007 08:55:44 +0000 Subject: * Merged ClientViewBase into ClientView for great justice --- .../Region/ClientStack/ClientView.PacketQueue.cs | 314 ++++++++++++++++++++ .../ClientStack/ClientView.ProcessPackets.cs | 2 +- OpenSim/Region/ClientStack/ClientView.cs | 6 +- OpenSim/Region/ClientStack/ClientViewBase.cs | 320 --------------------- OpenSim/Region/Environment/Scenes/SceneManager.cs | 1 - 5 files changed, 318 insertions(+), 325 deletions(-) create mode 100644 OpenSim/Region/ClientStack/ClientView.PacketQueue.cs delete mode 100644 OpenSim/Region/ClientStack/ClientViewBase.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs b/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs new file mode 100644 index 0000000..05c2869 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs @@ -0,0 +1,314 @@ +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Timers; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Console; +using OpenSim.Framework.Utilities; +using OpenSim.Region.Environment; + +namespace OpenSim.Region.ClientStack +{ + public partial class ClientView + { + protected BlockingQueue PacketQueue; + protected Dictionary PendingAcks = new Dictionary(); + protected Dictionary NeedAck = new Dictionary(); + + protected Timer AckTimer; + protected uint Sequence = 0; + protected object SequenceLock = new object(); + protected const int MAX_APPENDED_ACKS = 10; + protected const int RESEND_TIMEOUT = 4000; + protected const int MAX_SEQUENCE = 0xFFFFFF; + + public uint CircuitCode; + public EndPoint userEP; + + protected PacketServer m_networkServer; + + protected virtual void ProcessOutPacket(Packet Pack) + { + // Keep track of when this packet was sent out + Pack.TickCount = System.Environment.TickCount; + + if (!Pack.Header.Resent) + { + // Set the sequence number + lock (SequenceLock) + { + if (Sequence >= MAX_SEQUENCE) + { + Sequence = 1; + } + else + { + Sequence++; + } + + Pack.Header.Sequence = Sequence; + } + + if (Pack.Header.Reliable) //DIRTY HACK + { + lock (NeedAck) + { + if (!NeedAck.ContainsKey(Pack.Header.Sequence)) + { + try + { + NeedAck.Add(Pack.Header.Sequence, Pack); + } + catch (Exception e) // HACKY + { + e.ToString(); + // Ignore + // Seems to throw a exception here occasionally + // of 'duplicate key' despite being locked. + // !?!?!? + } + } + else + { + // Client.Log("Attempted to add a duplicate sequence number (" + + // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + + // packet.Type.ToString(), Helpers.LogLevel.Warning); + } + } + + // Don't append ACKs to resent packets, in case that's what was causing the + // delivery to fail + if (!Pack.Header.Resent) + { + // Append any ACKs that need to be sent out to this packet + lock (PendingAcks) + { + if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && + Pack.Type != PacketType.PacketAck && + Pack.Type != PacketType.LogoutRequest) + { + Pack.Header.AckList = new uint[PendingAcks.Count]; + int i = 0; + + foreach (uint ack in PendingAcks.Values) + { + Pack.Header.AckList[i] = ack; + i++; + } + + PendingAcks.Clear(); + Pack.Header.AppendedAcks = true; + } + } + } + } + } + + byte[] ZeroOutBuffer = new byte[4096]; + byte[] sendbuffer; + sendbuffer = Pack.ToBytes(); + + try + { + if (Pack.Header.Zerocoded) + { + int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); + m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP); + } + else + { + m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP); + } + } + catch (Exception) + { + MainLog.Instance.Warn("client", "OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread"); + this.KillThread(); + } + + } + + public virtual void InPacket(Packet NewPack) + { + // Handle appended ACKs + if (NewPack.Header.AppendedAcks) + { + lock (NeedAck) + { + foreach (uint ack in NewPack.Header.AckList) + { + NeedAck.Remove(ack); + } + } + } + + // Handle PacketAck packets + if (NewPack.Type == PacketType.PacketAck) + { + PacketAckPacket ackPacket = (PacketAckPacket)NewPack; + + lock (NeedAck) + { + foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) + { + NeedAck.Remove(block.ID); + } + } + } + else if ((NewPack.Type == PacketType.StartPingCheck)) + { + //reply to pingcheck + StartPingCheckPacket startPing = (StartPingCheckPacket)NewPack; + CompletePingCheckPacket endPing = new CompletePingCheckPacket(); + endPing.PingID.PingID = startPing.PingID.PingID; + OutPacket(endPing); + } + else + { + QueItem item = new QueItem(); + item.Packet = NewPack; + item.Incoming = true; + this.PacketQueue.Enqueue(item); + } + + } + + public virtual void OutPacket(Packet NewPack) + { + QueItem item = new QueItem(); + item.Packet = NewPack; + item.Incoming = false; + this.PacketQueue.Enqueue(item); + } + + # region Low Level Packet Methods + + protected void ack_pack(Packet Pack) + { + if (Pack.Header.Reliable) + { + PacketAckPacket ack_it = new PacketAckPacket(); + ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; + ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); + ack_it.Packets[0].ID = Pack.Header.Sequence; + ack_it.Header.Reliable = false; + + OutPacket(ack_it); + + } + /* + if (Pack.Header.Reliable) + { + lock (PendingAcks) + { + uint sequence = (uint)Pack.Header.Sequence; + if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; } + } + }*/ + } + + protected void ResendUnacked() + { + int now = System.Environment.TickCount; + + lock (NeedAck) + { + foreach (Packet packet in NeedAck.Values) + { + if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent)) + { + MainLog.Instance.Verbose( "Resending " + packet.Type.ToString() + " packet, " + + (now - packet.TickCount) + "ms have passed"); + + packet.Header.Resent = true; + OutPacket(packet); + } + } + } + } + + protected void SendAcks() + { + lock (PendingAcks) + { + if (PendingAcks.Count > 0) + { + if (PendingAcks.Count > 250) + { + // FIXME: Handle the odd case where we have too many pending ACKs queued up + MainLog.Instance.Verbose( "Too many ACKs queued up!"); + return; + } + + //OpenSim.Framework.Console.MainLog.Instance.WriteLine("Sending PacketAck"); + + + int i = 0; + PacketAckPacket acks = new PacketAckPacket(); + acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count]; + + foreach (uint ack in PendingAcks.Values) + { + acks.Packets[i] = new PacketAckPacket.PacketsBlock(); + acks.Packets[i].ID = ack; + i++; + } + + acks.Header.Reliable = false; + OutPacket(acks); + + PendingAcks.Clear(); + } + } + } + + protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) + { + SendAcks(); + ResendUnacked(); + } + #endregion + + #region Nested Classes + + public class QueItem + { + public QueItem() + { + } + + public Packet Packet; + public bool Incoming; + } + #endregion + } +} diff --git a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs index fe3e82c..80e499b 100644 --- a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs +++ b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack } } - protected override void ProcessInPacket(Packet Pack) + protected void ProcessInPacket(Packet Pack) { ack_pack(Pack); diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 54c9a0d..1d92cca 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.ClientStack /// Handles new client connections /// Constructor takes a single Packet and authenticates everything /// - public partial class ClientView : ClientViewBase, IClientAPI + public partial class ClientView : IClientAPI { public static TerrainManager TerrainManager; @@ -134,7 +134,7 @@ namespace OpenSim.Region.ClientStack this.ClientThread.Abort(); } - public override void ConnectionClosed() + public void ConnectionClosed() { clientPingTimer.Stop(); m_clientThreads.Remove(this.CircuitCode); @@ -315,7 +315,7 @@ namespace OpenSim.Region.ClientStack # endregion - protected override void KillThread() + protected void KillThread() { this.ClientThread.Abort(); } diff --git a/OpenSim/Region/ClientStack/ClientViewBase.cs b/OpenSim/Region/ClientStack/ClientViewBase.cs deleted file mode 100644 index 965dc40..0000000 --- a/OpenSim/Region/ClientStack/ClientViewBase.cs +++ /dev/null @@ -1,320 +0,0 @@ -/* -* Copyright (c) Contributors, http://opensimulator.org/ -* See CONTRIBUTORS.TXT for a full list of copyright holders. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the OpenSim Project nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Timers; -using libsecondlife; -using libsecondlife.Packets; -using OpenSim.Framework.Console; -using OpenSim.Framework.Utilities; -using OpenSim.Region.Environment; - -namespace OpenSim.Region.ClientStack -{ - public abstract class ClientViewBase - { - protected BlockingQueue PacketQueue; - protected Dictionary PendingAcks = new Dictionary(); - protected Dictionary NeedAck = new Dictionary(); - - protected Timer AckTimer; - protected uint Sequence = 0; - protected object SequenceLock = new object(); - protected const int MAX_APPENDED_ACKS = 10; - protected const int RESEND_TIMEOUT = 4000; - protected const int MAX_SEQUENCE = 0xFFFFFF; - - public uint CircuitCode; - public EndPoint userEP; - - protected PacketServer m_networkServer; - - protected abstract void ProcessInPacket(Packet Pack); - - protected virtual void ProcessOutPacket(Packet Pack) - { - // Keep track of when this packet was sent out - Pack.TickCount = System.Environment.TickCount; - - if (!Pack.Header.Resent) - { - // Set the sequence number - lock (SequenceLock) - { - if (Sequence >= MAX_SEQUENCE) - { - Sequence = 1; - } - else - { - Sequence++; - } - - Pack.Header.Sequence = Sequence; - } - - if (Pack.Header.Reliable) //DIRTY HACK - { - lock (NeedAck) - { - if (!NeedAck.ContainsKey(Pack.Header.Sequence)) - { - try - { - NeedAck.Add(Pack.Header.Sequence, Pack); - } - catch (Exception e) // HACKY - { - e.ToString(); - // Ignore - // Seems to throw a exception here occasionally - // of 'duplicate key' despite being locked. - // !?!?!? - } - } - else - { - // Client.Log("Attempted to add a duplicate sequence number (" + - // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + - // packet.Type.ToString(), Helpers.LogLevel.Warning); - } - } - - // Don't append ACKs to resent packets, in case that's what was causing the - // delivery to fail - if (!Pack.Header.Resent) - { - // Append any ACKs that need to be sent out to this packet - lock (PendingAcks) - { - if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && - Pack.Type != PacketType.PacketAck && - Pack.Type != PacketType.LogoutRequest) - { - Pack.Header.AckList = new uint[PendingAcks.Count]; - int i = 0; - - foreach (uint ack in PendingAcks.Values) - { - Pack.Header.AckList[i] = ack; - i++; - } - - PendingAcks.Clear(); - Pack.Header.AppendedAcks = true; - } - } - } - } - } - - byte[] ZeroOutBuffer = new byte[4096]; - byte[] sendbuffer; - sendbuffer = Pack.ToBytes(); - - try - { - if (Pack.Header.Zerocoded) - { - int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); - m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP); - } - else - { - m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP); - } - } - catch (Exception) - { - MainLog.Instance.Warn("client", "OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread"); - this.KillThread(); - } - - } - - public virtual void InPacket(Packet NewPack) - { - // Handle appended ACKs - if (NewPack.Header.AppendedAcks) - { - lock (NeedAck) - { - foreach (uint ack in NewPack.Header.AckList) - { - NeedAck.Remove(ack); - } - } - } - - // Handle PacketAck packets - if (NewPack.Type == PacketType.PacketAck) - { - PacketAckPacket ackPacket = (PacketAckPacket)NewPack; - - lock (NeedAck) - { - foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) - { - NeedAck.Remove(block.ID); - } - } - } - else if ((NewPack.Type == PacketType.StartPingCheck)) - { - //reply to pingcheck - StartPingCheckPacket startPing = (StartPingCheckPacket)NewPack; - CompletePingCheckPacket endPing = new CompletePingCheckPacket(); - endPing.PingID.PingID = startPing.PingID.PingID; - OutPacket(endPing); - } - else - { - QueItem item = new QueItem(); - item.Packet = NewPack; - item.Incoming = true; - this.PacketQueue.Enqueue(item); - } - - } - - public virtual void OutPacket(Packet NewPack) - { - QueItem item = new QueItem(); - item.Packet = NewPack; - item.Incoming = false; - this.PacketQueue.Enqueue(item); - } - - # region Low Level Packet Methods - - protected void ack_pack(Packet Pack) - { - if (Pack.Header.Reliable) - { - PacketAckPacket ack_it = new PacketAckPacket(); - ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; - ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); - ack_it.Packets[0].ID = Pack.Header.Sequence; - ack_it.Header.Reliable = false; - - OutPacket(ack_it); - - } - /* - if (Pack.Header.Reliable) - { - lock (PendingAcks) - { - uint sequence = (uint)Pack.Header.Sequence; - if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; } - } - }*/ - } - - protected void ResendUnacked() - { - int now = System.Environment.TickCount; - - lock (NeedAck) - { - foreach (Packet packet in NeedAck.Values) - { - if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent)) - { - MainLog.Instance.Verbose( "Resending " + packet.Type.ToString() + " packet, " + - (now - packet.TickCount) + "ms have passed"); - - packet.Header.Resent = true; - OutPacket(packet); - } - } - } - } - - protected void SendAcks() - { - lock (PendingAcks) - { - if (PendingAcks.Count > 0) - { - if (PendingAcks.Count > 250) - { - // FIXME: Handle the odd case where we have too many pending ACKs queued up - MainLog.Instance.Verbose( "Too many ACKs queued up!"); - return; - } - - //OpenSim.Framework.Console.MainLog.Instance.WriteLine("Sending PacketAck"); - - - int i = 0; - PacketAckPacket acks = new PacketAckPacket(); - acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count]; - - foreach (uint ack in PendingAcks.Values) - { - acks.Packets[i] = new PacketAckPacket.PacketsBlock(); - acks.Packets[i].ID = ack; - i++; - } - - acks.Header.Reliable = false; - OutPacket(acks); - - PendingAcks.Clear(); - } - } - } - - protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) - { - SendAcks(); - ResendUnacked(); - } - #endregion - - protected abstract void KillThread(); - - public abstract void ConnectionClosed(); - - #region Nested Classes - - public class QueItem - { - public QueItem() - { - } - - public Packet Packet; - public bool Incoming; - } - #endregion - } -} diff --git a/OpenSim/Region/Environment/Scenes/SceneManager.cs b/OpenSim/Region/Environment/Scenes/SceneManager.cs index 4a99a80..5655e72 100644 --- a/OpenSim/Region/Environment/Scenes/SceneManager.cs +++ b/OpenSim/Region/Environment/Scenes/SceneManager.cs @@ -135,7 +135,6 @@ namespace OpenSim.Region.Environment.Scenes else { Console.WriteLine("Searching for Region: '" + regionName + "'"); - Scene foundScene = null; foreach (Scene scene in m_localScenes) { -- cgit v1.1