From bdab4f14a0f023f6dbb675d80d2172d5b59e1dbe Mon Sep 17 00:00:00 2001 From: Madpeterz <57852827+Madpeterz@users.noreply.github.com> Date: Sat, 19 Dec 2020 23:44:24 +0000 Subject: [PATCH] Update NetworkManager.cs adds extra checks for null and improves SendPacket, also adds a new function: NetworkInvaildWarning to handle passing to the log as debug level. why: In some cases the network can disconnect from the sim in a weird way so the client trys to send data out but the outbox / inbox are gone. these extra checks will help stop it from outright killing itself. --- .../Libremetaverse/NetworkManager.cs | 187 +++++++++++------- 1 file changed, 111 insertions(+), 76 deletions(-) diff --git a/libremetaverse-core/Libremetaverse/NetworkManager.cs b/libremetaverse-core/Libremetaverse/NetworkManager.cs index 1ccd932..cfb89be 100644 --- a/libremetaverse-core/Libremetaverse/NetworkManager.cs +++ b/libremetaverse-core/Libremetaverse/NetworkManager.cs @@ -348,6 +348,8 @@ namespace OpenMetaverse private Timer DisconnectTimer; private bool connected; + private long lastpacketwarning = 0; + /// /// Default constructor /// @@ -450,26 +452,7 @@ namespace OpenMetaverse /// Packet to send public void SendPacket(Packet packet) { - // try CurrentSim, however directly after login this will - // be null, so if it is, we'll try to find the first simulator - // we're connected to in order to send the packet. - Simulator simulator = CurrentSim; - - if (simulator == null && Client.Network.Simulators.Count >= 1) - { - Logger.DebugLog("CurrentSim object was null, using first found connected simulator", Client); - simulator = Client.Network.Simulators[0]; - } - - if (simulator != null && simulator.Connected) - { - simulator.SendPacket(packet); - } - else - { - //throw new NotConnectedException("Packet received before simulator packet processing threads running, make certain you are completely logged in"); - Logger.Log("Packet received before simulator packet processing threads running, make certain you are completely logged in.", Helpers.LogLevel.Error); - } + SendPacket(packet, CurrentSim); } /// @@ -479,13 +462,18 @@ namespace OpenMetaverse /// Simulator to send the packet to public void SendPacket(Packet packet, Simulator simulator) { + if (simulator == null && Client.Network.Simulators.Count >= 1) + { + Logger.DebugLog("simulator object was null, using first found connected simulator", Client); + simulator = Client.Network.Simulators[0]; + } if (simulator != null) { simulator.SendPacket(packet); } - else - { - Logger.Log("Packet received before simulator packet processing threads running, make certain you are completely logged in", Helpers.LogLevel.Error); + else + { + NetworkInvaildWarning("simulator", "SendPacket"); } } @@ -494,9 +482,34 @@ namespace OpenMetaverse /// /// Incoming packet to process public void EnqueueIncoming(IncomingPacket packet) - { - if (_packetInbox.Writer.TryWrite(packet)) - Interlocked.Increment(ref _packetInboxCount); + { + if (_packetInbox != null) + { + if (_packetInbox.Writer.TryWrite(packet)) + Interlocked.Increment(ref _packetInboxCount); + } + else + { + NetworkInvaildWarning("_packetInbox", "EnqueueIncoming"); + } + } + + /// + /// adds a debug message when you try to access a network item + /// while they are still null + /// + /// what + /// where + protected void NetworkInvaildWarning(string source,string function) + { + long now = DateTimeOffset.Now.ToUnixTimeSeconds(); + long dif = lastpacketwarning - now; + if (dif > 10) + { + lastpacketwarning = now; + Logger.Log(source+" is null (Are we disconnected?) - from: "+ function, + Helpers.LogLevel.Debug); + } } /// @@ -505,8 +518,15 @@ namespace OpenMetaverse /// Incoming packet to process public void EnqueueOutgoing(OutgoingPacket packet) { - if (_packetOutbox.Writer.TryWrite(packet)) - Interlocked.Increment(ref _packetOutboxCount); + if (_packetOutbox != null) + { + if (_packetOutbox.Writer.TryWrite(packet)) + Interlocked.Increment(ref _packetOutboxCount); + } + else + { + NetworkInvaildWarning("_packetOutbox", "EnqueueOutgoing"); + } } /// @@ -772,9 +792,9 @@ namespace OpenMetaverse if (simulatorsCount == 0) Shutdown(DisconnectType.SimShutdown); } - else - { - Logger.Log("DisconnectSim() called with a null Simulator reference", Helpers.LogLevel.Warning, Client); + else + { + NetworkInvaildWarning("simulator", "DisconnectSim"); } } @@ -896,58 +916,73 @@ namespace OpenMetaverse private async Task OutgoingPacketHandler() { - var reader = _packetOutbox.Reader; - - // FIXME: This is kind of ridiculous. Port the HTB code from Simian over ASAP! - var stopwatch = new System.Diagnostics.Stopwatch(); - - while (await reader.WaitToReadAsync() && connected) - { - while (reader.TryRead(out var outgoingPacket)) - { - Interlocked.Decrement(ref _packetOutboxCount); - - var simulator = outgoingPacket.Simulator; - - stopwatch.Stop(); - if (stopwatch.ElapsedMilliseconds < 10) - { - //Logger.DebugLog(String.Format("Rate limiting, last packet was {0}ms ago", ms)); - Thread.Sleep(10 - (int)stopwatch.ElapsedMilliseconds); - } - - simulator.SendPacketFinal(outgoingPacket); - stopwatch.Start(); + if (_packetOutbox != null) + { + var reader = _packetOutbox.Reader; + + // FIXME: This is kind of ridiculous. Port the HTB code from Simian over ASAP! + var stopwatch = new System.Diagnostics.Stopwatch(); + + while (await reader.WaitToReadAsync() && connected) + { + while (reader.TryRead(out var outgoingPacket)) + { + Interlocked.Decrement(ref _packetOutboxCount); + + var simulator = outgoingPacket.Simulator; + + stopwatch.Stop(); + if (stopwatch.ElapsedMilliseconds < 10) + { + //Logger.DebugLog(String.Format("Rate limiting, last packet was {0}ms ago", ms)); + Thread.Sleep(10 - (int)stopwatch.ElapsedMilliseconds); + } + + simulator.SendPacketFinal(outgoingPacket); + stopwatch.Start(); + } } + } + else + { + NetworkInvaildWarning("_packetOutbox", "OutgoingPacketHandler"); } + } private async Task IncomingPacketHandler() { - var reader = _packetInbox.Reader; - - while (await reader.WaitToReadAsync() && connected) - { - while (reader.TryRead(out var incomingPacket)) - { - Interlocked.Decrement(ref _packetInboxCount); - - var packet = incomingPacket.Packet; - var simulator = incomingPacket.Simulator; - - if (packet == null) continue; - - // Skip blacklisted packets - if (UDPBlacklist.Contains(packet.Type.ToString())) - { - Logger.Log($"Discarding Blacklisted packet {packet.Type} from {simulator.IPEndPoint}", - Helpers.LogLevel.Warning); - return; - } - - // Fire the callback(s), if any - PacketEvents.RaiseEvent(packet.Type, packet, simulator); + if (_packetInbox != null) + { + var reader = _packetInbox.Reader; + + while (await reader.WaitToReadAsync() && connected) + { + while (reader.TryRead(out var incomingPacket)) + { + Interlocked.Decrement(ref _packetInboxCount); + + var packet = incomingPacket.Packet; + var simulator = incomingPacket.Simulator; + + if (packet == null) continue; + + // Skip blacklisted packets + if (UDPBlacklist.Contains(packet.Type.ToString())) + { + Logger.Log($"Discarding Blacklisted packet {packet.Type} from {simulator.IPEndPoint}", + Helpers.LogLevel.Warning); + return; + } + + // Fire the callback(s), if any + PacketEvents.RaiseEvent(packet.Type, packet, simulator); + } } + } + else + { + NetworkInvaildWarning("_packetInbox", "IncomingPacketHandler"); } }