Skip to content

Commit ae81b59

Browse files
author
FirstGearGames
committed
4.6.15
- Fixed TargetRpc sending as ObserverRpc when using multiple Rpc type attributes on a single method (#958). - Fixed SceneManager Additive Scenes Demo sometimes not moving the clientHost player. - Fixed PredictionManager reconcile throttle unintentionally dropping reconciles. - Fixed SceneManager initial scene loads not properly handling client load responses. - Fixed NetworkObject not initializing when the prefab failed to serialize, and when set under a parent already initialized during spawning (#953). - Fixed clientHost player sometimes not spawning due to incorrect parsing of connection payload. - Fixed SyncType collection memory leak (#977). - Fixed an instance of StatisticsManager improperly initializing NetworkTrafficStatistics (#978). - Changed put a MAXIMUM_CACHE_COUNT of 50 on caches. - Improved client Kicked message now provides stacktrace during invalid packet parsing.
1 parent 1d17590 commit ae81b59

File tree

13 files changed

+177
-152
lines changed

13 files changed

+177
-152
lines changed

Assets/FishNet/CodeGenerating/Processing/Rpc/RpcProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ private string GetRpcMethodName(CreatedRpc cr)
160160
/// </summary>
161161
private string GetRpcMethodName(RpcType rpcType, MethodDefinition originalMd)
162162
{
163-
return $"{GetMethodNameAsParameters(originalMd)}";
163+
return $"{rpcType.ToString()}_{GetMethodNameAsParameters(originalMd)}";
164164
}
165165

166166
/// <summary>

Assets/FishNet/Demos/SceneManager/Additive Scenes/Scripts/Player.cs

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,18 @@ public class Player : NetworkBehaviour
1616
private int _goalIndex;
1717
private Vector3 _goalOffset;
1818

19-
public override void OnStartServer()
20-
{
21-
_wayPoints = FindObjectsOfType<Waypoint>().ToList();
22-
/* Stagger spawn position slightly depending on player count.
23-
* Also inverse direction so players cross each other when more
24-
* than one. This is just demo fanciness. */
25-
if (ServerManager.Clients.Count % 2 == 0)
26-
{
27-
_goalOffset = new(-0.5f, 0f, 0f);
28-
_wayPoints = _wayPoints.OrderBy(x => x.WaypointIndex).ToList();
29-
}
30-
else
31-
{
32-
_goalOffset = new(0.5f, 0f, 0f);
33-
_wayPoints = _wayPoints.OrderByDescending(x => x.WaypointIndex).ToList();
34-
}
3519

36-
// Snap to current waypoint.
37-
transform.position = _wayPoints[0].transform.position + _goalOffset;
38-
// Set goal to next waypoint.
39-
_goalIndex = 1;
40-
}
20+
private bool _foundWaypoints;
4121

4222
public override void OnOwnershipClient(NetworkConnection prevOwner)
4323
{
4424
_ownerObjects.gameObject.SetActive(IsOwner);
4525
}
4626

27+
4728
private void Update()
4829
{
49-
// Not server or not setup.
50-
if (!IsServerStarted)
51-
return;
52-
if (_wayPoints.Count == 0)
53-
return;
54-
if (_goalIndex >= _wayPoints.Count)
30+
if (!TryFindWaypoints())
5531
return;
5632

5733
Vector3 posGoal = _wayPoints[_goalIndex].transform.position + _goalOffset;
@@ -74,5 +50,44 @@ private void Update()
7450
_goalIndex = 0;
7551
}
7652
}
53+
54+
55+
private bool TryFindWaypoints()
56+
{
57+
if (_foundWaypoints)
58+
return true;
59+
//Only the server uses waypoints.
60+
if (!IsServerStarted)
61+
return false;
62+
63+
_wayPoints = FindObjectsOfType<Waypoint>().ToList();
64+
/* There are expected 4 waypoints in this test -- if only
65+
* one is found then the other scenes did not load yet. */
66+
if (_wayPoints.Count != 4)
67+
return false;
68+
69+
/* Stagger spawn position slightly depending on player count.
70+
* Also inverse direction so players cross each other when more
71+
* than one. This is just demo fanciness. */
72+
if (ServerManager.Clients.Count % 2 == 0)
73+
{
74+
_goalOffset = new(-0.5f, 0f, 0f);
75+
_wayPoints = _wayPoints.OrderBy(x => x.WaypointIndex).ToList();
76+
}
77+
else
78+
{
79+
_goalOffset = new(0.5f, 0f, 0f);
80+
_wayPoints = _wayPoints.OrderByDescending(x => x.WaypointIndex).ToList();
81+
}
82+
83+
// Snap to current waypoint.
84+
transform.position = _wayPoints[0].transform.position + _goalOffset;
85+
// Set goal to next waypoint.
86+
_goalIndex = 1;
87+
88+
_foundWaypoints = true;
89+
90+
return true;
91+
}
7792
}
7893
}

