- Fixed network synchro of vars, needs synctype testing.

This commit is contained in:
MapleWheels
2026-04-09 05:34:50 -04:00
parent 84cb7cfeb7
commit ef66d27ffe
22 changed files with 115 additions and 23 deletions

View File

@@ -13,9 +13,25 @@ partial class NetworkingService : INetworkingService, IEventServerConnected, IEv
public void OnServerConnected() public void OnServerConnected()
{ {
ActivateNetVars();
SendSyncMessage(); SendSyncMessage();
} }
private void ActivateNetVars()
{
if (GameMain.Client == null)
{
return;
}
// re-activate net vars
// todo: unregister net vars on client disconnect, currently handled by unloading the state machine.
foreach (var networkSyncVar in netVars.Keys)
{
networkSyncVar.SetNetworkOwner(this);
}
}
public void OnReceivedServerNetMessage(IReadMessage netMessage, ServerPacketHeader serverPacketHeader) public void OnReceivedServerNetMessage(IReadMessage netMessage, ServerPacketHeader serverPacketHeader)
{ {
if (serverPacketHeader != ServerHeader) if (serverPacketHeader != ServerHeader)
@@ -44,7 +60,7 @@ partial class NetworkingService : INetworkingService, IEventServerConnected, IEv
private void SendSyncMessage() private void SendSyncMessage()
{ {
if (GameMain.Client == null) { return; } if (GameMain.Client == null) { return; }
WriteOnlyMessage message = new WriteOnlyMessage(); WriteOnlyMessage message = new WriteOnlyMessage();
message.WriteByte((byte)ClientHeader); message.WriteByte((byte)ClientHeader);
message.WriteByte((byte)ClientToServer.RequestSync); message.WriteByte((byte)ClientToServer.RequestSync);

View File

@@ -2,6 +2,8 @@
<Configuration> <Configuration>
<Settings> <Settings>
<Setting Name="TestTickbox" Type="bool"/> <Setting Name="TestTickbox" Type="bool"/>
<Setting Name="TestSynchroClient" Type="int" NetSync="TwoWay" />
<Setting Name="TestSynchroServer" Type="int" NetSync="ServerAuthority" />
<Setting Name="TestFloat" Type="float" NetSync="ServerAuthority" /> <Setting Name="TestFloat" Type="float" NetSync="ServerAuthority" />
<Setting Name="TestHidden" Type="bool" ShowInMenus="false"/> <Setting Name="TestHidden" Type="bool" ShowInMenus="false"/>
<Setting Name="TestRangeFloat" Type="rangeFloat" Min="0" Max="25" Steps="11"/> <Setting Name="TestRangeFloat" Type="rangeFloat" Min="0" Max="25" Steps="11"/>

View File

@@ -53,9 +53,14 @@ public partial class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyn
public virtual bool TrySetValue(T value) public virtual bool TrySetValue(T value)
{ {
if (value is null || value.Equals(Value))
{
return false;
}
#if CLIENT #if CLIENT
if (SyncType is NetSync.ServerAuthority && NetworkingService is not null if (SyncType is NetSync.ServerAuthority && NetworkingService is not null
&& GameMain.IsMultiplayer && GameMain.IsMultiplayer
&& GameMain.Client is not null
&& !GameMain.Client.HasPermission(this.WritePermissions)) && !GameMain.Client.HasPermission(this.WritePermissions))
{ {
return false; return false;
@@ -73,7 +78,7 @@ public partial class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyn
NetworkingService?.SendNetVar(this); NetworkingService?.SendNetVar(this);
} }
#elif SERVER #elif SERVER
if (GameMain.IsMultiplayer && SyncType is NetSync.TwoWay or NetSync.ServerAuthority) if (SyncType is NetSync.TwoWay or NetSync.ServerAuthority)
{ {
NetworkingService?.SendNetVar(this); NetworkingService?.SendNetVar(this);
} }
@@ -97,9 +102,48 @@ public partial class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyn
return true; return true;
} }
/// <summary>
/// handles internal networking rules after reading the net message (to avoid synchro issues).
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private bool TrySetValueNetwork(T value)
{
if (NetworkingService is null)
{
return false;
}
#if CLIENT
if (SyncType is NetSync.None or NetSync.ClientOneWay)
{
return false;
}
#else
if (SyncType is NetSync.None or NetSync.ServerAuthority)
{
return false;
}
#endif
if (!TrySetValueInternal(value))
{
return false;
}
#if SERVER
if (SyncType is NetSync.TwoWay)
{
NetworkingService?.SendNetVar(this);
}
#endif
OnValueChanged?.Invoke(this);
return true;
}
protected override void OnDispose() protected override void OnDispose()
{ {
ValueChangePredicate = null; ValueChangePredicate = null;
NetworkingService?.DeregisterNetVar(this);
} }
public override Type GetValueType() => typeof(T); public override Type GetValueType() => typeof(T);
@@ -151,11 +195,6 @@ public partial class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyn
public void SetNetworkOwner(IEntityNetworkingService networkingService) public void SetNetworkOwner(IEntityNetworkingService networkingService)
{ {
NetworkingService = networkingService; NetworkingService = networkingService;
if (NetworkingService is null)
{
return;
}
NetworkingService.RegisterNetVar(this);
} }
public NetSync SyncType => ConfigInfo?.NetSync ?? NetSync.None; public NetSync SyncType => ConfigInfo?.NetSync ?? NetSync.None;
@@ -181,42 +220,42 @@ public partial class SettingEntry<T> : SettingBase, ISettingBase<T>, INetworkSyn
switch (typeCode) switch (typeCode)
{ {
case TypeCode.Boolean: case TypeCode.Boolean:
TrySetValueInternal((T)Convert.ChangeType(message.ReadBoolean(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadBoolean(), typeCode));
return; return;
case TypeCode.Byte: case TypeCode.Byte:
TrySetValueInternal((T)Convert.ChangeType(message.ReadByte(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadByte(), typeCode));
return; return;
// SByte not supported by interface // SByte not supported by interface
case TypeCode.SByte: case TypeCode.SByte:
TrySetValueInternal((T)Convert.ChangeType(message.ReadInt16(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadInt16(), typeCode));
return; return;
case TypeCode.Int16: case TypeCode.Int16:
TrySetValueInternal((T)Convert.ChangeType(message.ReadInt16(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadInt16(), typeCode));
return; return;
case TypeCode.Char: case TypeCode.Char:
case TypeCode.UInt16: case TypeCode.UInt16:
TrySetValueInternal((T)Convert.ChangeType(message.ReadUInt16(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadUInt16(), typeCode));
return; return;
case TypeCode.Int32: case TypeCode.Int32:
TrySetValueInternal((T)Convert.ChangeType(message.ReadInt32(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadInt32(), typeCode));
return; return;
case TypeCode.UInt32: case TypeCode.UInt32:
TrySetValueInternal((T)Convert.ChangeType(message.ReadUInt32(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadUInt32(), typeCode));
return; return;
case TypeCode.Int64: case TypeCode.Int64:
TrySetValueInternal((T)Convert.ChangeType(message.ReadInt64(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadInt64(), typeCode));
return; return;
case TypeCode.UInt64: case TypeCode.UInt64:
TrySetValueInternal((T)Convert.ChangeType(message.ReadUInt64(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadUInt64(), typeCode));
return; return;
case TypeCode.Single: case TypeCode.Single:
TrySetValueInternal((T)Convert.ChangeType(message.ReadSingle(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadSingle(), typeCode));
return; return;
case TypeCode.Double: case TypeCode.Double:
TrySetValueInternal((T)Convert.ChangeType(message.ReadDouble(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadDouble(), typeCode));
return; return;
case TypeCode.String: case TypeCode.String:
TrySetValueInternal((T)Convert.ChangeType(message.ReadString(), typeCode)); TrySetValueNetwork((T)Convert.ChangeType(message.ReadString(), typeCode));
return; return;
case TypeCode.Decimal: case TypeCode.Decimal:
default: default:

View File

@@ -91,7 +91,11 @@ public class SettingList<T> : SettingEntry<T>, ISettingList<T> where T : IEquata
public bool TrySetValueByIndex(int index) public bool TrySetValueByIndex(int index)
{ {
throw new NotImplementedException(); if (_valuesList.Count <= index)
{
return false;
}
return base.TrySetValue(_valuesList[index]);
} }
public IReadOnlyList<T> Options => _valuesList.AsReadOnly(); public IReadOnlyList<T> Options => _valuesList.AsReadOnly();

View File

@@ -947,6 +947,8 @@ interface IEventInventoryItemSwap : IEvent<IEventInventoryItemSwap>
#region Networking #region Networking
#region Networking-Server #region Networking-Server
#if SERVER #if SERVER
public interface IEventClientRawNetMessageReceived : IEvent<IEventClientRawNetMessageReceived> public interface IEventClientRawNetMessageReceived : IEvent<IEventClientRawNetMessageReceived>

View File

@@ -11,10 +11,11 @@ using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using Barotrauma.LuaCs.Data;
namespace Barotrauma.LuaCs; namespace Barotrauma.LuaCs;
internal partial class NetworkingService : INetworkingService internal partial class NetworkingService : INetworkingService, IEventSettingInstanceLifetime
{ {
public readonly record struct NetId public readonly record struct NetId
{ {
@@ -112,7 +113,6 @@ internal partial class NetworkingService : INetworkingService
#if SERVER #if SERVER
IsSynchronized = true; IsSynchronized = true;
#endif #endif
SubscribeToEvents(); SubscribeToEvents();
} }
@@ -189,6 +189,7 @@ internal partial class NetworkingService : INetworkingService
private void SubscribeToEvents() private void SubscribeToEvents()
{ {
_eventService.Subscribe<IEventSettingInstanceLifetime>(this);
#if CLIENT #if CLIENT
_eventService.Subscribe<IEventServerConnected>(this); _eventService.Subscribe<IEventServerConnected>(this);
_eventService.Subscribe<IEventServerRawNetMessageReceived>(this); _eventService.Subscribe<IEventServerRawNetMessageReceived>(this);
@@ -246,7 +247,18 @@ internal partial class NetworkingService : INetworkingService
#endif #endif
} }
public void SendNetVar(INetworkSyncVar netVar) => SendNetVar(netVar); public void DeregisterNetVar(INetworkSyncVar netVar)
{
if (netVar is null)
{
return;
}
netVar.SetNetworkOwner(null);
netVars.TryRemove(netVar, out _);
}
public void SendNetVar(INetworkSyncVar netVar) => SendNetVar(netVar, null);
public void SendNetVar(INetworkSyncVar netVar, NetworkConnection connection = null) public void SendNetVar(INetworkSyncVar netVar, NetworkConnection connection = null)
{ {
@@ -390,4 +402,20 @@ internal partial class NetworkingService : INetworkingService
#endif #endif
#endregion #endregion
public void OnSettingInstanceCreated<T>(T configInstance) where T : ISettingBase
{
if (configInstance is INetworkSyncVar syncVar)
{
RegisterNetVar(syncVar);
}
}
public void OnSettingInstanceDisposed<T>(T configInstance) where T : ISettingBase
{
if (configInstance is INetworkSyncVar syncVar)
{
DeregisterNetVar(syncVar);
}
}
} }

View File

@@ -33,6 +33,7 @@ public interface IEntityNetworkingService
{ {
Guid GetNetworkIdForInstance(INetworkSyncVar var); Guid GetNetworkIdForInstance(INetworkSyncVar var);
void RegisterNetVar(INetworkSyncVar netVar); void RegisterNetVar(INetworkSyncVar netVar);
void DeregisterNetVar(INetworkSyncVar netVar);
void SendNetVar(INetworkSyncVar netVar); void SendNetVar(INetworkSyncVar netVar);
void SendNetVar(INetworkSyncVar netVar, NetworkConnection connection); void SendNetVar(INetworkSyncVar netVar, NetworkConnection connection);
} }