Previous PlayerIDs of Dedicated Server are staying in Player.PlayersIds after round restart
Lufou opened this issue · 2 comments
I made the tests only for Player.PlayersIds
but I think it works the same with Player.PlayersUserIds
(not sure for this one).
But anyway, Player.PlayersIds
dict is not correctly cleared when the round is restarting. This leads to error when TryGetting an IGameComponent from PlayerID, for instance, PlayerID 10 is assigned to the player, if the PlayerID 10 is already in the PlayersIds dict, it's not added in the dict because of the condition :
if (!Player.PlayersIds.ContainsKey(this.PlayerId))
{
Player.PlayersIds.Add(this.PlayerId, this.ReferenceHub);
}
So this leads to problems when trying to TryGet an IGameComponent from a playerID from this dictinary, because it's pointing to destroyed RHubs. (used in the Player.Get(int playerId)
method)
Example of the dictionary not cleaning properly:
[2023-01-17 11:34:17.200 +01:00] [Warning] Round #1 -> PlayersId #1 -> Server: False
[2023-01-17 11:34:17.212 +01:00] [Warning] Round #1 -> PlayersId #2 -> Server: True
Both rounds were started only with the Dedicated Server, on the second round dedi was pid 2 and on the first round it was pid 1.
I want to precise that PlayersIds only keep previous Dedicated Server PID meaning that OnInternalDestroy()
(which should remove the PID from the dictionary) is not called for the Dedicated Server
The error when you TryGet from this dict a PID of a player who's currently on the server but where the PID was previously assigned to Dedicated Server and so, still in the PlayersIds dict:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException
at (wrapper managed-to-native) UnityEngine.Component.get_gameObject(UnityEngine.Component)
at ReferenceHub.GetHashCode () [0x00000] in <114aeb735cee4e8082cd0686c54991e8>:0
at System.Collections.Generic.ObjectEqualityComparer`1[T].GetHashCode (T obj) [0x0000a] in <9577ac7a62ef43179789031239ba8798>:0
at System.Collections.Generic.Dictionary`2[TKey,TValue].FindEntry (TKey key) [0x0001b] in <9577ac7a62ef43179789031239ba8798>:0
at System.Collections.Generic.Dictionary`2[TKey,TValue].TryGetValue (TKey key, TValuevalue) [0x00000] in <9577ac7a62ef43179789031239ba8798>:0
at PluginAPI.Core.Factories.Factory`1[T].GetOrAdd (PluginAPI.Core.Interfaces.IGameComponent component) [0x00000] in <4c2a3c9f04a54612acd3e9a88faf0eba>:0
at PluginAPI.Core.Player.TryGet[T] (PluginAPI.Core.Interfaces.IGameComponent component, Tplayer) [0x00039] in <4c2a3c9f04a54612acd3e9a88faf0eba>:0
at PluginAPI.Core.Player.TryGet[T] (System.Int32 playerId, Tplayer) [0x00018] in <4c2a3c9f04a54612acd3e9a88faf0eba>:0
at PluginAPI.Core.Player.TryGet (System.Int32 playerId, PluginAPI.Core.Playerplayer) [0x00000] in
I confirm that the root of the issue is that Player.OnInternalDestroy()
is not called for the Dedicated Server.