.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   Half-Life 1 SDK (http://forums.bots-united.com/forumdisplay.php?f=33)
-   -   ClientDisconnect() is driving me NUTS!!! (http://forums.bots-united.com/showthread.php?t=152)

Pierre-Marie Baty 02-01-2004 19:03

ClientDisconnect() is driving me NUTS!!!
 
Okay, here's again one of the weirdest bugs ever - those who drive you mad for hours bunking your face on walls until it turns into an obnoxious red/grey mixture.

I use ClientDisconnect() in my bot code to keep track of bots and players disconnecting, in order to reset their structures and/or adapt the players and bot counts, and other stuff, etc, etc.

Here's a typical ClientDisconnect() function from one of my bot DLLs (in this case, it's a The Specialists version, but it's the same for the other MODs)
Code:

void ClientDisconnect (edict_t *pEntity)
{
  // this function is called whenever a client is VOLUNTARILY disconnected from the server,
  // either because the client dropped the connection, or because the server dropped him from
  // the game (latency timeout). The effect is the freeing of a client slot on the server. Note
  // that clients and bots disconnected because of a level change NOT NECESSARILY call this
  // function, because in case of a level change, it's a server shutdown, and not a normal
  // disconnection. I find that completely stupid, but that's it. Anyway it's time to update
  // the bots and players counts, and in case the client disconnecting is a bot, to back its
  // brain(s) up to disk. We also try to notice when a listenserver client disconnects, so as
  // to reset his entity pointer for safety. There are still a few server frames to go once a
  // listen server client disconnects, and we don't want to send him any sort of message then.
                printf ("RACC BOT DISCONNECTING\n");
  // only process bots if we are in multiplayer mode
  if (server.is_multiplayer && !DebugLevel.is_paused)
  {
          int player_index;
         
          player_index = ENTINDEX (pEntity) - 1; // get this player's index
          bots[player_index].is_active = FALSE; // mark this bot slot as free
          // was this client a bot ?
          if (players[player_index].is_racc_bot)
          {
                if (!FNullEnt (bots[player_index].pIllumination))
                        bots[player_index].pIllumination->v.flags |= FL_KILLME; // kill its light entity
                BotShutdownPathMachine (&bots[player_index]); // shutdown our bot's pathmachine
                BotNavSaveBrain (&bots[player_index]); // save our bot's nav brain
                BotHALSaveBrain (&bots[player_index]); // save our bot's HAL brain
                bot_count--; // decrement the bot count as we know this bot is disconnecting
          }
          memset (&players[player_index], 0, sizeof (players[player_index])); // reset his structure
          players[player_index].pEntity = NULL; // clear his entity pointer
          player_count--; // decrement the player count as we know this client is disconnected
  }
  (*other_gFunctionTable.pfnClientDisconnect) (pEntity);
}

....ah yes, because perhaps I never annoucned it yet, but the next release of my bot will probably support The Specialists :D

Now THE PROBLEM, is that, as the commenting says, ClientDisconnect() doesn't seem to be called each time someone is disconnected.

It looks like if you use the 'kick' command, ClientDisconnect() is not called. Neither is it on map changes (but NOT all cases, and THAT's the weirdest thing !!!)

I am completely puzzled. Is there a reason and eventually a fix to apply somewhere or do I need to move all the connecting/disconnecting stuff to the beginning of StartFrame ??? That would be more portable perhaps but since these functions are provided for this purpose it would be a shame not to use them.. ???:(

stefanhendriks 02-01-2004 19:33

Re: ClientDisconnect() is driving me NUTS!!!
 
perhaps you can somehow intercept the 'kick' and 'map' command. THen you force your own function being called to make sure your bot is kicked in your bot.dll as well.

Its an ugly hack, but it should work.

Lazy 02-01-2004 19:52

Re: ClientDisconnect() is driving me NUTS!!!
 
Just a thought - but maybe FreeEntPrivateData gets called on a disconnect.
I'd look into it but I'm eating a sandwich now.

Pierre-Marie Baty 03-01-2004 04:11

Re: ClientDisconnect() is driving me NUTS!!!
 
Nevermind...

I moved all my connect/disconnect stuff to StartFrame.

Took me a helluva time (especially when you try to get things working and a pesky dutchman keeps sending you rows of PMs for IRC every minute ;)), but I did it!!!!!

/me bows to avoid the flying dutchman :D

botmeister 03-01-2004 09:33

Re: ClientDisconnect() is driving me NUTS!!!
 
ClientDisconnect gets called only for players that actually spawned into the game, but I suppose you already know this. I use the same function call to test for disconnects, and as far as I know it works all the time.

stefanhendriks 03-01-2004 10:34

Re: ClientDisconnect() is driving me NUTS!!!
 
glad it works now pmb. I will try to send 2 pm's within a minute now instead of 1 ;)

Cheeseh 07-01-2004 17:57

Re: ClientDisconnect() is driving me NUTS!!!
 
I am also needing to store the amount of players. But I am in deeper crap because I want to store the amount of players trying to connect as well.

I need this so that my max bots command will work correctly.

What does the server use to get the amount of players when you use the "status" command??

Cheeseh 07-01-2004 18:16

Re: ClientDisconnect() is driving me NUTS!!!
 
btw PM, you can sort the problem you have by doing something like this if you want to get the number of clients playing.

getPlayerUserId will tell you if the player is in the server

but not if its joining, which is what I really need to know

:o hold on.. i think it returns 0 when a player is not in the server, maybe its -1 if connecting.. gonna check.
Code:

int UTIL_GetNumClients ( void )
{
        int i = 0;

        edict_t *pPlayer;
        int iNum;

        iNum = 0;

        for ( i = 1; i <= gpGlobals->maxClients; i ++ )
        {
                pPlayer = INDEXENT(i);

                if ( pPlayer == NULL )
                        continue;
                if ( pPlayer->free )
                        continue;

                if ( (*g_engfuncs.pfnGetPlayerUserId)(pPlayer) > 0 )
                                iNum++;
        }

        return iNum;
}


Pierre-Marie Baty 07-01-2004 18:28

Re: ClientDisconnect() is driving me NUTS!!!
 
All I can say, is that as soon as the engine is notified that a new player tries to connect, it calls ClientConnect() in the game DLL ; and in the case where the connection established successfully, when the new player finished downloading all the resources and stuff, then the engine allows the new player in game and immediately calls ClientPutInServer() in the game DLL.

Unfortunately if the equivalent to ClientPutInServer() is ClientDisconnect(), there is no equivalent for ClientConnect() and thus you can't know if a user who attempted to connect has been dropped by the server or cancelled the connection himself. You're left to put timeouts yourself for each of your players in ClientConnect(), and inhibite these timeouts once ClientPutInServer() has been called for them.

Cheeseh 07-01-2004 18:40

Re: ClientDisconnect() is driving me NUTS!!!
 
Although I don't think the time outs will work if a player is still downloading resources or maps or whatever, you really need to check this some how I do'n't think you can :|


All times are GMT +2. The time now is 07:58.

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