Skip to content

Commit

Permalink
4.0.6
Browse files Browse the repository at this point in the history
- Fixed prediction v2(experimental) replicate not replaying a single tick of input.
- Fixed prediction v2(experimental) delay in server accepting client input when re-gaining ownership of an object.
- Fixed prediction v2(experimental) large forwarded replicates not properly changing channel.
- Fixed SyncType constructors being overwritten with defaults.
- Fixed large replicates not properly changing channel.
- Fixed NetworkTransform using approximately 3% more bandwidth when Network LOD was enabled without having Pro.
- Improved debug output for when starting client and server to also state IP/Port when available.
- Fixed package.json not being on git root.
  • Loading branch information
FirstGearGames committed Dec 5, 2023
1 parent 3179667 commit d780e80
Show file tree
Hide file tree
Showing 17 changed files with 516 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ public static class CollectionCaches<T>
/// </summary>
private readonly static Stack<List<T>> _listCache = new Stack<List<T>>();
/// <summary>
/// Cache for queues.
/// </summary>
private readonly static Stack<Queue<T>> _queueCache = new Stack<Queue<T>>();
/// <summary>
/// Cache for hashset.
/// </summary>
private readonly static Stack<HashSet<T>> _hashsetCache = new Stack<HashSet<T>>();
Expand Down Expand Up @@ -380,6 +384,32 @@ public static List<T> RetrieveList()
return _listCache.Pop();
}
/// <summary>
/// Retrieves a collection.
/// </summary>
/// <returns></returns>
public static Queue<T> RetrieveQueue()
{
if (_queueCache.Count == 0)
return new Queue<T>();
else
return _queueCache.Pop();
}
/// <summary>
/// Retrieves a collection adding one entry.
/// </summary>
/// <returns></returns>
public static Queue<T> RetrieveQueue(T entry)
{
Queue<T> result;
if (_queueCache.Count == 0)
result = new Queue<T>();
else
result = _queueCache.Pop();

result.Enqueue(entry);
return result;
}
/// <summary>
/// Retrieves a collection adding one entry.
/// </summary>
/// <returns></returns>
Expand Down Expand Up @@ -472,6 +502,29 @@ public static void Store(List<T> value)
_listCache.Push(value);
}

/// <summary>
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
/// </summary>
/// <param name="value">Value to store.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void StoreAndDefault(ref Queue<T> value)
{
if (value == null)
return;
Store(value);
value = default;
}
/// <summary>
/// Stores a collection.
/// </summary>
/// <param name="value">Value to store.</param>
public static void Store(Queue<T> value)
{
value.Clear();
_queueCache.Push(value);
}

/// <summary>
/// Stores a collection and sets the original reference to default.
/// Method will not execute if value is null.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void Broadcast<T>(T message, Channel channel = Channel.Reliable) where T
}

PooledWriter writer = WriterPool.Retrieve();
Broadcasts.WriteBroadcast<T>(writer, message, channel);
Broadcasts.WriteBroadcast<T>(NetworkManager, writer, message, ref channel);
ArraySegment<byte> segment = writer.GetArraySegment();

NetworkManager.TransportManager.SendToServer((byte)channel, segment);
Expand Down
5 changes: 4 additions & 1 deletion Assets/FishNet/Runtime/Managing/Client/ClientManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,10 @@ private void Transport_OnClientConnectionState(ClientConnectionStateArgs args)
{
Transport t = NetworkManager.TransportManager.GetTransport(args.TransportIndex);
string tName = (t == null) ? "Unknown" : t.GetType().Name;
Debug.Log($"Local client is {state.ToString().ToLower()} for {tName}.");
string socketInformation = string.Empty;
if (state == LocalConnectionState.Starting)
socketInformation = $" Server IP is {t.GetClientAddress()}, port is {t.GetPort()}.";
Debug.Log($"Local client is {state.ToString().ToLower()} for {tName}.{socketInformation}");
}

