/* ==================== SV_StopRecording_f stop recording a demo ==================== */ void SV_StopRecord_f( void ) { int i; client_t *cl = NULL; if ( Cmd_Argc() == 2 ) { int clIndex = atoi( Cmd_Argv( 1 ) ); if ( clIndex < 0 || clIndex >= sv_maxclients->integer ) { Com_Printf( "Unknown client number %d.\n", clIndex ); return; } cl = &svs.clients[clIndex]; } else { for (i = 0; i < sv_maxclients->integer; i++) { if ( svs.clients[i].demo.demorecording ) { cl = &svs.clients[i]; break; } } if ( cl == NULL ) { Com_Printf( "No demo being recorded.\n" ); return; } } SV_StopRecordDemo( cl ); }
// stops all recording demos void SV_StopAutoRecordDemos() { if ( svs.clients && sv_autoDemo->integer ) { for ( client_t *client = svs.clients; client - svs.clients < sv_maxclients->integer; client++ ) { if ( client->demo.demorecording) { SV_StopRecordDemo( client ); } } } }
/* ===================== SV_DropClient Called when the player is totally leaving the server, either willingly or unwillingly. This is NOT called if the entire server is quiting or crashing -- SV_FinalMessage() will handle that ===================== */ void SV_DropClient( client_t *drop, const char *reason ) { int i; const bool isBot = drop->netchan.remoteAddress.type == NA_BOT; if ( drop->state == CS_ZOMBIE ) { return; // already dropped } // Kill any download SV_CloseDownload( drop ); // tell everyone why they got dropped SV_SendServerCommand( NULL, "print \"%s" S_COLOR_WHITE " %s\n\"", drop->name, reason ); // call the prog function for removing a client // this will remove the body, among other things GVM_ClientDisconnect( drop - svs.clients ); // add the disconnect command SV_SendServerCommand( drop, "disconnect \"%s\"", reason ); if ( isBot ) { SV_BotFreeClient( drop - svs.clients ); } // nuke user info SV_SetUserinfo( drop - svs.clients, "" ); if ( isBot ) { // bots shouldn't go zombie, as there's no real net connection. drop->state = CS_FREE; } else { Com_DPrintf( "Going to CS_ZOMBIE for %s\n", drop->name ); drop->state = CS_ZOMBIE; // become free in a few seconds } if ( drop->demo.demorecording ) { SV_StopRecordDemo( drop ); } // if this was the last client on the server, send a heartbeat // to the master so it is known the server is empty // send a heartbeat now so the master will get up to date info // if there is already a slot for this ip, reuse it for (i=0 ; i < sv_maxclients->integer ; i++ ) { if ( svs.clients[i].state >= CS_CONNECTED ) { break; } } if ( i == sv_maxclients->integer ) { SV_Heartbeat_f(); } }
/* ================== SV_BotFreeClient ================== */ void SV_BotFreeClient( int clientNum ) { client_t *cl; if ( clientNum < 0 || clientNum >= sv_maxclients->integer ) { Com_Error( ERR_DROP, "SV_BotFreeClient: bad clientNum: %i", clientNum ); } cl = &svs.clients[clientNum]; cl->state = CS_FREE; cl->name[0] = 0; if ( cl->gentity ) { cl->gentity->r.svFlags &= ~SVF_BOT; } if ( cl->demo.demorecording ) { SV_StopRecordDemo( cl ); } }