Skip to content

Commit fa7cc9b

Browse files
authored
Upgrade LiteNetLib to v1.0.1.1 (#2023)
* Upgrade LiteNetLib to v0.9.5.2 * Upgrade to LiteNetLib 1.0.1.1 * QoL * Replace WrapperPacket for direct byte sending * Added extra NR checking in WorldPersistence * Using bitwise operation in NitroxConnectionStateExtensions
1 parent f9ac48b commit fa7cc9b

21 files changed

+527
-518
lines changed

Nitrox.Test/Client/Communication/DeferredPacketReceiverTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public void TestInitialize()
4343
public void NonActionPacket()
4444
{
4545
TestNonActionPacket packet = new TestNonActionPacket(PLAYER_ID);
46-
packetReceiver.PacketReceived(packet, 0);
46+
packetReceiver.PacketReceived(packet);
4747

4848
Queue<Packet> packets = packetReceiver.GetReceivedPackets();
4949

Nitrox.sln.DotSettings

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpNaming/ApplyAutoDetectedRules/@EntryValue">False</s:Boolean>
104104
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
105105
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
106+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
106107
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Parameters/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"&gt;&lt;ExtraRule Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;ExtraRule Prefix="__" Suffix="" Style="aaBb" /&gt;&lt;ExtraRule Prefix="___" Suffix="" Style="aaBb" /&gt;&lt;ExtraRule Prefix="____" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
107108
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;</s:String>
108109
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>

NitroxClient/Communication/Abstract/IClient.cs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public interface IClient
1313
bool IsConnected { get; }
1414
Task StartAsync(string ipAddress, int serverPort);
1515
void Stop();
16+
void PollEvents();
1617
void Send(Packet packet);
1718
}
1819
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Net;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using LiteNetLib;
9+
using LiteNetLib.Utils;
10+
using NitroxModel.Constants;
11+
12+
namespace NitroxClient.Communication;
13+
14+
public static class LANBroadcastClient
15+
{
16+
private static event Action<IPEndPoint> serverFound;
17+
public static event Action<IPEndPoint> ServerFound
18+
{
19+
add
20+
{
21+
serverFound += value;
22+
23+
// Trigger event for servers already found.
24+
foreach (IPEndPoint server in discoveredServers)
25+
{
26+
value?.Invoke(server);
27+
}
28+
}
29+
remove => serverFound -= value;
30+
}
31+
private static Task<IEnumerable<IPEndPoint>> lastTask;
32+
private static ConcurrentBag<IPEndPoint> discoveredServers = new();
33+
34+
public static async Task<IEnumerable<IPEndPoint>> SearchAsync(bool force = false, CancellationToken cancellationToken = default)
35+
{
36+
if (!force && lastTask != null)
37+
{
38+
return await lastTask;
39+
}
40+
41+
discoveredServers = new ConcurrentBag<IPEndPoint>();
42+
return await (lastTask = SearchInternalAsync(cancellationToken));
43+
}
44+
45+
private static async Task<IEnumerable<IPEndPoint>> SearchInternalAsync(CancellationToken cancellationToken = default)
46+
{
47+
static void ReceivedResponse(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType)
48+
{
49+
if (messageType != UnconnectedMessageType.Broadcast)
50+
{
51+
return;
52+
}
53+
string responseString = reader.GetString();
54+
if (responseString != LANDiscoveryConstants.BROADCAST_RESPONSE_STRING)
55+
{
56+
return;
57+
}
58+
int serverPort = reader.GetInt();
59+
IPEndPoint serverEndPoint = new(remoteEndPoint.Address, serverPort);
60+
if (discoveredServers.Contains(serverEndPoint))
61+
{
62+
return;
63+
}
64+
65+
Log.Info($"Found LAN server at {serverEndPoint}.");
66+
discoveredServers.Add(serverEndPoint);
67+
OnServerFound(serverEndPoint);
68+
}
69+
70+
cancellationToken = cancellationToken == default ? new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token : cancellationToken;
71+
EventBasedNetListener listener = new();
72+
NetManager client = new(listener) {
73+
AutoRecycle = true,
74+
BroadcastReceiveEnabled = true,
75+
UnconnectedMessagesEnabled = true
76+
};
77+
// Try start client on an available, predefined, port
78+
foreach (int port in LANDiscoveryConstants.BROADCAST_PORTS)
79+
{
80+
if (client.Start(port))
81+
{
82+
break;
83+
}
84+
}
85+
if (!client.IsRunning)
86+
{
87+
Log.Warn("Failed to start LAN discover client: none of the defined ports are available");
88+
return Enumerable.Empty<IPEndPoint>();
89+
}
90+
91+
Log.Info("Searching for LAN servers...");
92+
listener.NetworkReceiveUnconnectedEvent += ReceivedResponse;
93+
Task broadcastTask = Task.Run(async () =>
94+
{
95+
while (!cancellationToken.IsCancellationRequested)
96+
{
97+
NetDataWriter writer = new();
98+
writer.Put(LANDiscoveryConstants.BROADCAST_REQUEST_STRING);
99+
foreach (int port in LANDiscoveryConstants.BROADCAST_PORTS)
100+
{
101+
client.SendBroadcast(writer, port);
102+
}
103+
try
104+
{
105+
await Task.Delay(5000, cancellationToken);
106+
}
107+
catch (TaskCanceledException)
108+
{
109+
// ignore
110+
}
111+
}
112+
}, cancellationToken);
113+
Task receiveTask = Task.Run(async () =>
114+
{
115+
while (!cancellationToken.IsCancellationRequested)
116+
{
117+
client.PollEvents();
118+
try
119+
{
120+
await Task.Delay(100, cancellationToken);
121+
}
122+
catch (TaskCanceledException)
123+
{
124+
// ignore
125+
}
126+
}
127+
}, cancellationToken);
128+
129+
await Task.WhenAll(broadcastTask, receiveTask);
130+
// Cleanup
131+
listener.ClearNetworkReceiveUnconnectedEvent();
132+
client.Stop();
133+
listener.NetworkReceiveUnconnectedEvent -= ReceivedResponse;
134+
return discoveredServers;
135+
}
136+
137+
private static void OnServerFound(IPEndPoint obj)
138+
{
139+
serverFound?.Invoke(obj);
140+
}
141+
}

NitroxClient/Communication/LANDiscoveryClient.cs

-142
This file was deleted.

0 commit comments

Comments
 (0)