diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 99ee971d..687dbb72 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -7969,6 +7969,7 @@ qc_extension_t QSG_Extensions[] = { {"DP_SV_PRINT", NULL, 1,{"print"}, "Says that the print builtin can be used from nqssqc (as well as just csqc), bypassing the developer cvar issues."}, {"DP_SV_ROTATINGBMODEL", check_notrerelease,0,{NULL}, "Engines that support this support avelocity on MOVETYPE_PUSH entities, pushing entities out of the way as needed."}, {"DP_SV_SETCOLOR", NULL, 1,{"setcolor"}}, + {"DP_SV_SHUTDOWN"}, {"DP_SV_SPAWNFUNC_PREFIX"}, {"DP_SV_WRITEPICTURE", NULL, 1,{"WritePicture"}}, {"DP_SV_WRITEUNTERMINATEDSTRING", NULL, 1,{"WriteUnterminatedString"}}, diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index b5e828b6..20d74cc8 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -168,6 +168,7 @@ static struct { func_t ParseClusterEvent; //FTE_SV_CLUSTER func_t ParseClientCommand; //KRIMZON_SV_PARSECLIENTCOMMAND func_t ParseConnectionlessPacket; //FTE_QC_SENDPACKET + func_t SV_Shutdown; func_t PausedTic; func_t ShouldPause; @@ -1117,6 +1118,7 @@ void PR_LoadGlabalStruct(qboolean muted) gfuncs.ParseClusterEvent = PR_FindFunction(svprogfuncs, "SV_ParseClusterEvent", PR_ANY); gfuncs.ParseClientCommand = PR_FindFunction(svprogfuncs, "SV_ParseClientCommand", PR_ANY); gfuncs.ParseConnectionlessPacket = PR_FindFunction(svprogfuncs, "SV_ParseConnectionlessPacket", PR_ANY); + gfuncs.SV_Shutdown = PR_FindFunction(svprogfuncs, "SV_Shutdown", PR_ANY); gfuncs.UserInfo_Changed = PR_FindFunction(svprogfuncs, "UserInfo_Changed", PR_ANY); gfuncs.localinfoChanged = PR_FindFunction(svprogfuncs, "localinfoChanged", PR_ANY); @@ -2626,6 +2628,24 @@ void PR_LocalInfoChanged(char *name, char *oldivalue, char *newvalue) PR_ExecuteProgram (svprogfuncs, gfuncs.localinfoChanged); } } +void PR_PreShutdown(void) +{ + if (svprogfuncs && gfuncs.SV_Shutdown && sv.state) + { + func_t f = gfuncs.SV_Shutdown; + globalvars_t *pr_globals; + gfuncs.SV_Shutdown = 0; //clear it early, to avoid (severe) recursion/whatever problems. + pr_globals = PR_globals(svprogfuncs, PR_CURRENT); + + pr_global_struct->time = sv.world.physicstime; + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); + + G_INT(OFS_PARM0) = 0; + G_INT(OFS_PARM1) = 0; + G_INT(OFS_PARM2) = 0; + PR_ExecuteProgram (svprogfuncs, f); + } +} void QC_Clear(void) { diff --git a/engine/server/progs.h b/engine/server/progs.h index c1220a11..1f7bae20 100644 --- a/engine/server/progs.h +++ b/engine/server/progs.h @@ -135,6 +135,7 @@ extern int pr_teamfield; qboolean PR_QCChat(char *text, int say_type); void PR_ClientUserInfoChanged(char *name, char *oldivalue, char *newvalue); +void PR_PreShutdown(void); void PR_LocalInfoChanged(char *name, char *oldivalue, char *newvalue); void PF_InitTempStrings(pubprogfuncs_t *inst); diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 5f23fd8e..bf5babd4 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -611,6 +611,8 @@ void SV_UnspawnServer (void) //terminate the running server. Con_TPrintf("Server ended\n"); SV_FinalMessage("Server unspawned\n"); + PR_PreShutdown(); + #ifdef SUBSERVERS if (sv.state == ss_clustermode && svs.allocated_client_slots == 1) MSV_Shutdown(); @@ -868,9 +870,6 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, Con_DPrintf ("SpawnServer: %s\n",server); - svs.spawncount++; // any partially connected client will be restarted - sv.world.spawncount = svs.spawncount; - #ifndef SERVERONLY total_loading_size = 100; current_loading_size = 0; @@ -879,6 +878,11 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, SCR_ImageName(server); #endif + PR_PreShutdown(); + + svs.spawncount++; // any partially connected client will be restarted + sv.world.spawncount = svs.spawncount; + sv.state = ss_dead; if (sv.gamedirchanged)