.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Bot Coding (http://forums.bots-united.com/forumdisplay.php?f=24)
-   -   limiting humans (http://forums.bots-united.com/showthread.php?t=202)

Austin 04-01-2004 20:45

limiting humans
 
I am using this code to count the number of players + bots on the server
// -----------------------------------------------------------------------
for (client_index = 1; client_index <= gpGlobals->maxClients; client_index++)
{
pPlayer = INDEXENT(client_index);

// skip invalid players
if( FNullEnt(pPlayer) || pPlayer->free || !(pPlayer->v.flags & (FL_CLIENT | FL_FAKECLIENT)))
continue;

if(pPlayer->v.flags & FL_FAKECLIENT)
nbots++;
else
nhumans++;
}


I am using this code to limit the number of humans on the server
// -----------------------------------------------------------------------
BOOL ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128])
{
// is max humans are on
if(nhumans >= (int)CVAR_GET_FLOAT("maxhumans"))
{
// don't allow this human to connect
sprintf (szRejectReason, MESSAGE_REFUSE_CLIENTCONNECT);
RETURN_META_VALUE (MRES_SUPERCEDE, false);
}

RETURN_META_VALUE(MRES_IGNORED, true);
}

Everything works fine except when more then 1 human tries to connect to the server a the same time. This method allows more then maxhumans on since it doesn't take into account players who are in the process of connecting, and not yet flagged as a valid player.

So for example, if maxhumans is set to 5 and there are 4 humans on the server and nhumans is 4 and 2 humans try to connect within a few seconds of each other BOTH will be allowed on.

Does anyone have a clean solution for this?

P.S.
How do I post code examples without it removing my tabs/spaces in front of every line?
Tx

stefanhendriks 04-01-2004 20:57

Re: limiting humans
 
Code:

This is code
 
void main()
{
  hello world();
}

i use the code tags?

about your problem, perhaps you can try to intercept a message where the client tries to connect first (so it is NOT yet connected).

Even when this is not possible, you can always check every frame for the latest connected clients and kick the latest one.

So, you keep an own list of pEdicts , you can have a flag for HUMAN/BOT and also a TIME (fTimeConnected). This way you can simply check each frame if you have more then MAXHUMANS set. When to many humans connected anyway, you can kick them with a reason: Too many humans present..

Rick 04-01-2004 21:03

Re: limiting humans
 
hmm you could check in your playercount function if there are to much players and if so kick them there
[edit]
stefan was faster then me :(
[/edit]

Austin 04-01-2004 22:37

Re: limiting humans
 
Quote:

Originally Posted by stefanhendriks
Even when this is not possible, you can always check every frame for the latest connected clients and kick the latest one.

I was hoping for a non-kludgy way but alas it IS HL programming...
And I was hoping to KEEP them from connecting, instead of kicking them after they connect.

Do you know where the time connected is stored?
Tx.

Rick 04-01-2004 23:42

Re: limiting humans
 
hmm for the time... I think you have to manage that by yourself;
Code:

// in ClientConnect()
int EntInd = ENTINDEX(pEntity);
ClientInfo[EntInd-1].JoinTime = gpGlobals->time;

or something like that....

Edit: Yay now im earlier the stefan :)

stefanhendriks 04-01-2004 23:42

Re: limiting humans
 
well, i don't know of any in-side-hl variables which hold track of that. Therefor i suggest you keep your own list:

Code:

// somewhere in a header file.
 
// Player information
typedef struct
{
 edict_t *pEdict; // edict
 bool bIsBot; // is this edict a bot?
 float fConnectedTime;
} tPlayer;
 
// somewhere in dll.cpp
tPlayer Players[32]; // players
 
// somewhere in GameDLLInit()
int i=0;
for (i; i < 32; i++)
{
 Players[i].pEdict=NULL;
 Players[i].bIsBot=false;
 Players[i].fConnectedTime=0.0;
}
 
// Somewhere in clientconnect
// etc etc.. find the client, attach the information

hope it helps, pretty tired. :)

botmeister 04-01-2004 23:45

Re: limiting humans
 
There is no non-kludgy way of limiting human connections. The method using ClientConnect is messy because you cannot give the connecting player a reason why their connection failed. The MESSAGE_REFUSE_CLIENTCONNECT does not get displayed in the refusal popup window, and the player is left thinking that there's something wrong with your server.

Quote:

So for example, if maxhumans is set to 5 and there are 4 humans on the server and nhumans is 4 and 2 humans try to connect within a few seconds of each other BOTH will be allowed on.


Change your code so it checks how many humans are in the game during the connection attempt and refuse the connection if the count will be exceeded. I see you may not be doing this, and instead periodically updating a global count (nhumans) which is not in sync with the connection attempts. If you replace nhumans to a function call that counts humans on the fly, your code should work fine.


Austin 05-01-2004 02:58

Re: limiting humans
 