Assets/FishNet/Runtime/Managing/Client/ClientManager.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,8 +639,9 @@ private void ParseAuthenticated(PooledReader reader)
639639
{
640640
/* If host then just read Ids, but do not
641641
* enqueue as server side already did so. */
642+
int id = reader.ReadNetworkObjectId();
642643
if (!isServerStarted)
643-
q.Enqueue(reader.ReadNetworkObjectId());
644+
q.Enqueue(id);
644645
}
645646
}
646647

Assets/FishNet/Runtime/Managing/NetworkManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ internal void SetBroadcastName<T>(ushort key) where T : struct, IBroadcast
227227
/// <summary>
228228
/// Version of this release.
229229
/// </summary>
230-
public const string FISHNET_VERSION = "4.6.14";
230+
public const string FISHNET_VERSION = "4.6.15";
231231
/// <summary>
232232
/// Maximum framerate allowed.
233233
/// </summary>

Assets/FishNet/Runtime/Managing/Prediction/PredictionManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ bool ConditionsMet(StatePacket spChecked)
632632
uint serverTick = sp.ServerTick;
633633

634634
//Check to throttle reconciles.
635-
if (_reduceReconcilesWithFramerate && _clientReconcileThrottler.TryReconcile(_minimumClientReconcileFramerate))
635+
if (_reduceReconcilesWithFramerate && !_clientReconcileThrottler.TryReconcile(_minimumClientReconcileFramerate))
636636
dropReconcile = true;
637637

638638
if (!dropReconcile)

Assets/FishNet/Runtime/Managing/Scened/SceneManager.cs

Lines changed: 20 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,8 @@ internal void InitializeOnce_Internal(NetworkManager manager)
464464
{
465465
NetworkManager = manager;
466466
// No need to unregister since managers are on the same object.
467-
NetworkManager.ServerManager.OnRemoteConnectionState += ServerManager_OnRemoteConnectionState;
468-
NetworkManager.ServerManager.OnServerConnectionState += ServerManager_OnServerConnectionState;
467+
_serverManager.OnRemoteConnectionState += ServerManager_OnRemoteConnectionState;
468+
_serverManager.OnServerConnectionState += ServerManager_OnServerConnectionState;
469469
_clientManager.RegisterBroadcast<LoadScenesBroadcast>(OnServerLoadedScenes);
470470
_clientManager.RegisterBroadcast<UnloadScenesBroadcast>(OnServerUnloadedScenes);
471471
_serverManager.RegisterBroadcast<ClientScenesLoadedBroadcast>(OnClientLoadedScenes);
@@ -550,6 +550,17 @@ internal void OnClientAuthenticated(NetworkConnection connection)
550550
return;
551551
}
552552

553+
void SendEmptyBroadcast()
554+
{
555+
_pendingClientSceneLoads.AddClientToDefaultLoad(connection);
556+
/* Invoke that client had loaded the default scenes immediately,
557+
* since there are no scenes to load. */
558+
// OnClientLoadedScenes(connection, new ClientScenesLoadedBroadcast());
559+
// Tell the client there are no scenes to load.
560+
EmptyStartScenesBroadcast emptyMsg = new();
561+
connection.Broadcast(emptyMsg);
562+
}
563+
553564
//There is at least 1 global scene to send.
554565
SceneLoadData sld = new(sceneLookupData.ToArray());
555566
sld.Params = _globalSceneLoadData.Params;
@@ -564,18 +575,10 @@ internal void OnClientAuthenticated(NetworkConnection connection)
564575
QueueData = qd
565576
};
566577

567-
connection.Broadcast(msg, requireAuthenticated: true);
578+
foreach (SceneLookupData lookupData in sceneLookupData)
579+
_pendingClientSceneLoads.AddClientToScene(connection, lookupData.Handle);
568580

569-
void SendEmptyBroadcast()
570-
{
571-
_pendingClientSceneLoads.AddClientToDefaultLoad(connection);
572-
/* Invoke that client had loaded the default scenes immediately,
573-
* since there are no scenes to load. */
574-
// OnClientLoadedScenes(connection, new ClientScenesLoadedBroadcast());
575-
// Tell the client there are no scenes to load.
576-
EmptyStartScenesBroadcast emptyMsg = new();
577-
connection.Broadcast(emptyMsg);
578-
}
581+
connection.Broadcast(msg, requireAuthenticated: true);
579582
}
580583

