From de2971541bb108228a69f41e7adf9b654a38d769 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 24 Jul 2018 21:40:23 +0100 Subject: [PATCH] Fix stack underflow: currently for each call it pops always the same fixed number of arguments related to instruction array size leading to underflow most of the time since it s mostly less. --- code/client/cl_cgame.c | 8 ++++---- code/client/cl_cin.c | 2 +- code/client/cl_console.c | 4 ++-- code/client/cl_input.c | 4 ++-- code/client/cl_keys.c | 18 +++++++++--------- code/client/cl_main.c | 10 +++++----- code/client/cl_scrn.c | 14 +++++++------- code/client/cl_ui.c | 12 ++++++------ code/qcommon/qcommon.h | 2 +- code/qcommon/vm.c | 13 +++++++------ code/server/sv_bot.c | 2 +- code/server/sv_ccmds.c | 6 +++--- code/server/sv_client.c | 12 ++++++------ code/server/sv_game.c | 8 ++++---- code/server/sv_init.c | 8 ++++---- code/server/sv_main.c | 2 +- 16 files changed, 63 insertions(+), 62 deletions(-) diff --git a/code/client/cl_cgame.c b/code/client/cl_cgame.c index 613d0842..ef871e08 100644 --- a/code/client/cl_cgame.c +++ b/code/client/cl_cgame.c @@ -389,7 +389,7 @@ void CL_ShutdownCGame( void ) { if ( !cgvm ) { return; } - VM_Call( cgvm, CG_SHUTDOWN ); + VM_Call( cgvm, CG_SHUTDOWN, 0 ); VM_Free( cgvm ); cgvm = NULL; } @@ -742,7 +742,7 @@ void CL_InitCGame( void ) { // init for this gamestate // use the lastExecutedServerCommand instead of the serverCommandSequence // otherwise server commands sent just before a gamestate are dropped - VM_Call( cgvm, CG_INIT, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum ); + VM_Call( cgvm, CG_INIT, 3, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum ); // reset any CVAR_CHEAT cvars registered by cgame if ( !clc.demoplaying && !cl_connectedToCheatServer ) @@ -782,7 +782,7 @@ qboolean CL_GameCommand( void ) { return qfalse; } - return VM_Call( cgvm, CG_CONSOLE_COMMAND ); + return VM_Call( cgvm, CG_CONSOLE_COMMAND, 0 ); } @@ -793,7 +793,7 @@ CL_CGameRendering ===================== */ void CL_CGameRendering( stereoFrame_t stereo ) { - VM_Call( cgvm, CG_DRAW_ACTIVE_FRAME, cl.serverTime, stereo, clc.demoplaying ); + VM_Call( cgvm, CG_DRAW_ACTIVE_FRAME, 3, cl.serverTime, stereo, clc.demoplaying ); VM_Debug( 0 ); } diff --git a/code/client/cl_cin.c b/code/client/cl_cin.c index cdc3ab3e..f9befb18 100644 --- a/code/client/cl_cin.c +++ b/code/client/cl_cin.c @@ -1455,7 +1455,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi if (cinTable[currentHandle].alterGameState) { // close the menu if ( uivm ) { - VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_NONE ); + VM_Call( uivm, UI_SET_ACTIVE_MENU, 1, UIMENU_NONE ); } } else { cinTable[currentHandle].playonwalls = cl_inGameVideo->integer; diff --git a/code/client/cl_console.c b/code/client/cl_console.c index 6a65bb79..d8211007 100644 --- a/code/client/cl_console.c +++ b/code/client/cl_console.c @@ -126,7 +126,7 @@ Con_MessageMode3_f ================ */ void Con_MessageMode3_f (void) { - chat_playerNum = VM_Call( cgvm, CG_CROSSHAIR_PLAYER ); + chat_playerNum = VM_Call( cgvm, CG_CROSSHAIR_PLAYER, 0 ); if ( chat_playerNum < 0 || chat_playerNum >= MAX_CLIENTS ) { chat_playerNum = -1; return; @@ -143,7 +143,7 @@ Con_MessageMode4_f ================ */ void Con_MessageMode4_f (void) { - chat_playerNum = VM_Call( cgvm, CG_LAST_ATTACKER ); + chat_playerNum = VM_Call( cgvm, CG_LAST_ATTACKER, 0 ); if ( chat_playerNum < 0 || chat_playerNum >= MAX_CLIENTS ) { chat_playerNum = -1; return; diff --git a/code/client/cl_input.c b/code/client/cl_input.c index cfdaa1d1..0432539b 100644 --- a/code/client/cl_input.c +++ b/code/client/cl_input.c @@ -361,9 +361,9 @@ CL_MouseEvent */ void CL_MouseEvent( int dx, int dy, int time ) { if ( Key_GetCatcher( ) & KEYCATCH_UI ) { - VM_Call( uivm, UI_MOUSE_EVENT, dx, dy ); + VM_Call( uivm, UI_MOUSE_EVENT, 2, dx, dy ); } else if (Key_GetCatcher( ) & KEYCATCH_CGAME) { - VM_Call (cgvm, CG_MOUSE_EVENT, dx, dy); + VM_Call (cgvm, CG_MOUSE_EVENT, 2, dx, dy); } else { cl.mouseDx[cl.mouseIndex] += dx; cl.mouseDy[cl.mouseIndex] += dy; diff --git a/code/client/cl_keys.c b/code/client/cl_keys.c index b2bc9559..61cc3c7c 100644 --- a/code/client/cl_keys.c +++ b/code/client/cl_keys.c @@ -1282,23 +1282,23 @@ void CL_KeyDownEvent( int key, unsigned time ) // escape always gets out of CGAME stuff if (Key_GetCatcher( ) & KEYCATCH_CGAME) { Key_SetCatcher( Key_GetCatcher( ) & ~KEYCATCH_CGAME ); - VM_Call (cgvm, CG_EVENT_HANDLING, CGAME_EVENT_NONE); + VM_Call (cgvm, CG_EVENT_HANDLING, 1, CGAME_EVENT_NONE); return; } if ( !( Key_GetCatcher( ) & KEYCATCH_UI ) ) { if ( clc.state == CA_ACTIVE && !clc.demoplaying ) { - VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_INGAME ); + VM_Call( uivm, UI_SET_ACTIVE_MENU, 1, UIMENU_INGAME ); } else if ( clc.state != CA_DISCONNECTED ) { CL_Disconnect_f(); S_StopAllSounds(); - VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN ); + VM_Call( uivm, UI_SET_ACTIVE_MENU, 1, UIMENU_MAIN ); } return; } - VM_Call( uivm, UI_KEY_EVENT, key, qtrue ); + VM_Call( uivm, UI_KEY_EVENT, 2, key, qtrue ); return; } @@ -1310,11 +1310,11 @@ void CL_KeyDownEvent( int key, unsigned time ) Console_Key( key ); } else if ( Key_GetCatcher( ) & KEYCATCH_UI ) { if ( uivm ) { - VM_Call( uivm, UI_KEY_EVENT, key, qtrue ); + VM_Call( uivm, UI_KEY_EVENT, 2, key, qtrue ); } } else if ( Key_GetCatcher( ) & KEYCATCH_CGAME ) { if ( cgvm ) { - VM_Call( cgvm, CG_KEY_EVENT, key, qtrue ); + VM_Call( cgvm, CG_KEY_EVENT, 2, key, qtrue ); } } else if ( Key_GetCatcher( ) & KEYCATCH_MESSAGE ) { Message_Key( key ); @@ -1353,9 +1353,9 @@ void CL_KeyUpEvent( int key, unsigned time ) CL_ParseBinding( key, qfalse, time ); if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) { - VM_Call( uivm, UI_KEY_EVENT, key, qfalse ); + VM_Call( uivm, UI_KEY_EVENT, 2, key, qfalse ); } else if ( Key_GetCatcher( ) & KEYCATCH_CGAME && cgvm ) { - VM_Call( cgvm, CG_KEY_EVENT, key, qfalse ); + VM_Call( cgvm, CG_KEY_EVENT, 2, key, qfalse ); } } @@ -1394,7 +1394,7 @@ void CL_CharEvent( int key ) { } else if ( Key_GetCatcher( ) & KEYCATCH_UI ) { - VM_Call( uivm, UI_KEY_EVENT, key | K_CHAR_FLAG, qtrue ); + VM_Call( uivm, UI_KEY_EVENT, 2, key | K_CHAR_FLAG, qtrue ); } else if ( Key_GetCatcher( ) & KEYCATCH_MESSAGE ) { diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 528df6a9..b6390030 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -359,12 +359,12 @@ void CL_VoipParseTargets(void) { if(!Q_stricmpn(target, "attacker", 8)) { - val = VM_Call(cgvm, CG_LAST_ATTACKER); + val = VM_Call(cgvm, CG_LAST_ATTACKER, 0); target += 8; } else if(!Q_stricmpn(target, "crosshair", 9)) { - val = VM_Call(cgvm, CG_CROSSHAIR_PLAYER); + val = VM_Call(cgvm, CG_CROSSHAIR_PLAYER, 0); target += 9; } else @@ -1429,7 +1429,7 @@ void CL_Disconnect( qboolean showMainMenu ) { } if ( uivm && showMainMenu ) { - VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_NONE ); + VM_Call( uivm, UI_SET_ACTIVE_MENU, 1, UIMENU_NONE ); } SCR_StopCinematic (); @@ -2956,12 +2956,12 @@ void CL_Frame ( int msec ) { if ( cls.cddialog ) { // bring up the cd error dialog if needed cls.cddialog = qfalse; - VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_NEED_CD ); + VM_Call( uivm, UI_SET_ACTIVE_MENU, 1, UIMENU_NEED_CD ); } else if ( clc.state == CA_DISCONNECTED && !( Key_GetCatcher( ) & KEYCATCH_UI ) && !com_sv_running->integer && uivm ) { // if disconnected, bring up the menu S_StopAllSounds(); - VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN ); + VM_Call( uivm, UI_SET_ACTIVE_MENU, 1, UIMENU_MAIN ); } // if recording an avi, lock to a fixed fps diff --git a/code/client/cl_scrn.c b/code/client/cl_scrn.c index 831d5ef7..5d3f917b 100644 --- a/code/client/cl_scrn.c +++ b/code/client/cl_scrn.c @@ -477,7 +477,7 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) { re.BeginFrame( stereoFrame ); - uiFullscreen = (uivm && VM_Call( uivm, UI_IS_FULLSCREEN )); + uiFullscreen = (uivm && VM_Call( uivm, UI_IS_FULLSCREEN, 0 )); // wide aspect ratio screens need to have the sides cleared // unless they are displaying game renderings @@ -502,15 +502,15 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) { case CA_DISCONNECTED: // force menu up S_StopAllSounds(); - VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN ); + VM_Call( uivm, UI_SET_ACTIVE_MENU, 1, UIMENU_MAIN ); break; case CA_CONNECTING: case CA_CHALLENGING: case CA_CONNECTED: // connecting clients will only show the connection dialog // refresh to update the time - VM_Call( uivm, UI_REFRESH, cls.realtime ); - VM_Call( uivm, UI_DRAW_CONNECT_SCREEN, qfalse ); + VM_Call( uivm, UI_REFRESH, 1, cls.realtime ); + VM_Call( uivm, UI_DRAW_CONNECT_SCREEN, 1, qfalse ); break; case CA_LOADING: case CA_PRIMED: @@ -520,8 +520,8 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) { // also draw the connection information, so it doesn't // flash away too briefly on local or lan games // refresh to update the time - VM_Call( uivm, UI_REFRESH, cls.realtime ); - VM_Call( uivm, UI_DRAW_CONNECT_SCREEN, qtrue ); + VM_Call( uivm, UI_REFRESH, 1, cls.realtime ); + VM_Call( uivm, UI_DRAW_CONNECT_SCREEN, 1, qtrue ); break; case CA_ACTIVE: // always supply STEREO_CENTER as vieworg offset is now done by the engine. @@ -536,7 +536,7 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) { // the menu draws next if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) { - VM_Call( uivm, UI_REFRESH, cls.realtime ); + VM_Call( uivm, UI_REFRESH, 1, cls.realtime ); } // console draws next diff --git a/code/client/cl_ui.c b/code/client/cl_ui.c index 71436484..ca3096de 100644 --- a/code/client/cl_ui.c +++ b/code/client/cl_ui.c @@ -1091,7 +1091,7 @@ void CL_ShutdownUI( void ) { if ( !uivm ) { return; } - VM_Call( uivm, UI_SHUTDOWN ); + VM_Call( uivm, UI_SHUTDOWN, 0 ); VM_Free( uivm ); uivm = NULL; } @@ -1122,11 +1122,11 @@ void CL_InitUI( void ) { } // sanity check - v = VM_Call( uivm, UI_GETAPIVERSION ); + v = VM_Call( uivm, UI_GETAPIVERSION, 0 ); if (v == UI_OLD_API_VERSION) { // Com_Printf(S_COLOR_YELLOW "WARNING: loading old Quake III Arena User Interface version %d\n", v ); // init for this gamestate - VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE)); + VM_Call( uivm, UI_INIT, 1, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE)); } else if (v != UI_API_VERSION) { // Free uivm now, so UI_SHUTDOWN doesn't get called later. @@ -1138,14 +1138,14 @@ void CL_InitUI( void ) { } else { // init for this gamestate - VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE) ); + VM_Call( uivm, UI_INIT, 1, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE) ); } } #ifndef STANDALONE qboolean UI_usesUniqueCDKey( void ) { if (uivm) { - return (VM_Call( uivm, UI_HASUNIQUECDKEY) == qtrue); + return (VM_Call( uivm, UI_HASUNIQUECDKEY, 0) == qtrue); } else { return qfalse; } @@ -1164,5 +1164,5 @@ qboolean UI_GameCommand( void ) { return qfalse; } - return VM_Call( uivm, UI_CONSOLE_COMMAND, cls.realtime ); + return VM_Call( uivm, UI_CONSOLE_COMMAND, 1, cls.realtime ); } diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index 4471198c..d765a3fd 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -366,7 +366,7 @@ void VM_Forced_Unload_Start(void); void VM_Forced_Unload_Done(void); vm_t *VM_Restart(vm_t *vm, qboolean unpure); -intptr_t QDECL VM_Call( vm_t *vm, int callNum, ... ); +intptr_t QDECL VM_Call( vm_t *vm, int callNum, int n, ... ); void VM_Debug( int level ); diff --git a/code/qcommon/vm.c b/code/qcommon/vm.c index 03bdb966..b42ba170 100644 --- a/code/qcommon/vm.c +++ b/code/qcommon/vm.c @@ -804,11 +804,11 @@ locals from sp ============== */ -intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) +intptr_t QDECL VM_Call( vm_t *vm, int callnum, int n, ... ) { vm_t *oldVM; intptr_t r; - int i; + int i, cnt = n; if(!vm || !vm->name[0]) Com_Error(ERR_FATAL, "VM_Call with NULL vm"); @@ -827,8 +827,8 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) //rcg010207 - see dissertation at top of VM_DllSyscall() in this file. int args[MAX_VMMAIN_ARGS-1]; va_list ap; - va_start(ap, callnum); - for (i = 0; i < ARRAY_LEN(args); i++) { + va_start(ap, n); + for (i = 0; i < ARRAY_LEN(args) && cnt-- > 0; i++) { args[i] = va_arg(ap, int); } va_end(ap); @@ -845,6 +845,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) #endif r = VM_CallInterpreted( vm, (int*)&callnum ); #else + cnt = n; struct { int callnum; int args[MAX_VMMAIN_ARGS-1]; @@ -852,8 +853,8 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) va_list ap; a.callnum = callnum; - va_start(ap, callnum); - for (i = 0; i < ARRAY_LEN(a.args); i++) { + va_start(ap, n); + for (i = 0; i < ARRAY_LEN(a.args) && cnt-- > 0; i++) { a.args[i] = va_arg(ap, int); } va_end(ap); diff --git a/code/server/sv_bot.c b/code/server/sv_bot.c index 58503542..dc936e44 100644 --- a/code/server/sv_bot.c +++ b/code/server/sv_bot.c @@ -435,7 +435,7 @@ void SV_BotFrame( int time ) { if (!bot_enable) return; //NOTE: maybe the game is already shutdown if (!gvm) return; - VM_Call( gvm, BOTAI_START_FRAME, time ); + VM_Call( gvm, BOTAI_START_FRAME, 1, time ); } /* diff --git a/code/server/sv_ccmds.c b/code/server/sv_ccmds.c index 2ba8194d..f05776d7 100644 --- a/code/server/sv_ccmds.c +++ b/code/server/sv_ccmds.c @@ -302,7 +302,7 @@ static void SV_MapRestart_f( void ) { // run a few frames to allow everything to settle for (i = 0; i < 3; i++) { - VM_Call (gvm, GAME_RUN_FRAME, sv.time); + VM_Call (gvm, GAME_RUN_FRAME, 1, sv.time); sv.time += 100; svs.time += 100; } @@ -329,7 +329,7 @@ static void SV_MapRestart_f( void ) { SV_AddServerCommand( client, "map_restart\n" ); // connect the client again, without the firstTime flag - denied = VM_ExplicitArgPtr( gvm, VM_Call( gvm, GAME_CLIENT_CONNECT, i, qfalse, isBot ) ); + denied = VM_ExplicitArgPtr( gvm, VM_Call( gvm, GAME_CLIENT_CONNECT, 3, i, qfalse, isBot ) ); if ( denied ) { // this generally shouldn't happen, because the client // was connected before the level change @@ -350,7 +350,7 @@ static void SV_MapRestart_f( void ) { } // run another frame to allow things to look at all the players - VM_Call (gvm, GAME_RUN_FRAME, sv.time); + VM_Call (gvm, GAME_RUN_FRAME, 1, sv.time); sv.time += 100; svs.time += 100; } diff --git a/code/server/sv_client.c b/code/server/sv_client.c index 62d6456e..c7db3839 100644 --- a/code/server/sv_client.c +++ b/code/server/sv_client.c @@ -558,7 +558,7 @@ gotnewcl: Q_strncpyz( newcl->userinfo, userinfo, sizeof(newcl->userinfo) ); // get the game a chance to reject this connection or modify the userinfo - denied = VM_Call( gvm, GAME_CLIENT_CONNECT, clientNum, qtrue, qfalse ); // firstTime = qtrue + denied = VM_Call( gvm, GAME_CLIENT_CONNECT, 3, clientNum, qtrue, qfalse ); // firstTime = qtrue if ( denied ) { // we can't just use VM_ArgPtr, because that is only valid inside a VM_Call char *str = VM_ExplicitArgPtr( gvm, denied ); @@ -664,7 +664,7 @@ void SV_DropClient( client_t *drop, const char *reason ) { // call the prog function for removing a client // this will remove the body, among other things - VM_Call( gvm, GAME_CLIENT_DISCONNECT, drop - svs.clients ); + VM_Call( gvm, GAME_CLIENT_DISCONNECT, 1, drop - svs.clients ); // add the disconnect command SV_SendServerCommand( drop, "disconnect \"%s\"", reason); @@ -803,7 +803,7 @@ void SV_ClientEnterWorld( client_t *client, usercmd_t *cmd ) { memset(&client->lastUsercmd, '\0', sizeof(client->lastUsercmd)); // call the game begin function - VM_Call( gvm, GAME_CLIENT_BEGIN, client - svs.clients ); + VM_Call( gvm, GAME_CLIENT_BEGIN, 1, client - svs.clients ); } /* @@ -1492,7 +1492,7 @@ static void SV_UpdateUserinfo_f( client_t *cl ) { SV_UserinfoChanged( cl ); // call prog code to allow overrides - VM_Call( gvm, GAME_CLIENT_USERINFO_CHANGED, cl - svs.clients ); + VM_Call( gvm, GAME_CLIENT_USERINFO_CHANGED, 1, cl - svs.clients ); } @@ -1576,7 +1576,7 @@ void SV_ExecuteClientCommand( client_t *cl, const char *s, qboolean clientOK ) { // pass unknown strings to the game if (!u->name && sv.state == SS_GAME && (cl->state == CS_ACTIVE || cl->state == CS_PRIMED)) { Cmd_Args_Sanitize(); - VM_Call( gvm, GAME_CLIENT_COMMAND, cl - svs.clients ); + VM_Call( gvm, GAME_CLIENT_COMMAND, 1, cl - svs.clients ); } } else if (!bProcessed) @@ -1656,7 +1656,7 @@ void SV_ClientThink (client_t *cl, usercmd_t *cmd) { return; // may have been kicked during the last usercmd } - VM_Call( gvm, GAME_CLIENT_THINK, cl - svs.clients ); + VM_Call( gvm, GAME_CLIENT_THINK, 1, cl - svs.clients ); } /* diff --git a/code/server/sv_game.c b/code/server/sv_game.c index 161d975e..1d8617dc 100644 --- a/code/server/sv_game.c +++ b/code/server/sv_game.c @@ -860,7 +860,7 @@ void SV_ShutdownGameProgs( void ) { if ( !gvm ) { return; } - VM_Call( gvm, GAME_SHUTDOWN, qfalse ); + VM_Call( gvm, GAME_SHUTDOWN, 1, qfalse ); VM_Free( gvm ); gvm = NULL; } @@ -888,7 +888,7 @@ static void SV_InitGameVM( qboolean restart ) { // use the current msec count for a random seed // init for this gamestate - VM_Call (gvm, GAME_INIT, sv.time, Com_Milliseconds(), restart); + VM_Call (gvm, GAME_INIT, 3, sv.time, Com_Milliseconds(), restart); } @@ -904,7 +904,7 @@ void SV_RestartGameProgs( void ) { if ( !gvm ) { return; } - VM_Call( gvm, GAME_SHUTDOWN, qtrue ); + VM_Call( gvm, GAME_SHUTDOWN, 1, qtrue ); // do a restart instead of a free gvm = VM_Restart(gvm, qtrue); @@ -958,6 +958,6 @@ qboolean SV_GameCommand( void ) { return qfalse; } - return VM_Call( gvm, GAME_CONSOLE_COMMAND ); + return VM_Call( gvm, GAME_CONSOLE_COMMAND, 0 ); } diff --git a/code/server/sv_init.c b/code/server/sv_init.c index b8fb28c2..bf9afdc2 100644 --- a/code/server/sv_init.c +++ b/code/server/sv_init.c @@ -497,7 +497,7 @@ void SV_SpawnServer( char *server, qboolean killBots ) { // run a few frames to allow everything to settle for (i = 0;i < 3; i++) { - VM_Call (gvm, GAME_RUN_FRAME, sv.time); + VM_Call (gvm, GAME_RUN_FRAME, 1, sv.time); SV_BotFrame (sv.time); sv.time += 100; svs.time += 100; @@ -523,7 +523,7 @@ void SV_SpawnServer( char *server, qboolean killBots ) { } // connect the client again - denied = VM_ExplicitArgPtr( gvm, VM_Call( gvm, GAME_CLIENT_CONNECT, i, qfalse, isBot ) ); // firstTime = qfalse + denied = VM_ExplicitArgPtr( gvm, VM_Call( gvm, GAME_CLIENT_CONNECT, 3, i, qfalse, isBot ) ); // firstTime = qfalse if ( denied ) { // this generally shouldn't happen, because the client // was connected before the level change @@ -547,14 +547,14 @@ void SV_SpawnServer( char *server, qboolean killBots ) { client->deltaMessage = -1; client->lastSnapshotTime = 0; // generate a snapshot immediately - VM_Call( gvm, GAME_CLIENT_BEGIN, i ); + VM_Call( gvm, GAME_CLIENT_BEGIN, 1, i ); } } } } // run another frame to allow things to look at all the players - VM_Call (gvm, GAME_RUN_FRAME, sv.time); + VM_Call (gvm, GAME_RUN_FRAME, 1, sv.time); SV_BotFrame (sv.time); sv.time += 100; svs.time += 100; diff --git a/code/server/sv_main.c b/code/server/sv_main.c index 4d94c1e3..71ebf950 100644 --- a/code/server/sv_main.c +++ b/code/server/sv_main.c @@ -1140,7 +1140,7 @@ void SV_Frame( int msec ) { sv.time += frameMsec; // let everything in the world think and move - VM_Call (gvm, GAME_RUN_FRAME, sv.time); + VM_Call (gvm, GAME_RUN_FRAME, 1, sv.time); } if ( com_speeds->integer ) {