Quote:

Originally Posted by botmeister
MESSAGE_REFUSE_CLIENTCONNECT does not get displayed in the refusal popup window, and the player is left thinking that there's something wrong with your server.

Yes, but it does at least get displayed and you can see it for a few seconds on the screen right after you are disconnected. So this is better then nothing.

Quote:

Originally Posted by botmeister
Change your code so it checks how many humans are in the game during the connection attempt and refuse the connection if the count will be exceeded.

I actually do this. The code I posted was simplified. I call a function that counts the number of bots and humans on the server right before I do the check.

The problem is still as described.

In ClientConnect() If more then 1 human tries to connect within a few seconds of each other, they can exceed the allowed maxhumans, because the code that counts the players doesn't take into consideration players who are in the process of connecting but not actually in the game yet.

I guess I could start to kludge it by keeping track of who is connecting over the last several seconds and then watch who actually gets put into the server and track and check all this every few seconds, exactly what I didn't want to do.

As far as the time on the server, HL must keep it somewhere for each player since it is shown for each player in the server tool HLSW (time on for each player is returned by the server "Infostring" command)

Pierre-Marie Baty 05-01-2004 04:31

Re: limiting humans
 
You could define a time window after which you decide a client who tried to connect through ClientConnect() and who has not yet reached the ClientPutInServer() step is a client who has cancelled connecting, and thus you could move your player count to ClientConnect() instead. It's not a perfect method, but it's better than nothing...

botmeister 05-01-2004 09:01

Re: limiting humans
 
Quote:

Yes, but it does at least get displayed and you can see it for a few seconds on the screen right after you are disconnected. So this is better then nothing.
I guess you're still using CS 1.5. It's a lot worse in CS 1.6 because you don't see any of the connection messages like you do in CS 1.5.

Quote:

I actually do this. The code I posted was simplified. I call a function that counts the number of bots and humans on the server right before I do the check.

The problem is still as described.

In ClientConnect() If more then 1 human tries to connect within a few seconds of each other, they can exceed the allowed maxhumans, because the code that counts the players doesn't take into consideration players who are in the process of connecting but not actually in the game yet.
Yes, you are indeed correct, here's why

Assume MaxHumans = 5 AND there are 4 humans in the game.

If a human tries to connect, ClientConnect() will get called, and the count will return 4 humans in game allowing the player to connect as the 5th human. If another human tries to connect before the first one becomes "valid" and counted, then this human will be allowed in as the 6th human.

The real problem here is that there is no corresponding ClientDisconnect() function to hook onto when a connection attempt is refused. Only Valve can solve this one, so you're left with doing silly coding to solve the problem.

I think the best "solution" is to leave your existing code in place but to also kick out extra humans as soon as they can be detected. Most of the time people will be refused at ClientConnect(), and only the few who slip through the first check will get kicked. These guys can still get a console message informing them why they were kicked just as they do with the refusal.

Austin 05-01-2004 20:20

Re: limiting humans
 
Quote:

Originally Posted by botmeister
I guess you're still using CS 1.5. It's a lot worse in CS 1.6

Oh, thanks, I am still on 1.5. I guess I need to specify 1.5 or 1.6 in all post from now on.
I think I will wait about 1 year for the 1.6 "Beta" to be over...
I am SERIOUS.

Quote:

Originally Posted by botmeister
If a human tries to connect, ClientConnect() will get called, and the count will return 4 humans in game allowing the player to connect as the 5th human. If another human tries to connect before the first one becomes "valid" and counted, then this human will be allowed in as the 6th human.

EXACTLY, what I was trying to describe in my first post.

Quote:

Originally Posted by botmeister
so you're left with doing silly coding to solve the problem.

Exactly why I was posting this question. I have already consider / tested / and tried out most of what was mentioned here before posting, HOPING I would not have to kludge it like this..

What I have settled on trying last is tracking the clients in client connect and setting a certain amount of time for them to connect. I then will use the number of humans on now + number connecting to determine if they will be allowed on. I don't like kicking people it tends to anger most people. But I am still going to do this as a double check to keep the limit what I want.

Quote:

Originally Posted by botmeister
These guys can still get a console message informing them why they were kicked just as they do with the refusal.

All I know about is sending the clients a message on their screen. Do you have an example of how I would send a console message to a specific client before kicking them?

Thanks everyone for the help.
I will post the source to this plug in when finished.

botmeister 07-01-2004 06:26

Re: limiting humans
 
Quote:

Originally Posted by Austin
Do you have an example of how I would send a console message to a specific client before kicking them?

Use the engine function

pfnClientPrintf( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg );

for ptype pass the enumerated type constant "print_console"

Eaxmple
pfnClientPrintf( edict_of_player_to_kick, print_console, "you have been kicked" );

In CS 1.5 they will see the message in their console after being kicked.


All times are GMT +2. The time now is 15:20.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.