NetworkManager.UpdateFramerate();
Expand Down
3 changes: 3 additions & 0 deletions Assets/FishNet/Runtime/Managing/Observing/ObserverManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ internal void CalculateLevelOfDetail(uint tick)
/// </summary>
private void ValidateLevelOfDetails()
{
#if !FISHNET_PRO
_enableNetworkLod = false;
#endif

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,8 @@ internal void ReconcileToStates()
* Replay up to localtick, excluding localtick. There will
* be no input for localtick since reconcile runs before
* OnTick. */
uint clientReplayTick = StateClientTick + 1;
uint serverReplayTick = StateServerTick + 1;
uint clientReplayTick = StateClientTick; //+ 1;
uint serverReplayTick = StateServerTick;// + 1;
while (clientReplayTick < localTick)
{
OnPreReplicateReplay?.Invoke(clientReplayTick, serverReplayTick);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void Broadcast<T>(NetworkConnection connection, T message, bool requireAu
}

PooledWriter writer = WriterPool.Retrieve();
Broadcasts.WriteBroadcast<T>(writer, message, channel);
Broadcasts.WriteBroadcast<T>(NetworkManager, writer, message, ref channel);
ArraySegment<byte> segment = writer.GetArraySegment();
NetworkManager.TransportManager.SendToClient((byte)channel, segment, connection);
writer.Store();
Expand All @@ -137,7 +137,7 @@ public void Broadcast<T>(HashSet<NetworkConnection> connections, T message, bool

bool failedAuthentication = false;
PooledWriter writer = WriterPool.Retrieve();
Broadcasts.WriteBroadcast<T>(writer, message, channel);
Broadcasts.WriteBroadcast<T>(NetworkManager, writer, message, ref channel);
ArraySegment<byte> segment = writer.GetArraySegment();

foreach (NetworkConnection conn in connections)
Expand Down Expand Up @@ -326,7 +326,7 @@ public void Broadcast<T>(T message, bool requireAuthenticated = true, Channel ch

bool failedAuthentication = false;
PooledWriter writer = WriterPool.Retrieve();
Broadcasts.WriteBroadcast<T>(writer, message, channel);
Broadcasts.WriteBroadcast<T>(NetworkManager, writer, message, ref channel);
ArraySegment<byte> segment = writer.GetArraySegment();

foreach (NetworkConnection conn in Clients.Values)
Expand Down
5 changes: 4 additions & 1 deletion Assets/FishNet/Runtime/Managing/Server/ServerManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,10 @@ private void Transport_OnServerConnectionState(ServerConnectionStateArgs args)
{
Transport t = NetworkManager.TransportManager.GetTransport(args.TransportIndex);
string tName = (t == null) ? "Unknown" : t.GetType().Name;
Debug.Log($"Local server is {state.ToString().ToLower()} for {tName}.");
string socketInformation = string.Empty;
if (state == LocalConnectionState.Starting)
socketInformation = $" Listening on port {t.GetPort()}.";
Debug.Log($"Local server is {state.ToString().ToLower()} for {tName}.{socketInformation}");
}

NetworkManager.UpdateFramerate();
Expand Down
15 changes: 9 additions & 6 deletions Assets/FishNet/Runtime/Object/NetworkBehaviour.Prediction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ internal virtual void ClearReplicateCache_Virtual(bool asServer) { }
/// </summary>
public void ClearReplicateCache()
{
_lastReadReconcileTick = TimeManager.UNSET_TICK;
_lastReadReplicateTick = TimeManager.UNSET_TICK;
_networkObjectCache.ResetReplicateTick();
ClearReplicateCache_Virtual<IReplicateData>(null, null);
}
Expand Down Expand Up @@ -347,6 +349,7 @@ private void Owner_SendReplicateRpc<T>(uint hash, List<T> replicates, Channel ch
//writer = CreateLinkedRpc(link, methodWriter, Channel.Unreliable);
//else //todo add support for -> server rpc links.

_transportManagerCache.CheckSetReliableChannel(methodWriter.Length + MAXIMUM_RPC_HEADER_SIZE, ref channel);
writer = CreateRpc(hash, methodWriter, PacketId.Replicate, channel);
NetworkManager.TransportManager.SendToServer((byte)channel, writer.GetArraySegment(), false);

Expand Down Expand Up @@ -990,6 +993,8 @@ private void SendReplicateRpc<T>(bool toServer, uint hash, List<T> replicatesHis
methodWriter.WriteTickUnpacked(TimeManager.LocalTick);
}
methodWriter.WriteReplicate<T>(replicatesHistory, offset);

_transportManagerCache.CheckSetReliableChannel(methodWriter.Length + MAXIMUM_RPC_HEADER_SIZE, ref channel);
PooledWriter writer = CreateRpc(hash, methodWriter, PacketId.Replicate, channel);

if (toServer)
Expand Down Expand Up @@ -1069,7 +1074,6 @@ internal void Replicate_Reader<T>(uint hash, PooledReader reader, NetworkConnect
//Early exit if old data.
if (lastPacketTick <= _networkObjectCache.ReplicateTick.RemoteTick)
return;

/* Replicate rpc readers relay to this method and
* do not have an owner check in the generated code.
* Only server needs to check for owners. Clients
Expand All @@ -1095,7 +1099,7 @@ internal void Replicate_Reader<T>(uint hash, PooledReader reader, NetworkConnect
if (IsServerStarted)
{
ArraySegment<byte> replicateDataOnly = new ArraySegment<byte>(reader.GetByteBuffer(), startingPosition, (reader.Position - startingPosition));
Replicate_Server_SendToSpectators<T>(hash, startingQueueCount, replicateDataOnly, receivedReplicatesCount);
Replicate_Server_SendToSpectators<T>(hash, startingQueueCount, replicateDataOnly, receivedReplicatesCount, channel);
}
}
#endif
Expand All @@ -1106,7 +1110,7 @@ internal void Replicate_Reader<T>(uint hash, PooledReader reader, NetworkConnect
/// Sends data from a reader which only contains the replicate packet.
/// </summary>
[MakePublic]
internal void Replicate_Server_SendToSpectators<T>(uint hash, int startingReplicatesQueueCount, ArraySegment<byte> data, int queueCount) where T : IReplicateData
internal void Replicate_Server_SendToSpectators<T>(uint hash, int startingReplicatesQueueCount, ArraySegment<byte> data, int queueCount, Channel channel) where T : IReplicateData
{
//Should not be possible.
if (queueCount == 0)
Expand Down Expand Up @@ -1150,7 +1154,6 @@ internal void Replicate_Server_SendToSpectators<T>(uint hash, int startingReplic

//Write history to methodWriter.
methodWriter.WriteArraySegment(data);
Channel channel = Channel.Unreliable;
PooledWriter writer = CreateRpc(hash, methodWriter, PacketId.Replicate, channel);

//Exclude owner and if clientHost, also localClient.
Expand Down Expand Up @@ -1415,8 +1418,8 @@ protected internal void Reconcile_Client<T, T2>(ReconcileUserLogicDelegate<T> re
{
//Remove from replicates up to reconcile.
int replicateIndex = GetReplicateHistoryIndex<T2>(data.GetTick(), replicatesHistory);
if (replicateIndex >= 0)
replicatesHistory.RemoveRange(0, replicateIndex + 1);
if (replicateIndex > 0)
replicatesHistory.RemoveRange(0, replicateIndex);
}
//Call reconcile user logic.
reconcileDel?.Invoke(data, Channel.Reliable);
Expand Down
82 changes: 51 additions & 31 deletions Assets/FishNet/Runtime/Object/NetworkObject.Prediction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,46 +115,55 @@ private void InitializeSmoothers()
RigidbodyPauser.UpdateRigidbodies(transform, rbType, true, _graphicalObject);
}

//Create SetInterpolation smoother.
_ownerSetInterpolationSmoother = new SetInterpolationSmoother();
float teleportThreshold = (_enableTeleport) ? _ownerTeleportThreshold : MoveRatesCls.UNSET_VALUE;
SetInterpolationSmootherData osd = new SetInterpolationSmootherData()
if (_graphicalObject == null)
{
GraphicalObject = _graphicalObject,
Interpolation = _ownerInterpolation,
SmoothPosition = true,
SmoothRotation = true,
SmoothScale = true,
NetworkObject = this,
TeleportThreshold = teleportThreshold,
};
_ownerSetInterpolationSmoother.InitializeOnce(osd);

//Spectator.
_spectatorSetInterpolationSmoother = new SetInterpolationSmoother();
_spectatorSetInterpolationSmoother.InitializeOnce(osd);

//Create adaptive interpolation smoother if enabled.
if (_spectatorAdaptiveInterpolation)
Debug.Log($"GraphicalObject is null on {this.ToString()}. This may be intentional, and acceptable, if you are smoothing between ticks yourself. Otherwise consider assigning the GraphicalObject field.");
}
else
{
_spectatorAdaptiveInterpolationSmoother = new AdaptiveInterpolationSmoother();
//Smoothing values.
AdaptiveInterpolationSmoothingData aisd = GetAdaptiveSmoothingData(_adaptiveSmoothingType);
//Other details.
aisd.GraphicalObject = _graphicalObject;
aisd.SmoothPosition = true;
aisd.SmoothRotation = true;
aisd.SmoothScale = true;
aisd.NetworkObject = this;
aisd.TeleportThreshold = teleportThreshold;
_spectatorAdaptiveInterpolationSmoother.Initialize(aisd);
//Create SetInterpolation smoother.
_ownerSetInterpolationSmoother = new SetInterpolationSmoother();
float teleportThreshold = (_enableTeleport) ? _ownerTeleportThreshold : MoveRatesCls.UNSET_VALUE;
SetInterpolationSmootherData osd = new SetInterpolationSmootherData()
{
GraphicalObject = _graphicalObject,
Interpolation = _ownerInterpolation,
SmoothPosition = true,
SmoothRotation = true,
SmoothScale = true,
NetworkObject = this,
TeleportThreshold = teleportThreshold,
};
_ownerSetInterpolationSmoother.InitializeOnce(osd);

//Spectator.
_spectatorSetInterpolationSmoother = new SetInterpolationSmoother();
_spectatorSetInterpolationSmoother.InitializeOnce(osd);

//Create adaptive interpolation smoother if enabled.
if (_spectatorAdaptiveInterpolation)
{
_spectatorAdaptiveInterpolationSmoother = new AdaptiveInterpolationSmoother();
//Smoothing values.
AdaptiveInterpolationSmoothingData aisd = GetAdaptiveSmoothingData(_adaptiveSmoothingType);
//Other details.
aisd.GraphicalObject = _graphicalObject;
aisd.SmoothPosition = true;
aisd.SmoothRotation = true;
aisd.SmoothScale = true;
aisd.NetworkObject = this;
aisd.TeleportThreshold = teleportThreshold;
_spectatorAdaptiveInterpolationSmoother.Initialize(aisd);
}
}
}

private void Prediction_Update()
{
if (!_enablePrediction)
return;
if (_graphicalObject == null)
return;

_ownerSetInterpolationSmoother.Update();
if (IsHostStarted)
Expand All @@ -165,6 +174,9 @@ private void Prediction_Update()

private void TimeManager_OnPreTick()
{
if (_graphicalObject == null)
return;

//Do not need to check use prediction because this method only fires if prediction is on for this object.
_ownerSetInterpolationSmoother.OnPreTick();
if (IsHostStarted)
Expand All @@ -174,6 +186,9 @@ private void TimeManager_OnPreTick()
}
private void TimeManager_OnPostTick()
{
if (_graphicalObject == null)
return;

//Do not need to check use prediction because this method only fires if prediction is on for this object.
_ownerSetInterpolationSmoother.OnPostTick();
if (IsHostStarted)
Expand Down Expand Up @@ -309,6 +324,9 @@ private void OnCollisionEnter(Collision collision)
/// </summary>
private void CollisionEntered(GameObject go)
{
if (_graphicalObject == null)
return;

_collisionStayedTick = TimeManager.LocalTick;
_localClientCollidedObjects.Add(go);
}
Expand All @@ -318,6 +336,8 @@ private void CollisionEntered(GameObject go)
/// </summary>
private void OnCollisionEnter2D(Collision2D collision)
{
if (_graphicalObject == null)
return;
if (!IsClientInitialized)
return;
if (_predictionType != PredictionType.Rigidbody2D)
Expand Down
Loading

0 comments on commit d780e80

Please sign in to comment.