Skip to content

Commit

Permalink
4.0.5
Browse files Browse the repository at this point in the history
- Fixed clientHost setting Tick value overwriting servers value. (#559)(#560)
- Fixed NetworkTransform sending repeatedly under certain conditions, bug introduced in 3.11.11.
- Fixed key already exist error when multiple classes with SyncTypes inherited the same NetworkBehaviour.
- Improved logging message when a RPC or SyncType index has already been registered.
- Changed Release Mode and Development Mode to Stable and Beta.
- Changed RigidbodyPauser parenting fix is no longer in Beta.
- Fixed Version 3 to Version 4 SyncType validator causing editor error for abstract NetworkBehaviours while on IL2CPP.
  • Loading branch information
FirstGearGames committed Nov 27, 2023
1 parent 47e4af5 commit 3179667
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ internal bool ProcessLocal(TypeDefinition typeDef)
* as well error if the awake does not exist, such as could not be created. */
typeDefs.Reverse();

uint declaredSyncTypes = 0;
foreach (TypeDefinition td in typeDefs)
{
/* Create NetworkInitialize before-hand so the other procesors
Expand Down Expand Up @@ -102,7 +101,7 @@ internal bool ProcessLocal(TypeDefinition typeDef)
* each registers to their own delegates this is possible. */

/* SyncTypes. */
modified |= base.GetClass<SyncTypeProcessor>().ProcessLocal(td, ref declaredSyncTypes);
modified |= base.GetClass<SyncTypeProcessor>().ProcessLocal(td);

//Call base networkinitialize early/late.
CallBaseOnNetworkInitializeMethods(td);
Expand Down Expand Up @@ -136,12 +135,6 @@ internal bool ProcessLocal(TypeDefinition typeDef)
_processedClasses.Add(td);
}

if (declaredSyncTypes > NetworkBehaviourHelper.MAX_SYNCTYPE_ALLOWANCE)
{
base.LogError($"Found {declaredSyncTypes} SyncTypes within {typeDef.FullName} and inherited classes. The maximum number of allowed SyncTypes within type and inherited types is {NetworkBehaviourHelper.MAX_SYNCTYPE_ALLOWANCE}. Remove SyncTypes or condense them using data containers, or a custom SyncObject.");
return false;
}

/* If here then all inerited classes for firstTypeDef have
* been processed. */
//Sets UsesPrediction in NetworkBehaviours.
Expand Down
39 changes: 33 additions & 6 deletions Assets/FishNet/CodeGenerating/Processing/SyncTypeProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,20 @@ public override bool ImportReferences()
/// Processes SyncVars and Objects.
/// </summary>
/// <param name="syncTypeHash">Number of SyncTypes implemented in this typeDef and those inherited of.</param>
internal bool ProcessLocal(TypeDefinition typeDef, ref uint syncTypeHash)
internal bool ProcessLocal(TypeDefinition typeDef)
{
bool modified = false;

ValidateVersion3ToVersion4SyncVars(typeDef);

uint startingHash = GetSyncTypeCountInParents(typeDef);
uint totalSyncTypes = (startingHash + GetSyncTypeCount(typeDef));
if (totalSyncTypes > NetworkBehaviourHelper.MAX_SYNCTYPE_ALLOWANCE)
{
base.LogError($"Found {totalSyncTypes} SyncTypes within {typeDef.FullName} and inherited classes. The maximum number of allowed SyncTypes within type and inherited types is {NetworkBehaviourHelper.MAX_SYNCTYPE_ALLOWANCE}. Remove SyncTypes or condense them using data containers, or a custom SyncObject.");
return false;
}

FieldDefinition[] fieldDefs = typeDef.Fields.ToArray();
foreach (FieldDefinition fd in fieldDefs)
{
Expand Down Expand Up @@ -79,13 +87,13 @@ internal bool ProcessLocal(TypeDefinition typeDef, ref uint syncTypeHash)
bool isGeneric = fd.FieldType.IsGenericInstance;
if (isGeneric)
{
if (TryCreateGenericSyncType(syncTypeHash, fd, isSyncObject))
syncTypeHash++;
if (TryCreateGenericSyncType(startingHash, fd, isSyncObject))
startingHash++;
}
else
{
if (TryCreateNonGenericSyncType(syncTypeHash, fd, isSyncObject))
syncTypeHash++;
if (TryCreateNonGenericSyncType(startingHash, fd, isSyncObject))
startingHash++;
}

modified = true;
Expand All @@ -112,6 +120,24 @@ internal uint GetSyncTypeCount(TypeDefinition typeDef)
return count;
}

/// <summary>
/// Gets SyncType count in all of typeDefs parents, excluding typeDef itself.
/// </summary>
internal uint GetSyncTypeCountInParents(TypeDefinition typeDef)
{
uint count = 0;
while (true)
{
typeDef = typeDef.GetNextBaseClassToProcess(base.Session);
if (typeDef != null)
count += GetSyncTypeCount(typeDef);
else
break;
}

return count;
}

/// <summary>
/// Returns if fieldDef is a syncType.
/// </summary>
Expand Down Expand Up @@ -177,7 +203,8 @@ private void ValidateVersion3ToVersion4SyncVars(TypeDefinition td)
//Ignore constructors.
if (methodDef.IsConstructor)
continue;

if (methodDef.IsAbstract)
continue;
for (int i = 0; i < methodDef.Body.Instructions.Count; i++)
{
Instruction inst = methodDef.Body.Instructions[i];
Expand Down
20 changes: 10 additions & 10 deletions Assets/FishNet/Runtime/Editor/Configuring/ConfigurationEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,29 @@ public static void ShowConfiguration()
public class DeveloperMenu : MonoBehaviour
{
#region const.
private const string RELEASE_DEFINE = "FISHNET_RELEASE_MODE";
private const string STABLE_DEFINE = "FISHNET_STABLE_MODE";
private const string PREDICTIONV2_DEFINE = "PREDICTION_V2";
private const string QOL_ATTRIBUTES_DEFINE = "DISABLE_QOL_ATTRIBUTES";
private const string DEVELOPER_ONLY_WARNING = "If you are not a developer or were not instructed to do this by a developer things are likely to break. You have been warned.";
#endregion


#region Release mode.
#if !FISHNET_RELEASE_MODE
[MenuItem("Fish-Networking/Switch to Release Mode", false, -1100)]
private static void SwitchToReleaseMode()
#if !FISHNET_STABLE_MODE
[MenuItem("Fish-Networking/Switch to Stable", false, -1101)]
private static void SwitchToStable()
{
bool result = RemoveOrAddDefine(RELEASE_DEFINE, false);
bool result = RemoveOrAddDefine(STABLE_DEFINE, false);
if (result)
Debug.LogWarning($"Release mode has been enabled. Please note that experimental features may not function in release mode.");
Debug.LogWarning($"Fish-Networking has been switched to Stable. Please note that experimental features may not function in this mode.");
}
#else
[MenuItem("Fish-Networking/Switch to Development Mode", false, -1100)]
private static void SwitchToReleaseMode()
[MenuItem("Fish-Networking/Switch to Beta", false, -1100)]
private static void SwitchToBeta()
{
bool result = RemoveOrAddDefine(RELEASE_DEFINE, true);
bool result = RemoveOrAddDefine(STABLE_DEFINE, true);
if (result)
Debug.LogWarning($"Development mode has been enabled.");
Debug.LogWarning($"Fish-Networking has been switched to Beta.");
}
#endif
#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,44 @@ public enum ExtrapolateState : byte
Available = 1,
Active = 2
}

/// <summary>
/// True if default state. This becomes false during an update and true when resetting state.
/// </summary>
public bool IsDefault { get; private set; } = true;
/// <summary>
/// Tick this data was received or created.
/// </summary>
public uint Tick;
public bool Snapped;
/// <summary>
/// True if this data has already been checked for snapping.
/// Snapping calls may occur multiple times when data is received, depending why or how it came in.
/// This check prevents excessive work.
/// </summary>
public bool SnappingChecked;
/// <summary>
/// Local position in the data.
/// </summary>
public Vector3 Position;
/// <summary>
/// Local rotation in the data.
/// </summary>
public Quaternion Rotation;
/// <summary>
/// Local scale in the data.
/// </summary>
public Vector3 Scale;
/// <summary>
/// Position to extrapolate towards.
/// </summary>
public Vector3 ExtrapolatedPosition;
/// <summary>
/// Current state of extrapolation.
/// </summary>
public ExtrapolateState ExtrapolationState;
/// <summary>
/// NetworkBehaviour which is the parent of this object for Tick.
/// </summary>
public NetworkBehaviour ParentBehaviour;
public TransformData() { }

Expand All @@ -247,6 +278,7 @@ internal void Update(TransformData copy)
}
internal void Update(uint tick, Vector3 position, Quaternion rotation, Vector3 scale, Vector3 extrapolatedPosition, NetworkBehaviour parentBehaviour)
{
IsDefault = false;
Tick = tick;
Position = position;
Rotation = rotation;
Expand All @@ -257,8 +289,9 @@ internal void Update(uint tick, Vector3 position, Quaternion rotation, Vector3 s

public void ResetState()
{
IsDefault = true;
Tick = 0;
Snapped = false;
SnappingChecked = false;
Position = Vector3.zero;
Rotation = Quaternion.identity;
Scale = Vector3.zero;
Expand Down Expand Up @@ -1763,7 +1796,7 @@ private bool HasChanged(TransformData a, TransformData b, ref ChangedFull change
private ChangedDelta GetChanged(TransformData transformData)
{
//If default return full changed.
if (transformData.Tick == FishNet.Managing.Timing.TimeManager.UNSET_TICK)
if (transformData.IsDefault)
return _fullChanged;
else
/* If parent behaviour exist.
Expand Down Expand Up @@ -1824,10 +1857,10 @@ private ChangedDelta GetChanged(ref Vector3 lastPosition, ref Quaternion lastRot
private void SnapProperties(TransformData transformData, bool force = false)
{
//Already snapped.
if (transformData.Snapped)
if (transformData.SnappingChecked)
return;

transformData.Snapped = true;
transformData.SnappingChecked = true;
Transform t = transform;

//Position.
Expand Down Expand Up @@ -2205,10 +2238,10 @@ private void DataReceived(ArraySegment<byte> data, Channel channel, bool asServe

_lastReceiveReliable = (channel == Channel.Reliable);
/* If channel is reliable then this is a settled packet.
* Reset last received tick so next starting move eases
* in. */
* Set tick to UNSET. When this occurs time calculations
* assume only 1 tick has passed. */
if (channel == Channel.Reliable)
nextTd.Tick = 0;
nextTd.Tick = FishNet.Managing.Timing.TimeManager.UNSET_TICK;

prevTd.Update(nextTd);
prevRd.Update(nextGd.Rates);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ private void Rigidbodies_OnOwnershipClient(NetworkConnection prevOwner)
#if UNITY_2022_1_OR_NEWER
_graphicalAnimators[i].keepAnimatorStateOnDisable = true;
#else
_graphicalAnimators[i].keepAnimatorStateOnDisable = true;
_graphicalAnimators[i].keepAnimatorControllerStateOnDisable = true;
#endif

/* True if at least one animator is on the graphical root.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,9 @@ bool PauseRigidbody(int index)
/* Move only first rigidbody to save
* performance. If rb has a parent then unset
* parent as child objects cannot be moved. */
#if !FISHNET_RELEASE_MODE
if (rb.transform.parent != null)
rb.transform.SetParent(null);
#endif

SceneManager.MoveGameObjectToScene(rb.transform.gameObject, kinematicScene);

return true;
Expand Down Expand Up @@ -350,10 +349,8 @@ bool PauseRigidbody(int index)
rbData.Update(rb);
_rigidbody2dDatas[index] = rbData;

#if !FISHNET_RELEASE_MODE
if (rb.transform.parent != null)
rb.transform.SetParent(null);
#endif

SceneManager.MoveGameObjectToScene(rb.transform.gameObject, kinematicScene);
return true;
Expand Down Expand Up @@ -393,7 +390,6 @@ bool UnpauseRigidbody(int index)
return false;

SceneManager.MoveGameObjectToScene(rb.transform.gameObject, rbData.SimulatedScene);
#if !FISHNET_RELEASE_MODE
/* If was moved while having a parent
* then set back to the same parent. If the parent does
* not exist then the object must have been destroyed.
Expand All @@ -406,7 +402,6 @@ bool UnpauseRigidbody(int index)
else
MonoBehaviour.Destroy(rb.gameObject);
}
#endif

rb.velocity = rbData.Velocity;
rb.angularVelocity = rbData.AngularVelocity;
Expand Down Expand Up @@ -436,7 +431,6 @@ bool UnpauseRigidbody(int index)
return false;

SceneManager.MoveGameObjectToScene(rb.transform.gameObject, rbData.SimulatedScene);
#if !FISHNET_RELEASE_MODE
if (rbData.HasParent)
{
Transform par = rbData.Parent;
Expand All @@ -445,7 +439,6 @@ bool UnpauseRigidbody(int index)
else
MonoBehaviour.Destroy(rb.gameObject);
}
#endif

rb.velocity = rbData.Velocity;
rb.angularVelocity = rbData.AngularVelocity;
Expand Down
3 changes: 2 additions & 1 deletion Assets/FishNet/Runtime/Managing/Client/ClientManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,8 @@ private void ParseAuthenticated(PooledReader reader)
* This still doesn't account for latency but
* it's the best we can do until the client gets
* a ping response. */
networkManager.TimeManager.Tick = networkManager.TimeManager.LastPacketTick;
if (!networkManager.IsServerStarted)
networkManager.TimeManager.Tick = networkManager.TimeManager.LastPacketTick;

//Mark as authenticated.
Connection.ConnectionAuthenticated();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -724,10 +724,7 @@ private void ReadSpawnedObject(PooledReader reader, out int? parentObjectId, out
}
}

//prefabId = (ushort)reader.ReadNetworkObjectId();
// componentIndex is currently unused
_ = reader.ReadNetworkBehaviourId(out var nobId);
prefabId = (ushort)nobId;
prefabId = (ushort)reader.ReadNetworkObjectId();
}

}
Expand Down
33 changes: 9 additions & 24 deletions Assets/FishNet/Runtime/Object/NetworkBehaviour.RPCs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,10 @@ internal void SendBufferedRpcs(NetworkConnection conn)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void RegisterServerRpc(uint hash, ServerRpcDelegate del)
{
if (_serverRpcDelegates.TryGetValueIL2CPP(hash, out ServerRpcDelegate currentDelegate))
{
FishNet.Managing.NetworkManager.StaticLogError($"ServerRpc hash {hash} registered multiple times. First registration by {currentDelegate.Method.DeclaringType.GetType().FullName}. New registration by {GetType().FullName}.");
}
else
{
_serverRpcDelegates[hash] = del;
if (_serverRpcDelegates.TryAdd(hash, del))
IncreaseRpcMethodCount();
}
else
FishNet.Managing.NetworkManager.StaticLogError($"ServerRpc key {hash} has already been added for {GetType().FullName} on {gameObject.name}");
}
/// <summary>
/// Registers a RPC method.
Expand All @@ -114,15 +109,10 @@ internal void RegisterServerRpc(uint hash, ServerRpcDelegate del)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void RegisterObserversRpc(uint hash, ClientRpcDelegate del)
{
if (_observersRpcDelegates.TryGetValueIL2CPP(hash, out ClientRpcDelegate currentDelegate))
{
FishNet.Managing.NetworkManager.StaticLogError($"ObserverRpc hash {hash} registered multiple times. First registration by {currentDelegate.Method.DeclaringType.GetType().FullName}. New registration by {GetType().FullName}.");
}
else
{
_observersRpcDelegates[hash] = del;
if (_observersRpcDelegates.TryAdd(hash, del))
IncreaseRpcMethodCount();
}
else
FishNet.Managing.NetworkManager.StaticLogError($"ObserversRpc key {hash} has already been added for {GetType().FullName} on {gameObject.name}");
}
/// <summary>
/// Registers a RPC method.
Expand All @@ -134,15 +124,10 @@ internal void RegisterObserversRpc(uint hash, ClientRpcDelegate del)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void RegisterTargetRpc(uint hash, ClientRpcDelegate del)
{
if (_targetRpcDelegates.TryGetValueIL2CPP(hash, out ClientRpcDelegate currentDelegate))
{
FishNet.Managing.NetworkManager.StaticLogError($"TargetRpc hash {hash} registered multiple times. First registration by {currentDelegate.Method.DeclaringType.GetType().FullName}. New registration by {GetType().FullName}.");
}
if (_targetRpcDelegates.TryAdd(hash, del))
IncreaseRpcMethodCount();
else
{
_targetRpcDelegates[hash] = del;
IncreaseRpcMethodCount();
}
FishNet.Managing.NetworkManager.StaticLogError($"TargetRpc key {hash} has already been added for {GetType().FullName} on {gameObject.name}");
}

/// <summary>
Expand Down
3 changes: 2 additions & 1 deletion Assets/FishNet/Runtime/Object/NetworkBehaviour.SyncTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ public void Reset()
/// <param name="index"></param>
internal void RegisterSyncType(SyncBase sb, uint index)
{
_syncTypes.Add(index, sb);
if (!_syncTypes.TryAdd(index, sb))
FishNet.Managing.NetworkManager.StaticLogError($"SyncType key {index} has already been added for {GetType().FullName} on {gameObject.name}");
}
/// <summary>
/// Sets a SyncVar as dirty.
Expand Down
Loading

0 comments on commit 3179667

Please sign in to comment.