581584
/// <summary>
@@ -690,7 +693,7 @@ private void OnClientLoadedScenes(NetworkConnection conn, ClientScenesLoadedBroa
690693
//Make sure the sceneId is pending.
691694
if (!_pendingClientSceneLoads.RemoveClientFromScene(conn, item.Handle, out _))
692695
{
693-
KickClient($"Sent a scene load response for handle [{item.Handle}], but client was not sent a load for this handle.");
696+
KickClient($"Client {conn.ToString()} sent a scene load response for handle [{item.Handle}], but client was not sent a load for this handle.");
694697
break;
695698
}
696699

@@ -704,7 +707,7 @@ private void OnClientLoadedScenes(NetworkConnection conn, ClientScenesLoadedBroa
704707

705708
void KickClient(string reason)
706709
{
707-
// conn.Kick(KickReason.ExploitAttempt, LoggingType.Common, $"{reason} Connection will be kicked immediately.");
710+
conn.Kick(KickReason.ExploitAttempt, LoggingType.Common, $"{reason} Connection will be kicked immediately.");
708711
}
709712
}
710713
#endregion
@@ -882,72 +885,6 @@ private string[] GlobalScenesExcludingLoading()
882885
}
883886
}
884887

885-
// #region IsQueuedScene.
886-
///// <summary>
887-
///// Returns if this SceneManager has a scene load or unload in queue for server or client.
888-
///// </summary>
889-
///// <param name="loading">True to check loading scenes, false to check unloading.</param>
890-
///// <param name="asServer">True to check if data in queue is for server, false if for client.
891-
///// <returns></returns>
892-
// public bool IsQueuedScene(string sceneName, bool loading, bool asServer)
893-
// {
894-
// _sceneLookupDataCache.Update(sceneName, 0);
895-
// return IsQueuedScene(_sceneLookupDataCache, loading, asServer);
896-
// }
897-
///// <summary>
898-
///// Returns if this SceneManager has a scene load or unload in queue for server or client.
899-
///// </summary>
900-
///// <param name="loading">True to check loading scenes, false to check unloading.</param>
901-
///// <param name="asServer">True to check if data in queue is for server, false if for client.
902-
///// <returns></returns>
903-
// public bool IsQueuedScene(int handle, bool loading, bool asServer)
904-
// {
905-
// _sceneLookupDataCache.Update(string.Empty, handle);
906-
// return IsQueuedScene(_sceneLookupDataCache, loading, asServer);
907-
// }
908-
///// <summary>
909-
///// Returns if this SceneManager has a scene load or unload in queue for server or client.
910-
///// </summary>
911-
///// <param name="loading">True to check loading scenes, false to check unloading.</param>
912-
///// <param name="asServer">True to check if data in queue is for server, false if for client.
913-
///// <returns></returns>
914-
// public bool IsQueuedScene(Scene scene, bool loading, bool asServer)
915-
// {
916-
// _sceneLookupDataCache.Update(scene.name, scene.handle);
917-
// return IsQueuedScene(_sceneLookupDataCache, loading, asServer);
918-
// }
919-
///// <summary>
920-
///// Returns if this SceneManager has a scene load or unload in queue for server or client.
921-
///// </summary>
922-
///// <param name="loading">True to check loading scenes, false to check unloading.</param>
923-
///// <param name="asServer">True to check if data in queue is for server, false if for client.
924-
///// <returns></returns>
925-
// public bool IsQueuedScene(SceneLookupData sld, bool loading, bool asServer)
926-
// {
927-
// foreach (object item in _queuedOperations)
928-
// {
929-
// SceneLookupData[] lookupDatas = null;
930-
// // Loading check.
931-
// if (loading && item is SceneLoadData loadData)
932-
// lookupDatas = loadData.SceneLookupDatas;
933-
// else if (!loading && item is SceneUnloadData unloadData)
934-
// lookupDatas = unloadData.SceneLookupDatas;
935-
936-
// if (lookupDatas != null)
937-
// {
938-
// foreach (SceneLookupData operationSld in lookupDatas)
939-
// {
940-
// if (operationSld == sld)
941-
// return true;
942-
// }
943-
// }
944-
// }
945-
946-
// // Fall through, not found in any queue operations.
947-
// return false;
948-
// }
949-
// #endregion
950-
951888
#region LoadScenes
952889
/// <summary>
953890
/// Loads scenes on the server and for all clients. Future clients will automatically load these scenes.
@@ -1544,9 +1481,9 @@ void SetInFirstNullIndex(Scene scene)
15441481
if (data.ScopeType == SceneScopeType.Global)
15451482
{
15461483
NetworkConnection[] conns = _serverManager.Clients.Values.ToArray();
1547-
1484+
15481485
AddClientPendingLoads(conns);
1549-
1486+
15501487
_serverManager.Broadcast(msg, requireAuthenticated: true);
15511488
}
15521489
// If connections scope then only send to connections.

