Skip to content

Commit

Permalink
Fixed LAN server discovery crash when having server select menu open
Browse files Browse the repository at this point in the history
Co-authored-by: Measurity <[email protected]>
  • Loading branch information
2 people authored and Jannify committed Dec 15, 2024
1 parent b064f26 commit 6b5b3de
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 29 deletions.
31 changes: 19 additions & 12 deletions NitroxClient/Communication/LANBroadcastClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,37 @@ namespace NitroxClient.Communication;
public static class LANBroadcastClient
{
private static event Action<IPEndPoint> serverFound;

public static event Action<IPEndPoint> ServerFound
{
add
{
serverFound += value;

// Trigger event for servers already found.
foreach (IPEndPoint server in discoveredServers)
foreach (IPEndPoint server in DiscoveredServers)
{
value?.Invoke(server);
}
}
remove => serverFound -= value;
}

private static Task<IEnumerable<IPEndPoint>> lastTask;
private static ConcurrentBag<IPEndPoint> discoveredServers = new();
public static ConcurrentQueue<IPEndPoint> DiscoveredServers = [];

public static async Task<IEnumerable<IPEndPoint>> SearchAsync(bool force = false, CancellationToken cancellationToken = default)
{
if (!force && lastTask != null)
{
return await lastTask;
DiscoveredServers = [];
foreach (IPEndPoint ipEndPoint in await lastTask)
{
DiscoveredServers.Enqueue(ipEndPoint);
}
return DiscoveredServers;
}

discoveredServers = new ConcurrentBag<IPEndPoint>();
return await (lastTask = SearchInternalAsync(cancellationToken));
}

Expand All @@ -57,20 +63,21 @@ static void ReceivedResponse(IPEndPoint remoteEndPoint, NetPacketReader reader,
}
int serverPort = reader.GetInt();
IPEndPoint serverEndPoint = new(remoteEndPoint.Address, serverPort);
if (discoveredServers.Contains(serverEndPoint))
if (DiscoveredServers.Contains(serverEndPoint))
{
return;
}
Log.Info($"Found LAN server at {serverEndPoint}.");
discoveredServers.Add(serverEndPoint);

Log.Debug($"Found LAN server at {serverEndPoint}.");
DiscoveredServers.Enqueue(serverEndPoint);
OnServerFound(serverEndPoint);
}

cancellationToken = cancellationToken == default ? new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token : cancellationToken;
EventBasedNetListener listener = new();
NetManager client = new(listener) {
AutoRecycle = true,
NetManager client = new(listener)
{
AutoRecycle = true,
BroadcastReceiveEnabled = true,
UnconnectedMessagesEnabled = true
};
Expand All @@ -85,7 +92,7 @@ static void ReceivedResponse(IPEndPoint remoteEndPoint, NetPacketReader reader,
if (!client.IsRunning)
{
Log.Warn("Failed to start LAN discover client: none of the defined ports are available");
return Enumerable.Empty<IPEndPoint>();
return [];
}

Log.Info("Searching for LAN servers...");
Expand Down Expand Up @@ -131,7 +138,7 @@ static void ReceivedResponse(IPEndPoint remoteEndPoint, NetPacketReader reader,
listener.ClearNetworkReceiveUnconnectedEvent();
client.Stop();
listener.NetworkReceiveUnconnectedEvent -= ReceivedResponse;
return discoveredServers;
return DiscoveredServers;
}

private static void OnServerFound(IPEndPoint obj)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
Expand All @@ -11,6 +13,7 @@
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UWE;

namespace NitroxClient.MonoBehaviours.Gui.MainMenu.ServersList;

Expand Down Expand Up @@ -245,18 +248,33 @@ private void LoadSavedServers()
}
}

private async Task FindLANServersAsync()
private IEnumerator FindLANServers()
{
void AddButton(IPEndPoint serverEndPoint)
void LateAddButton(IPEndPoint serverEndPoint)
{
// Add ServerList entry to keep indices in sync with servers UI, to enable removal by index
ServerList.Instance.Add(new("LAN Server", $"{serverEndPoint.Address}", $"{serverEndPoint.Port}", false));
CreateServerButton("LAN Server", serverEndPoint.Address.ToString(), serverEndPoint.Port, true);
if (!ServerList.Instance.Entries.Any(e => e.Address == serverEndPoint.Address.ToString() && e.Port == serverEndPoint.Port))
{
Log.Info($"Adding LAN server: {serverEndPoint}");
// Add ServerList entry to keep indices in sync with servers UI, to enable removal by index
ServerList.Instance.Add(new ServerList.Entry("LAN Server", serverEndPoint.Address.ToString(), serverEndPoint.Port.ToString(), false));
CreateServerButton("LAN Server", serverEndPoint.Address.ToString(), serverEndPoint.Port, true);
}
}

LANBroadcastClient.ServerFound += AddButton;
await LANBroadcastClient.SearchAsync();
LANBroadcastClient.ServerFound -= AddButton;
using Task<IEnumerable<IPEndPoint>> searchTask = LANBroadcastClient.SearchAsync();
while (!searchTask.IsCompleted)
{
while (LANBroadcastClient.DiscoveredServers.TryDequeue(out IPEndPoint endPoint))
{
LateAddButton(endPoint);
}
yield return null;
}
while (LANBroadcastClient.DiscoveredServers.TryDequeue(out IPEndPoint endPoint))
{
LateAddButton(endPoint);
}
ServerList.Instance.Save();
}

public GameObject CreateServerButton(string serverName, string address, int port, bool isReadOnly = false)
Expand All @@ -277,7 +295,7 @@ public GameObject CreateServerButton(string serverName, string address, int port
}
else
{
buttonText.Append(address[^Math.Min(address.Length, 25)..]).Append(':').Append(port);
buttonText.Append(address[^System.Math.Min(address.Length, 25)..]).Append(':').Append(port);
}

MainMenuServerButton serverButton = multiplayerButtonInst.AddComponent<MainMenuServerButton>();
Expand Down Expand Up @@ -342,12 +360,6 @@ public void RefreshServerEntries()

CreateAddServerButton();
LoadSavedServers();
FindLANServersAsync().ContinueWith(t =>
{
if (t is { IsFaulted: true, Exception: { } ex })
{
Log.Warn($"Failed to execute {nameof(FindLANServersAsync)}: {ex.GetFirstNonAggregateMessage()}");
}
});
CoroutineHost.StartCoroutine(FindLANServers());
}
}

0 comments on commit 6b5b3de

Please sign in to comment.