diff --git a/Barotrauma/BarotraumaClient/ClientSource/LuaCs/Services/NetworkingService.cs b/Barotrauma/BarotraumaClient/ClientSource/LuaCs/Services/NetworkingService.cs index 34c1a978d..7381d416d 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/LuaCs/Services/NetworkingService.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/LuaCs/Services/NetworkingService.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace Barotrauma.LuaCs; -public partial class NetworkingService : INetworkingService, IEventConnectedToServer, IEventServerRawNetMessageReceived +partial class NetworkingService : INetworkingService, IEventConnectedToServer, IEventServerRawNetMessageReceived { private ConcurrentDictionary> receiveQueue = new(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/NetworkingService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/NetworkingService.cs index 3f9e3d0e2..261621bbf 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/NetworkingService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/NetworkingService.cs @@ -4,13 +4,14 @@ using Barotrauma.LuaCs.Events; using Barotrauma.Networking; using FluentResults; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; namespace Barotrauma.LuaCs; -public partial class NetworkingService : INetworkingService +internal partial class NetworkingService : INetworkingService { public readonly record struct NetId { @@ -47,9 +48,12 @@ public partial class NetworkingService : INetworkingService ReceiveNetIds } - private Dictionary netReceives = new Dictionary(); - private Dictionary packetToId = new Dictionary(); - private Dictionary idToPacket = new Dictionary(); + + private ConcurrentDictionary netVars = []; + + private ConcurrentDictionary netReceives = []; + private ConcurrentDictionary packetToId = []; + private ConcurrentDictionary idToPacket = []; public bool IsActive { @@ -64,10 +68,12 @@ public partial class NetworkingService : INetworkingService private readonly IEventService _eventService; private readonly ILoggerService _loggerService; + private readonly INetworkIdProvider _networkIdProvider; - public NetworkingService(IEventService eventService, ILoggerService loggerService) + internal NetworkingService(IEventService eventService, INetworkIdProvider networkIdProvider, ILoggerService loggerService) { _eventService = eventService; + _networkIdProvider = networkIdProvider; _loggerService = loggerService; #if SERVER @@ -82,7 +88,7 @@ public partial class NetworkingService : INetworkingService public IWriteMessage Start(string netIdString) => Start(new NetId(netIdString)); public IWriteMessage Start(Guid netIdGuid) => Start(new NetId(netIdGuid.ToString())); - public void Receive(NetId netId, NetMessageReceived callback) + internal void Receive(NetId netId, NetMessageReceived callback) { #if SERVER RegisterId(netId); @@ -101,7 +107,7 @@ public partial class NetworkingService : INetworkingService #if CLIENT netReceives[netId](netMessage); #elif SERVER - netReceives[netId](netMessage, client.Connection); + netReceives[netId](netMessage, client); #endif } catch (Exception e) @@ -141,25 +147,78 @@ public partial class NetworkingService : INetworkingService public Guid GetNetworkIdForInstance(INetworkSyncVar var) { - throw new NotImplementedException(); + return _networkIdProvider.GetNetworkIdForInstance(var); } public void RegisterNetVar(INetworkSyncVar netVar) { - throw new NotImplementedException(); + netVar.SetNetworkOwner(this); + + NetId netId = new NetId(netVar.InstanceId.ToString()); + netVars[netVar] = netId; + +#if CLIENT + Receive(netId, (IReadMessage message) => + { + if (netVar.SyncType == NetSync.None) + { + _loggerService.LogWarning($"Received net var from server but {nameof(NetSync)} is {netVar.SyncType.ToString()}"); + return; + } + + netVar.ReadNetMessage(message); + }); +#elif SERVER + Receive(netId, (IReadMessage message, Client client) => + { + if (netVar.SyncType == NetSync.None || netVar.SyncType == NetSync.ServerAuthority) + { + _loggerService.LogWarning($"Received net var from {GameServer.ClientLogName(client)} but {nameof(NetSync)} is {netVar.SyncType.ToString()}"); + return; + } + + if (!client.HasPermission(netVar.WritePermissions)) + { + _loggerService.LogWarning($"Received net var from {GameServer.ClientLogName(client)} but the client lacks permissions to modify it"); + return; + } + + netVar.ReadNetMessage(message); + }); +#endif } public void SendNetVar(INetworkSyncVar netVar) { - throw new NotImplementedException(); + if (!netVars.TryGetValue(netVar, out NetId netId)) + { + throw new InvalidOperationException("Tried to send net var across network without registering first"); + } + + if (netVar.SyncType == NetSync.None) { return; } +#if CLIENT + if (netVar.SyncType == NetSync.ServerAuthority) { return; } +#elif SERVER + if (netVar.SyncType == NetSync.ClientOneWay) { return; } +#endif + + IWriteMessage message = Start(netId); + netVar.WriteNetMessage(message); +#if CLIENT + SendToServer(message); +#elif SERVER + SendToClient(message); +#endif } public FluentResults.Result Reset() { IsSynchronized = false; - netReceives = new Dictionary(); - packetToId = new Dictionary(); - idToPacket = new Dictionary(); + netReceives = new ConcurrentDictionary(); + packetToId = new ConcurrentDictionary(); + idToPacket = new ConcurrentDictionary(); + netVars = new ConcurrentDictionary(); + SubscribeToEvents(); return FluentResults.Result.Ok(); } diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/_Interfaces/INetworkingService.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/_Interfaces/INetworkingService.cs index f4abbf6e2..7d6ac2930 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/_Interfaces/INetworkingService.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/_Services/_Interfaces/INetworkingService.cs @@ -9,10 +9,10 @@ namespace Barotrauma.LuaCs; #if CLIENT public delegate void NetMessageReceived(IReadMessage netMessage); #elif SERVER -public delegate void NetMessageReceived(IReadMessage netMessage, NetworkConnection connection); +internal delegate void NetMessageReceived(IReadMessage netMessage, Client connection); #endif -public interface INetworkingService : IReusableService, ILuaCsNetworking, IEntityNetworkingService +internal interface INetworkingService : IReusableService, ILuaCsNetworking, IEntityNetworkingService { bool IsActive { get; } bool IsSynchronized { get; }