diff --git a/libsecondlife/Login.cs b/libsecondlife/Login.cs index 78b0fefb..bd1f196f 100644 --- a/libsecondlife/Login.cs +++ b/libsecondlife/Login.cs @@ -455,7 +455,9 @@ namespace libsecondlife CurrentContext.Params.Password = Helpers.MD5(CurrentContext.Params.Password); // Set the sim disconnect timer interval - DisconnectTimer.Change(Client.Settings.SIMULATOR_TIMEOUT, Client.Settings.SIMULATOR_TIMEOUT); + if (DisconnectTimer != null) DisconnectTimer.Dispose(); + DisconnectTimer = new Timer(new TimerCallback(DisconnectTimer_Elapsed), null, + Client.Settings.SIMULATOR_TIMEOUT, Client.Settings.SIMULATOR_TIMEOUT); // Override SSL authentication mechanisms. DO NOT convert this to the // .NET 2.0 preferred method, the equivalent function in Mono has a diff --git a/libsecondlife/NetworkManager.cs b/libsecondlife/NetworkManager.cs index 759a1ed6..4d399a76 100644 --- a/libsecondlife/NetworkManager.cs +++ b/libsecondlife/NetworkManager.cs @@ -229,9 +229,6 @@ namespace libsecondlife RegisterCallback(PacketType.LogoutReply, new PacketCallback(LogoutReplyHandler)); RegisterCallback(PacketType.CompletePingCheck, new PacketCallback(PongHandler)); RegisterCallback(PacketType.SimStats, new PacketCallback(SimStatsHandler)); - - // The proper timeout for this will get set again at Login - DisconnectTimer = new Timer(new TimerCallback(DisconnectTimer_Elapsed), null, Timeout.Infinite, Timeout.Infinite); // GLOBAL SETTING: Don't force Expect-100: Continue headers on HTTP POST calls ServicePointManager.Expect100Continue = false; @@ -391,7 +388,9 @@ namespace libsecondlife if (simulator.Connect(setDefault)) { // Start a timer that checks if we've been disconnected - DisconnectTimer.Change(Client.Settings.SIMULATOR_TIMEOUT, Client.Settings.SIMULATOR_TIMEOUT); + if (DisconnectTimer != null) DisconnectTimer.Dispose(); + DisconnectTimer = new Timer(new TimerCallback(DisconnectTimer_Elapsed), null, + Client.Settings.SIMULATOR_TIMEOUT, Client.Settings.SIMULATOR_TIMEOUT); if (setDefault) SetCurrentSim(simulator, seedcaps); @@ -468,7 +467,7 @@ namespace libsecondlife public void RequestLogout() { // No need to run the disconnect timer any more - DisconnectTimer.Change(Timeout.Infinite, Timeout.Infinite); + if (DisconnectTimer != null) DisconnectTimer.Dispose(); // This will catch a Logout when the client is not logged in if (CurrentSim == null || !connected) @@ -632,13 +631,22 @@ namespace libsecondlife // Check the archives to see whether we already received this packet lock (simulator.PacketArchive) { - if (simulator.PacketArchive.Contains(packet.Header.Sequence)) + if (packet.Header.Sequence == 0) + { + Client.Log( + String.Format("Received a packet with a sequence number of 0, type: {0}", + packet.Type), Helpers.LogLevel.Warning); + + // Not sure what to do with this, skip it + continue; + } + else if (simulator.PacketArchive.Contains(packet.Header.Sequence)) { if (packet.Header.Resent) { Client.DebugLog("Received resent packet #" + packet.Header.Sequence); } - else if(packet.Header.Sequence != 0) + else { Client.Log(String.Format("Received a duplicate of packet #{0}, current type: {1}", packet.Header.Sequence, packet.Type), Helpers.LogLevel.Warning); @@ -730,31 +738,30 @@ namespace libsecondlife private void DisconnectTimer_Elapsed(object obj) { - if (connected) + if (!connected || CurrentSim == null) { - if (CurrentSim == null) - { - DisconnectTimer.Change(Timeout.Infinite, Timeout.Infinite); - connected = false; - return; - } + if (DisconnectTimer != null) DisconnectTimer.Dispose(); + connected = false; + } + else if (CurrentSim.DisconnectCandidate) + { + // The currently occupied simulator hasn't sent us any traffic in a while, shutdown + Client.Log("Network timeout for the current simulator (" + + CurrentSim.ToString() + "), logging out", Helpers.LogLevel.Warning); - // If the current simulator is disconnected, shutdown+callback+return - if (CurrentSim.DisconnectCandidate) - { - Client.Log("Network timeout for the current simulator (" + - CurrentSim.ToString() + "), logging out", Helpers.LogLevel.Warning); + if (DisconnectTimer != null) DisconnectTimer.Dispose(); + connected = false; - DisconnectTimer.Change(Timeout.Infinite, Timeout.Infinite); - connected = false; - - // Shutdown the network layer - Shutdown(DisconnectType.NetworkTimeout); - - // We're completely logged out and shut down, leave this function - return; - } + // Shutdown the network layer + Shutdown(DisconnectType.NetworkTimeout); + } + else + { + #region Check for timed out simulators + // Figure out which sims need to be disconnected, then fire + // all of the events to avoid calling DisconnectSim() inside + // the Simulators lock List disconnectedSims = null; // Check all of the connected sims for disconnects @@ -764,6 +771,8 @@ namespace libsecondlife { if (Simulators[i].DisconnectCandidate) { + // Avoid initializing a new List<> every time the timer + // fires with this piece of code if (disconnectedSims == null) disconnectedSims = new List(); @@ -792,6 +801,8 @@ namespace libsecondlife } } } + + #endregion Check for timed out simulators } } diff --git a/libsecondlife/ObjectPoolBase.cs b/libsecondlife/ObjectPoolBase.cs index 2f4573eb..1609f9e1 100644 --- a/libsecondlife/ObjectPoolBase.cs +++ b/libsecondlife/ObjectPoolBase.cs @@ -75,7 +75,7 @@ namespace libsecondlife } /// - /// Checkes the instance back into the object pool + /// Checks the instance back into the object pool /// public void Dispose() { diff --git a/libsecondlife/Simulator.cs b/libsecondlife/Simulator.cs index a7bffa38..6a9f20af 100644 --- a/libsecondlife/Simulator.cs +++ b/libsecondlife/Simulator.cs @@ -397,13 +397,6 @@ namespace libsecondlife PacketArchive = new Queue(Settings.PACKET_ARCHIVE_SIZE); InBytes = new Queue(Client.Settings.STATS_QUEUE_SIZE); OutBytes = new Queue(Client.Settings.STATS_QUEUE_SIZE); - - // Timer for sending out queued packet acknowledgements - AckTimer = new Timer(new TimerCallback(AckTimer_Elapsed), null, Timeout.Infinite, Timeout.Infinite); - // Timer for recording simulator connection statistics - StatsTimer = new Timer(new TimerCallback(StatsTimer_Elapsed), null, Timeout.Infinite, Timeout.Infinite); - // Timer for periodically pinging the simulator - PingTimer = new Timer(new TimerCallback(PingTimer_Elapsed), null, Timeout.Infinite, Timeout.Infinite); } /// @@ -432,11 +425,24 @@ namespace libsecondlife return true; } - // Start the timers - AckTimer.Change(Settings.NETWORK_TICK_INTERVAL, Settings.NETWORK_TICK_INTERVAL); - StatsTimer.Change(1000, 1000); + #region Start Timers + + // Destroy the timers + if (AckTimer != null) AckTimer.Dispose(); + if (StatsTimer != null) StatsTimer.Dispose(); + if (PingTimer != null) PingTimer.Dispose(); + + // Timer for sending out queued packet acknowledgements + AckTimer = new Timer(new TimerCallback(AckTimer_Elapsed), null, Settings.NETWORK_TICK_INTERVAL, + Settings.NETWORK_TICK_INTERVAL); + // Timer for recording simulator connection statistics + StatsTimer = new Timer(new TimerCallback(StatsTimer_Elapsed), null, 1000, 1000); + // Timer for periodically pinging the simulator if (Client.Settings.SEND_PINGS) - PingTimer.Change(Settings.PING_INTERVAL, Settings.PING_INTERVAL); + PingTimer = new Timer(new TimerCallback(PingTimer_Elapsed), null, Settings.PING_INTERVAL, + Settings.PING_INTERVAL); + + #endregion Start Timers Client.Log("Connecting to " + this.ToString(), Helpers.LogLevel.Info); @@ -512,10 +518,10 @@ namespace libsecondlife { connected = false; - AckTimer.Change(Timeout.Infinite, Timeout.Infinite); - StatsTimer.Change(Timeout.Infinite, Timeout.Infinite); - if (Client.Settings.SEND_PINGS) - PingTimer.Change(Timeout.Infinite, Timeout.Infinite); + // Destroy the timers + if (AckTimer != null) AckTimer.Dispose(); + if (StatsTimer != null) StatsTimer.Dispose(); + if (PingTimer != null) PingTimer.Dispose(); // Kill the current CAPS system if (Caps != null) diff --git a/libsecondlife/examples/TestClient/Commands/Movement/FlyCommand.cs b/libsecondlife/examples/TestClient/Commands/Movement/FlyCommand.cs index 179c9dd8..b5988e9d 100644 --- a/libsecondlife/examples/TestClient/Commands/Movement/FlyCommand.cs +++ b/libsecondlife/examples/TestClient/Commands/Movement/FlyCommand.cs @@ -21,12 +21,12 @@ namespace libsecondlife.TestClient if (start) { Client.Self.Fly(true); - return "Started crouching"; + return "Started flying"; } else { Client.Self.Fly(false); - return "Stopped crouching"; + return "Stopped flying"; } } }