Raised This Month: $51 Target: $400
 12% 

Solved Client index vs user id vs real player index


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
McSnaggit
Junior Member
Join Date: Feb 2019
Old 03-20-2019 , 09:12   Client index vs user id vs real player index
Reply With Quote #1

Hi all,

I'm busy with a plugin for armsrace that saves stats to the database. Every time a user connects I want to add him to the database if he doesn't exist. After that, or if he already existed, I want to get the player database ID so I can use that in the plugin to store other events, linked to that player, in the database.

What I do is create a global array named g_playerDatabaseIds[MAXPLAYERS + 1]. Each time a player connects I add the database ID value to that array, on the real player index. But what is that index exactly? I have looked at the available API but cannot wrap my head around it.

As I see it, there are 3 different ID's:

1. The player index (this is an incremented value as a new player connects?)
2. The client's user id. This can be achieved by using GetClientUserId(player index). Officially: "Retrieves a client's user id, which is an index incremented for every client that joins the server."
3. The real player index. This can be achieved by using GetClientOfUserId(client's user id). Officially: "Translates an userid index to the real player index."

How do these three values compare? It seems to me as if 1 and 2 are almost the same. They both increment when a new players joins. And what does the real player index mean? And can I store that in an array that is max 64+1 in size? Should I remove the player entry in that array upon disconnect?

Can you guys clarify this so I can make sure I understand what id to use. Because different functions seem to output different types of id's.

Thanks in advance!

Last edited by McSnaggit; 03-24-2019 at 11:55. Reason: Post Solved
McSnaggit is offline
lugui
Senior Member
Join Date: Feb 2016
Location: GetClientAbsOrigin();
Old 03-20-2019 , 09:55   Re: Client index vs user id vs real player index
Reply With Quote #2

In pratice, the only value that is useful to store is the SteamID. UserID or player index cn change every time the player connects.

if you want the steamid when the client connects, use:
public OnClientPutInServer(client)
{
char authid[64];
GetClientAuthString(client, authid, 64);
// do what you want with authid
}
lugui is offline
McSnaggit
Junior Member
Join Date: Feb 2019
Old 03-20-2019 , 10:03   Re: Client index vs user id vs real player index
Reply With Quote #3

Quote:
Originally Posted by lugui View Post
In pratice, the only value that is useful to store is the SteamID. UserID or player index cn change every time the player connects.

if you want the steamid when the client connects, use:
public OnClientPutInServer(client)
{
char authid[64];
GetClientAuthString(client, authid, 64);
// do what you want with authid
}
I do that too. But when inserting a new event like a kill, I need the user id in the database. To fasten things, I can then use the array on the player id to find out the database id.

So if player x with gameID 1 kills someone. I want to quickly find the database id by doing g_playerDatabaseIds[1]. Do you follow me?
McSnaggit is offline
DarkDeviL
SourceMod Moderator
Join Date: Apr 2012
Old 03-20-2019 , 10:18   Re: Client index vs user id vs real player index
Reply With Quote #4

Quote:
Originally Posted by lugui View Post
if you want the steamid when the client connects, use:
public OnClientPutInServer(client)
{
char authid[64];
GetClientAuthString(client, authid, 64);
// do what you want with authid
}
Shame with all the documentation that no one ever wants to follow...

When things are a boolean, we do actually check the boolean return value of commands, to ensure everything works as expected:

PHP Code:
char authid[64];
if (
GetClientAuthId(clientAuthId_Engineauthid64)) {
// do what you want with authid

Not doing so will cause unforeseen consequences...
__________________
Mostly known as "DarkDeviL".

Dropbox FastDL: Public folder will no longer work after March 15, 2017!
For more info, see the [SRCDS Thread], or the [HLDS Thread].
DarkDeviL is offline
lugui
Senior Member
Join Date: Feb 2016
Location: GetClientAbsOrigin();
Old 03-20-2019 , 10:28   Re: Client index vs user id vs real player index
Reply With Quote #5

Quote:
Originally Posted by McSnaggit View Post
So if player x with gameID 1 kills someone. I want to quickly find the database id by doing g_playerDatabaseIds[1]. Do you follow me?
It will work for as long aa no player disconects from your server.
User the steamID to identify it

UPDATE logs SET(kill = 'blabla') WHERE steamid = STEAMID_HERE
lugui is offline
Mitchell
~lick~
Join Date: Mar 2010
Old 03-20-2019 , 11:01   Re: Client index vs user id vs real player index
Reply With Quote #6

Quote:
Originally Posted by DarkDeviL View Post
Shame with all the documentation that no one ever wants to follow...

When things are a boolean, we do actually check the boolean return value of commands, to ensure everything works as expected:

PHP Code:
char authid[64];
if (
GetClientAuthId(clientAuthId_Engineauthid64)) {
// do what you want with authid

Not doing so will cause unforeseen consequences...
Curious though, is this technically just doing an IsClientAuthorized check before filling the string buffer? Also does OnClientPostAdminCheck and OnClientAuthorized fire later after the client's connection when their steamid becomes resolved right?

Also OP,
1 and 3 in your list are the same index.
Basically this by uniqueness
1. SteamId/Account id etc, unique per client even after reconnect a week later etc.
2. IP semi unique per client, vpns/providers etc can change the outcome for a user's connection. Mainly only used to check if a client is connecting to a server using an alternative account, should only be taken with a grain of salt as often people like to use vpns and there is a chance two random people can connect to the same vpn server making this info kind of unreliable.
3. UserId, When the client first connects to the server they will be given a userId, userIds will stick after map change etc and will not be reused until it gets to a certain high value then restarts at 1 or 2 etc. Used to have a low value to reference a player during a connection, usually used while stored in arraylists, stringmaps, or used in callbacks like timers which the player could disconnect in the middle of the timer/callback.
4. Client index. Usually best seen as a reference to what slot they are taking while playing in the server, 0 being console, 1-MAXPLAYERS being connectable clients. These are reused, i.e. a player could disconnect and a different person can reconnect and take their client index. Unsafe to use in anything that's not synchronized, theoretically all it would take is a couple frame for a player to disconnect and a new one to connect taking their spot and confusing your code and targeting the wrong person.

Usually if you're storing anything within a data structure you'll want to use what's best fit for your purpose. You don't want to use UserIds for variables that you wouldn't really care about after disconnect etc.
However there are still cases that you'd want to store userIds instead of a client index because you want to be prepared for any scenario of a disconnected player. For an example, OnClientDisconnect(int client) fires for all clients within OnMapEnd(), but player_disconnect event fires when the player actually leaves the server, and provides the userId.

Last edited by Mitchell; 03-20-2019 at 11:22.
Mitchell is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 03-20-2019 , 16:47   Re: Client index vs user id vs real player index
Reply With Quote #7

McSnaggit, I would do like that:

PHP Code:
#include <sourcemod>

char g_sSteamId[MAXPLAYERS+1][64];

public 
void OnClientAuthorized(int client, const char[] auth)
{
    if (!
StrEqual(auth"BOT")) {
        
strcopy(g_sSteamId[client], sizeof(g_sSteamId[]), auth); // AuthId_Steam2
        
        // database check etc.
    
}

Everytime you need to access DB, you get cached SteamId from g_sSteamId array for performance reasons and use it as a key field of statistics table.

As about ClientId and UserId.
Whenever you need to pass ClientId to a timer function as an argument, make a reference (GetClientUserId) instead. And convert vice versa in the timer callback (GetClientOfUserId), than check it for valid. Because, before the timer actually trigger, engine has a time to replace ClientId by another client (one player disconnected, another player took his place). Reference has a minimal chance to point you to wrong ClientId.
The same with entities.
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]
Dragokas is offline
McSnaggit
Junior Member
Join Date: Feb 2019
Old 03-21-2019 , 09:33   Re: Client index vs user id vs real player index
Reply With Quote #8

Thank you all for replying!

@Mitchell, thanks for clarifying the different ids. I had no idea that 1 and 3 are the same. That explains a lot.

@Dragokas, that sounds logical. The "problem" is that I have a lot of foreign keys in my db. So my players table has an id and steamid etc. In my event database I link to the playerid (not steamid), so I want to store my player ids from the database in an array so I can quickly insert the player id's.

Therefore I need to use an array with the client id. So what you are saying is that I should reference to the clientuserid (that is an id that lives after disconnects etc.) and then convert it back when I need it for an array like g_array[client]?

That seems logical to me! I will use that.

PS: My script works fine as is, but I want to prevent any troubles with inserting data as it can get complicated later on!

Thanks everyone!
McSnaggit is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 03-21-2019 , 12:52   Re: Client index vs user id vs real player index
Reply With Quote #9

Quote:
Therefore I need to use an array with the client id. So what you are saying is that I should reference to the clientuserid (that is an id that lives after disconnects etc.) and then convert it back when I need it for an array like g_array[client]?
Since you have that array always updated, you can reference to it whenever you need to get Client -> SteamId binding.

Quote:
So my players table has an id and steamid etc. In my event database I link to the playerid (not steamid), so I want to store my player ids from the database in an array so I can quickly insert the player id's.
UserId is only valid until player disconnect. Next time it will have another UserId.

Personally, I think it's a bad idea to store UserId in database.
long story, or bad style


How it should be:
You are using global g_sSteamId array (described in #7) to bind Client -> SteamId to write info to DB.
You are using cycle (or arralylist or adt array) to bind SteamId -> Client after retreiving info from DB by "SteamId" unique key field.

Simplest example (get ClientId by SteamId):
PHP Code:
int GetClientOfSteamId(char[] SteamId)
{
    for (
int i 1<= MaxClientsi++)
        if (
g_sSteamId[i][0] != '\0' && StrEqual(g_sSteamId[i], SteamIdfalse))
            return 
i;
    return 
0;

For best performace you need to remove items from that array in player_disconnect (EventHookMode_Pre) event (or use ArrayList / StringMap to store such binding)

P.S. I am not professional in DB building or such kind of architecture, so maybe somebody else have better suggestions.
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]
Dragokas is offline
McSnaggit
Junior Member
Join Date: Feb 2019
Old 03-22-2019 , 05:23   Re: Client index vs user id vs real player index
Reply With Quote #10

I might not have been clear enough about the user ids (all these different terms right).

Database
In my database when I create a new player with a steamId, that player gets an autoincremented ID. That id is needed to use as foreign keys in other tables.

Game
When a player connects I check the steamId and then link the player Database ID to the g_playerDatabaseId array, so I don't need to store the steamId as a string. When a player disconnects, I remove that instance in the array again.

I do appreciate your help because now I know better how to deal with userId's and clientId's in arrays!

Thanks.
McSnaggit is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 19:12.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode