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.
This commit is contained in:
Madpeterz 2020-12-19 23:44:24 +00:00
parent c7826595cd
commit bdab4f14a0

View file

@ -348,6 +348,8 @@ namespace OpenMetaverse
private Timer DisconnectTimer; private Timer DisconnectTimer;
private bool connected; private bool connected;
private long lastpacketwarning = 0;
/// <summary> /// <summary>
/// Default constructor /// Default constructor
/// </summary> /// </summary>
@ -450,26 +452,7 @@ namespace OpenMetaverse
/// <param name="packet">Packet to send</param> /// <param name="packet">Packet to send</param>
public void SendPacket(Packet packet) public void SendPacket(Packet packet)
{ {
// try CurrentSim, however directly after login this will SendPacket(packet, CurrentSim);
// 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);
}
} }
/// <summary> /// <summary>
@ -479,13 +462,18 @@ namespace OpenMetaverse
/// <param name="simulator">Simulator to send the packet to</param> /// <param name="simulator">Simulator to send the packet to</param>
public void SendPacket(Packet packet, Simulator simulator) 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) if (simulator != null)
{ {
simulator.SendPacket(packet); simulator.SendPacket(packet);
} }
else else
{ {
Logger.Log("Packet received before simulator packet processing threads running, make certain you are completely logged in", Helpers.LogLevel.Error); NetworkInvaildWarning("simulator", "SendPacket");
} }
} }
@ -494,9 +482,34 @@ namespace OpenMetaverse
/// </summary> /// </summary>
/// <param name="packet">Incoming packet to process</param> /// <param name="packet">Incoming packet to process</param>
public void EnqueueIncoming(IncomingPacket packet) public void EnqueueIncoming(IncomingPacket packet)
{ {
if (_packetInbox.Writer.TryWrite(packet)) if (_packetInbox != null)
Interlocked.Increment(ref _packetInboxCount); {
if (_packetInbox.Writer.TryWrite(packet))
Interlocked.Increment(ref _packetInboxCount);
}
else
{
NetworkInvaildWarning("_packetInbox", "EnqueueIncoming");
}
}
/// <summary>
/// adds a debug message when you try to access a network item
/// while they are still null
/// </summary>
/// <param name="source">what</param>
/// <param name="function">where</param>
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);
}
} }
/// <summary> /// <summary>
@ -505,8 +518,15 @@ namespace OpenMetaverse
/// <param name="packet">Incoming packet to process</param> /// <param name="packet">Incoming packet to process</param>
public void EnqueueOutgoing(OutgoingPacket packet) public void EnqueueOutgoing(OutgoingPacket packet)
{ {
if (_packetOutbox.Writer.TryWrite(packet)) if (_packetOutbox != null)
Interlocked.Increment(ref _packetOutboxCount); {
if (_packetOutbox.Writer.TryWrite(packet))
Interlocked.Increment(ref _packetOutboxCount);
}
else
{
NetworkInvaildWarning("_packetOutbox", "EnqueueOutgoing");
}
} }
/// <summary> /// <summary>
@ -772,9 +792,9 @@ namespace OpenMetaverse
if (simulatorsCount == 0) Shutdown(DisconnectType.SimShutdown); if (simulatorsCount == 0) Shutdown(DisconnectType.SimShutdown);
} }
else else
{ {
Logger.Log("DisconnectSim() called with a null Simulator reference", Helpers.LogLevel.Warning, Client); NetworkInvaildWarning("simulator", "DisconnectSim");
} }
} }
@ -896,58 +916,73 @@ namespace OpenMetaverse
private async Task OutgoingPacketHandler() private async Task OutgoingPacketHandler()
{ {
var reader = _packetOutbox.Reader; if (_packetOutbox != null)
{
// FIXME: This is kind of ridiculous. Port the HTB code from Simian over ASAP! var reader = _packetOutbox.Reader;
var stopwatch = new System.Diagnostics.Stopwatch();
// FIXME: This is kind of ridiculous. Port the HTB code from Simian over ASAP!
while (await reader.WaitToReadAsync() && connected) var stopwatch = new System.Diagnostics.Stopwatch();
{
while (reader.TryRead(out var outgoingPacket)) while (await reader.WaitToReadAsync() && connected)
{ {
Interlocked.Decrement(ref _packetOutboxCount); while (reader.TryRead(out var outgoingPacket))
{
var simulator = outgoingPacket.Simulator; Interlocked.Decrement(ref _packetOutboxCount);
stopwatch.Stop(); var simulator = outgoingPacket.Simulator;
if (stopwatch.ElapsedMilliseconds < 10)
{ stopwatch.Stop();
//Logger.DebugLog(String.Format("Rate limiting, last packet was {0}ms ago", ms)); if (stopwatch.ElapsedMilliseconds < 10)
Thread.Sleep(10 - (int)stopwatch.ElapsedMilliseconds); {
} //Logger.DebugLog(String.Format("Rate limiting, last packet was {0}ms ago", ms));
Thread.Sleep(10 - (int)stopwatch.ElapsedMilliseconds);
simulator.SendPacketFinal(outgoingPacket); }
stopwatch.Start();
simulator.SendPacketFinal(outgoingPacket);
stopwatch.Start();
}
} }
}
else
{
NetworkInvaildWarning("_packetOutbox", "OutgoingPacketHandler");
} }
} }
private async Task IncomingPacketHandler() private async Task IncomingPacketHandler()
{ {
var reader = _packetInbox.Reader; if (_packetInbox != null)
{
while (await reader.WaitToReadAsync() && connected) var reader = _packetInbox.Reader;
{
while (reader.TryRead(out var incomingPacket)) while (await reader.WaitToReadAsync() && connected)
{ {
Interlocked.Decrement(ref _packetInboxCount); while (reader.TryRead(out var incomingPacket))
{
var packet = incomingPacket.Packet; Interlocked.Decrement(ref _packetInboxCount);
var simulator = incomingPacket.Simulator;
var packet = incomingPacket.Packet;
if (packet == null) continue; var simulator = incomingPacket.Simulator;
// Skip blacklisted packets if (packet == null) continue;
if (UDPBlacklist.Contains(packet.Type.ToString()))
{ // Skip blacklisted packets
Logger.Log($"Discarding Blacklisted packet {packet.Type} from {simulator.IPEndPoint}", if (UDPBlacklist.Contains(packet.Type.ToString()))
Helpers.LogLevel.Warning); {
return; 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);
// Fire the callback(s), if any
PacketEvents.RaiseEvent(packet.Type, packet, simulator);
}
} }
}
else
{
NetworkInvaildWarning("_packetInbox", "IncomingPacketHandler");
} }
} }