[C#] Get all players ID / Server side

Hello,
is there a way to get all the players ID connected to the server?
I need this because if I try to kick an ID that doesn’t exist my plugin will crash and stop to work…

Or I must implement a list to take note of the IDs on connect and disconnect?

There’s a PlayerList class. It contains all players connected to the server. I don’t know exactly how to get the server ID (maybe it’s a property) but, you can do something like the following:

PlayerList pl = new PlayerList();
foreach(Player player in pl){

}

Edit: If not, you can probably just loop through the player indices using this native

player.Handle


1 Like

I tried to use this before , defined this list:

PlayerList pl = new PlayerList();

and next if I try to use the list like this:

             for (int i = 0; i < pl.Count(); i++)
            {
                Debug.WriteLine(pl[i].Name);
            }

I get this error:

Error invoking callback for event chatMessage: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object
  at CitizenFX.Core.ScriptContext.GetResult (System.Type type, System.Byte[] ptr) [0x00028] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\ScriptContext.cs:112
  at CitizenFX.Core.ScriptContext.GetResult (System.Type type) [0x00000] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\ScriptContext.cs:101
  at CitizenFX.Core.Native.Function.InvokeInternal (CitizenFX.Core.Native.Hash nativeHash, System.Type returnType, CitizenFX.Core.Native.InputArgument[] args) [0x00044] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\Native.cs:32
  at CitizenFX.Core.Native.Function.Call[T] (CitizenFX.Core.Native.Hash hash, CitizenFX.Core.Native.InputArgument[] arguments) [0x00000] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\Native.cs:11
  at CitizenFX.Core.Player.get_Name () [0x00000] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\Server\ServerWrappers.cs:27
  at BasicResourceServer.BasicResourceServer.PlayerHaScrittoInChat (CitizenFX.Core.Player player, System.Int32 playerId, System.String playerName, System.String chatMessage) [0x0004a] in <700d470812044042a361626c2b47d2bb>:0
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <0123fd5b1a1040fe9d70a7e0d4b28acb>:0
   --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00048] in <0123fd5b1a1040fe9d70a7e0d4b28acb>:0
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <0123fd5b1a1040fe9d70a7e0d4b28acb>:0
  at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x000e7] in <0123fd5b1a1040fe9d70a7e0d4b28acb>:0
  at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00008] in <0123fd5b1a1040fe9d70a7e0d4b28acb>:0
  at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] in <0123fd5b1a1040fe9d70a7e0d4b28acb>:0
  at CitizenFX.Core.EventHandlerEntry+<Invoke>d__5.MoveNext () [0x00064] in C:\gl\builds\4ff63adb\0\cfx\fivem\code\client\clrcore\EventHandlerDictionary.cs:85

This Native (int GET_NUM_PLAYER_INDICES(); ) you suggested return an int (not a list of int), I suppost the number of total indices connected right? Not the single number value of all ID (or I’m wrong?)

Yes, you would use this instead of PlayerList#Count (which, I don’t even think exists).

But in this case if there are 2 indices, but they are number 10 and number 7 , they can lead to the same error right? When you try to call an ID that doesn’t exist (because when you connect many times the ID is not progressive).
GET_NUM_PLAYER_INDICES(); will give me the int = 2 right (2 ID)? But the ID 0 and 1 doesn’t exist and I will never know that the ID are 10 and 7.

i don’t know your specific needs but in most of case you send the serverId from any client to the server and then you don’t need to look for it.

anyway if you need to check if any unknow ID is associated to any player on server side you just can do a loop as you did but first you have to check your result before doing .name on it .

just do : Player p = playerList[i]; if(p != null) { Debug.WriteLine(p.name)}

ps: when you use the ‘count’ in a loop don’t forget to apply minus 1 on it or you will indexOutOfRange everytime

I need this code for this, to kick a player by an ID, but if the ID doesn’t exist the plugin will crash :

Player p = playerList[i]; 

if(p != null) { 
 API.DropPlayer(i,  "kicked");
}

But also in this case I continue to have this error :(, if the ID exist no error.

maybe try to add more verification , like if(p != null && p.exist() )

if you get trouble finding the id you could use the identifier instead ,sometime it’s more easier for people ^^

i wonder if you try exactly what i typed
if yeah normal you got error , i just type the idea but you have to write like that :

PlayerList pl = new PlayerList();
for(int i =0;i<pl.Count -1;i++){
  if(pl[i] != null){ Debug.WriteLine(pl[i].name);}
}
PlayerList pl = new PlayerList();
for(int i =0;i<pl.Count -1;i++){
  if(pl[i] != null){ Debug.WriteLine(pl[i].name);}
}

I did like you wrote now but 1 thing :smiley: , -1 is used when you have <= because you start from 0 to max but if you have < you start from 0 to max-1 already , soo you don’t need it :).

Anyway it’s hard to find a solution :D. And the problem is if I use a custom list, when the ID change I will not know the corrispondence from the old ID to the new one, soo I can’t use this way “playerspawn” “playerdrop” client side and update it by myself (the custom list)…

so you should use the identifier if you need to get back the same player info when he disconnect and reconnect , the identifier will never change instead of the ID

I will for the information like jobs bank etc… but I think for kick and other action I can only use the ID right?
I was tring to use a trigger request :

TriggerClientEvent(“GiveMeYourID”);

So if I try to kick an ID I request to all the client connected to the server the ID, and if exist I will kick him, but there is only one problem… how can I say after the TriggerClientEvent to wait some seconds? Because there is a delay and I can’t get in time the ID list … I never used async method and I don’t know how to use after this trigger XD. The trigger work but I don’t know how to say wait until you get the list , or wait for some seconds.

UPDATE

I did something like that :

        public async Task OnTick()
        {

            await Delay(5000);
            listaIdPlayer.Clear();
            TriggerClientEvent("GiveMeYourID");  
        }

Seems to work… thx you all guys :)!

Now I’ll try to get the identifier also to store permission and role :D!

I’ll try to redo my zombie mod for FIVEM + some roleplay :D!

1 Like

you have posted this mod?