/* ================ SV_Shutdown Quake calls this before calling Sys_Quit or Sys_Error ================ */ void SV_Shutdown (char *finalmsg) { int i; SV_FinalMessage (finalmsg); PR_FreeStrings (); Master_Shutdown (); NET_ServerConfig (false); if (sv_fraglogfile) { fclose (sv_fraglogfile); sv_fraglogfile = NULL; } memset (&sv, 0, sizeof(sv)); sv.state = ss_dead; com_serveractive = false; for (i = 0; i < MAX_CLIENTS; i++) SV_FreeDelayedPackets(&svs.clients[i]); memset (svs.clients, 0, sizeof(svs.clients)); svs.lastuserid = 0; }
/* * ================ * SV_Shutdown * * Called when each game quits, * before Sys_Quit or Sys_Error * ================ */ void SV_Shutdown(char *finalmsg, qboolean reconnect) { if (svs.clients) { SV_FinalMessage(finalmsg, reconnect); } Master_Shutdown(); SV_ShutdownGameProgs(); // free current level if (sv.demofile) { FS_FCloseFile(sv.demofile); } memset(&sv, 0, sizeof(sv)); Com_SetServerState(sv.state); // free server static data if (svs.clients) { Z_Free(svs.clients); } if (svs.client_entities) { Z_Free(svs.client_entities); } if (svs.demofile) { fclose(svs.demofile); } memset(&svs, 0, sizeof(svs)); }
/* ================ SV_Shutdown Called when each game quits, and before exitting application ================ */ void SV_Shutdown(const char *finalmsg, bool reconnect) { guard(SV_Shutdown); if (svs.clients) // NOTE: this required even for attractloop: if disable, when demo finishes, client will not be automatically disconnected { int i; client_t *cl; // Send a final message to all connected clients before the server goes down. // The messages are sent immediately, not just stuck on the outgoing message // list, because the server is going to totally exit after returning from this function. for (i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++) { if (cl->state < cs_connected) continue; net_message.Clear(); MSG_WriteByte(&net_message, svc_print); MSG_WriteByte(&net_message, PRINT_HIGH); if (cl->newprotocol && !reconnect) // colorize exit message MSG_WriteString(&net_message, va(S_RED"%s", finalmsg)); else MSG_WriteString(&net_message, finalmsg); MSG_WriteByte(&net_message, reconnect ? svc_reconnect : svc_disconnect); cl->netchan.Transmit(net_message.data, net_message.cursize); } } Master_Shutdown(); SV_ShutdownGameLibrary(); // free current level if (sv.rdemofile) delete sv.rdemofile; memset(&sv, 0, sizeof(sv)); Com_SetServerState(ss_dead); // == 0 // free server static data sv_client = NULL; if (svs.clients) delete svs.clients; if (svs.client_entities) delete svs.client_entities; if (svs.wdemofile) fclose(svs.wdemofile); memset(&svs, 0, sizeof(svs)); SV_InitVars(); // called for unlocking latched vars Cvar_ForceSet("nointro", "1"); unguard; }
/* ================ SV_Shutdown Quake calls this before calling Sys_Quit or Sys_Error ================ */ void SV_Shutdown (void) { Master_Shutdown (); if (sv_logfile) { fclose (sv_logfile); sv_logfile = NULL; } if (sv_fraglogfile) { fclose (sv_fraglogfile); sv_logfile = NULL; } NET_Shutdown (); }
/** * @brief Called when each game quits, before Sys_Quit or Sys_Error * @param[in] finalmsg The message all clients get as server shutdown message * @param[in] reconnect True if this is only a restart (new map or map restart), * false if the server shutdown completely and you also want to disconnect all clients */ void SV_Shutdown (const char *finalmsg, qboolean reconnect) { unsigned int i; if (!svs.initialized) return; if (svs.clients) SV_FinalMessage(finalmsg, reconnect); Com_Printf("Shutdown server: %s\n", finalmsg); Master_Shutdown(); SV_ShutdownGameProgs(); NET_DatagramSocketClose(svs.netDatagramSocket); SV_Stop(); for (i = 0; i < sv->numSVModels; i++) { sv_model_t *model = &sv->svModels[i]; if (model->name) Mem_Free(model->name); } /* free current level */ OBJZERO(*sv); /* free server static data */ if (svs.clients) Mem_Free(svs.clients); if (svs.serverMutex != NULL) TH_MutexDestroy(svs.serverMutex); OBJZERO(svs); /* maybe we shut down before we init - e.g. in case of an error */ if (sv_maxclients) sv_maxclients->flags &= ~CVAR_LATCH; if (sv_mapname) sv_mapname->flags &= ~CVAR_NOSET; }
/* ================ SV_Shutdown Called when each game quits, before Sys_Quit or Sys_Error ================ */ void SV_Shutdown( qboolean reconnect ) { // already freed if( !SV_Active( )) return; if( host.type == HOST_DEDICATED ) MsgDev( D_INFO, "SV_Shutdown: %s\n", host.finalmsg ); if( svs.clients ) SV_FinalMessage( host.finalmsg, reconnect ); Master_Shutdown(); if( !reconnect ) SV_UnloadProgs (); else SV_DeactivateServer (); // free current level Q_memset( &sv, 0, sizeof( sv )); Host_SetServerState( sv.state ); // free server static data if( svs.clients ) { Z_Free( svs.clients ); svs.clients = NULL; } if( svs.baselines ) { Z_Free( svs.baselines ); svs.baselines = NULL; } if( svs.packet_entities ) { Z_Free( svs.packet_entities ); svs.packet_entities = NULL; svs.num_client_entities = 0; svs.next_client_entities = 0; } svs.initialized = false; }