Assets/FishNet/Runtime/Managing/Server/ServerManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ private void SendAuthenticated(NetworkConnection conn)
659659
writer.WriteNetworkConnection(conn);
660660
/* If predicted spawning is enabled then also send
661661
* reserved objectIds. */
662-
;
662+
663663
PredictionManager pm = NetworkManager.PredictionManager;
664664
if (GetAllowPredictedSpawning())
665665
{
@@ -862,7 +862,7 @@ private void ParseReceived(ServerReceivedDataArgs args)
862862
}
863863
catch (Exception e)
864864
{
865-
Kick(args.ConnectionId, KickReason.MalformedData, LoggingType.Error, $"Server encountered an error while parsing data for packetId {packetId} from connectionId {args.ConnectionId}. Connection will be kicked immediately. Message: {e.Message}.");
865+
Kick(args.ConnectionId, KickReason.MalformedData, LoggingType.Error, $"Server encountered an error while parsing data for packetId {packetId} from connectionId {args.ConnectionId}. Connection will be kicked immediately. Message: {e}.");
866866
}
867867
finally
868868
{

Assets/FishNet/Runtime/Managing/Statistic/NetworkTrafficStatistics.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ public bool UpdateServer
102102
/// Size suffixes as text.
103103
/// </summary>
104104
private static readonly string[] _sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
105+
/// <summary>
106+
/// True if initialized.
107+
/// </summary>
108+
private bool _initializedOnce;
105109
#endregion
106110

107111
#region Consts.
@@ -113,6 +117,9 @@ public bool UpdateServer
113117

114118
internal void InitializeOnce_Internal(NetworkManager manager)
115119
{
120+
if (_initializedOnce)
121+
return;
122+
116123
_networkManager = manager;
117124

118125
/* Do not bother caching once destroyed. Losing a single instance of each

Assets/FishNet/Runtime/Managing/Statistic/StatisticsManager.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ internal void InitializeOnce_Internal(NetworkManager manager)
3434
public bool TryGetNetworkTrafficStatistics(out NetworkTrafficStatistics statistics)
3535
{
3636
statistics = null;
37-
37+
3838
/* Cannot run in the current build type. */
3939
#if (!UNITY_EDITOR && !DEVELOPMENT_BUILD) || UNITY_SERVER
4040
if (!_runInRelease)
@@ -43,17 +43,16 @@ public bool TryGetNetworkTrafficStatistics(out NetworkTrafficStatistics statisti
4343
return false;
4444
}
4545
#endif
46-
46+
4747
//NetworkManager must be set to work.
4848
if (_networkManager == null)
4949
return false;
5050

51-
//Hotload if needed.
51+
//Hot-load if needed.
5252
if (_networkTraffic == null)
53-
{
5453
_networkTraffic = new();
55-
_networkTraffic.InitializeOnce_Internal(_networkManager);
56-
}
54+
55+
_networkTraffic.InitializeOnce_Internal(_networkManager);
5756

5857
if (_networkTraffic.IsEnabled())
5958
statistics = _networkTraffic;

Assets/FishNet/Runtime/Object/NetworkBehaviour/NetworkBehaviour.SyncTypes.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,17 @@ public void Initialize()
6060
/// <summary>
6161
/// SyncTypes within this NetworkBehaviour.
6262
/// </summary>
63-
private Dictionary<uint, SyncBase> _syncTypes = new();
63+
private Dictionary<uint, SyncBase> _syncTypes
64+
{
65+
get
66+
{
67+
if (_syncTypesCache == null)
68+
_syncTypesCache = CollectionCaches<uint, SyncBase>.RetrieveDictionary();
69+
70+
return _syncTypesCache;
71+
}
72+
}
73+
private Dictionary<uint, SyncBase> _syncTypesCache;
6474
/// <summary>
6575
/// True if at least one syncType is dirty.
6676
/// </summary>
@@ -92,8 +102,6 @@ public void Initialize()
92102
/// <param name = "index"></param>
93103
internal void RegisterSyncType(SyncBase sb, uint index)
94104
{
95-
if (_syncTypes == null)
96-
_syncTypes = CollectionCaches<uint, SyncBase>.RetrieveDictionary();
97105
if (!_syncTypes.TryAdd(index, sb))
98106
NetworkManager.LogError($"SyncType key {index} has already been added for {GetType().FullName} on {gameObject.name}");
99107
}
@@ -540,7 +548,7 @@ internal void ResetState_SyncTypes(bool asServer)
540548

541549
private void SyncTypes_OnDestroy()
542550
{
543-
CollectionCaches<uint, SyncBase>.StoreAndDefault(ref _syncTypes);
551+
CollectionCaches<uint, SyncBase>.StoreAndDefault(ref _syncTypesCache);
544552
}
545553
}
546554
}

0 commit comments

Comments
 (0)