From f7c2b4a708af081fc8b05a5b189a21ac9174096d Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 6 Dec 2006 08:34:35 +0000 Subject: [PATCH] fixed bug that caused csqc to only load after a map restart rearranged entity linking when csqc is active to fix the lagging weapon model bug git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6635 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 45 +++++++++++++++++++++++++++++++-------------- csprogs.c | 51 ++++++++++++++++++++++++++++----------------------- server.h | 4 ++++ sv_main.c | 30 ++++++++++++++++++------------ 4 files changed, 81 insertions(+), 49 deletions(-) diff --git a/cl_main.c b/cl_main.c index 012de0db..50c185d6 100644 --- a/cl_main.c +++ b/cl_main.c @@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // references them even when on a unix system. cvar_t csqc_progname = {0, "csqc_progname","csprogs.dat","name of csprogs.dat file to load"}; //[515]: csqc crc check and right csprogs name according to progs.dat -cvar_t csqc_progcrc = {CVAR_READONLY, "csqc_progcrc","0","CRC of csprogs.dat file to load"}; +cvar_t csqc_progcrc = {CVAR_READONLY, "csqc_progcrc","-1","CRC of csprogs.dat file to load (-1 is none), only used during level changes and then reset to -1"}; cvar_t cl_shownet = {0, "cl_shownet","0","1 = print packet size, 2 = print packet message list"}; cvar_t cl_nolerp = {0, "cl_nolerp", "0","network update smoothing"}; @@ -1544,6 +1544,17 @@ void CL_LerpPlayer(float frac) void CSQC_RelinkAllEntities (int drawmask) { + // process network entities (note: this sets up the view!) + cl.num_brushmodel_entities = 0; + CL_UpdateEntities(); + + entitylinkframenumber++; + // link stuff + CL_RelinkWorld(); + CL_RelinkStaticEntities(); + CL_RelinkBeams(); + CL_RelinkEffects(); + // link stuff if (drawmask & ENTMASK_ENGINE) { @@ -1553,6 +1564,9 @@ void CSQC_RelinkAllEntities (int drawmask) if (drawmask & ENTMASK_ENGINEVIEWMODELS) CL_LinkNetworkEntity(&cl.viewent); // link gun model + + // update view blend + V_CalcViewBlend(); } /* @@ -1588,32 +1602,35 @@ int CL_ReadFromServer(void) CL_MoveParticles(); R_MoveExplosions(); - // process network entities (note: this sets up the view!) + // predict current player location CL_ClientMovement_Replay(); - cl.num_brushmodel_entities = 0; + // now that the player entity has been updated we can call V_CalcRefdef V_CalcRefdef(); - CL_UpdateEntities(); - - entitylinkframenumber++; - // link stuff - CL_RelinkWorld(); - CL_RelinkStaticEntities(); - CL_RelinkBeams(); - CL_RelinkEffects(); if(!csqc_loaded) //[515]: csqc { + // process network entities (note: this sets up the view!) + cl.num_brushmodel_entities = 0; + CL_UpdateEntities(); + + entitylinkframenumber++; + // link stuff + CL_RelinkWorld(); + CL_RelinkStaticEntities(); + CL_RelinkBeams(); + CL_RelinkEffects(); + CL_RelinkNetworkEntities(); CL_LinkNetworkEntity(&cl.viewent); // link gun model CL_RelinkQWNails(); + + // update view blend + V_CalcViewBlend(); } else csqc_frame = true; - // update view blend - V_CalcViewBlend(); - CL_UpdateLights(); CL_StairSmoothing(); diff --git a/csprogs.c b/csprogs.c index b77940cb..d2123853 100644 --- a/csprogs.c +++ b/csprogs.c @@ -110,7 +110,7 @@ void CL_VM_Error (const char *format, ...) //[515]: hope it will be never execut csqc_loaded = false; Mem_FreePool(&csqc_mempool); - Cvar_SetValueQuick(&csqc_progcrc, 0); + Cvar_SetValueQuick(&csqc_progcrc, -1); // Host_AbortCurrentFrame(); //[515]: hmmm... if server says it needs csqc then client MUST disconnect Host_Error(va("CL_VM_Error: %s", errorstring)); @@ -349,15 +349,18 @@ qboolean CL_VM_Parse_TempEntity (void) void CL_VM_Parse_StuffCmd (const char *msg) { - if(!csqc_loaded) //[515]: add more here if(msg[0] == 'c') if(msg[1] == 's') if(msg[2] == 'q') if(msg[3] == 'c') { - csqc_progcrc.flags = 0; + // if this is setting a csqc variable, deprotect csqc_progcrc + // temporarily so that it can be set by the cvar command, + // and then reprotect it afterwards + int flags = csqc_progcrc.flags; + csqc_progcrc.flags &= ~CVAR_READONLY; Cmd_ExecuteString (msg, src_command); - csqc_progcrc.flags = CVAR_READONLY; + csqc_progcrc.flags = flags; return; } if(!csqc_loaded || !CSQC_Parse_StuffCmd) @@ -483,37 +486,47 @@ void CL_VM_Init (void) { unsigned char *csprogsdata; fs_offset_t csprogsdatasize; - unsigned int csprogsdatacrc; + unsigned int csprogsdatacrc, requiredcrc; entity_t *ent; + // reset csqc_progcrc after reading it, so that changing servers doesn't + // expect csqc on the next server + requiredcrc = csqc_progcrc.integer; + Cvar_SetValueQuick(&csqc_progcrc, -1); + csqc_loaded = false; memset(cl.csqc_model_precache, 0, sizeof(cl.csqc_model_precache)); memset(&cl.csqc_vidvars, true, sizeof(csqc_vidvars_t)); // if the server is not requesting a csprogs, then we're done here - if (!csqc_progcrc.integer) + if (requiredcrc < 0) return; - // see if there is a csprogs.dat installed, and if so, set the csqc_progcrc accordingly, this will be sent to connecting clients to tell them to only load a matching csprogs.dat file - csprogsdatacrc = 0; + // see if the requested csprogs.dat file matches the requested crc + csprogsdatacrc = -1; csprogsdata = FS_LoadFile(csqc_progname.string, tempmempool, true, &csprogsdatasize); if (csprogsdata) { csprogsdatacrc = CRC_Block(csprogsdata, csprogsdatasize); Mem_Free(csprogsdata); - if(csprogsdatacrc != (unsigned short)csqc_progcrc.integer && !sv.active && !cls.demoplayback) + if (csprogsdatacrc != requiredcrc) { - Con_Printf("^1Your %s is not the same version as the server (CRC is %i but should be %i)\n", csqc_progname.string, prog->filecrc, csqc_progcrc.integer); - PRVM_ResetProg(); + if (cls.demoplayback) + Con_Printf("^1Your %s is not the same version as the demo was recorded with (CRC is %i but should be %i)\n", csqc_progname.string, csprogsdatacrc, requiredcrc); + else + Con_Printf("^1Your %s is not the same version as the server (CRC is %i but should be %i)\n", csqc_progname.string, csprogsdatacrc, requiredcrc); CL_Disconnect(); return; } } else { - if(!sv.active && csqc_progcrc.integer) + if (requiredcrc >= 0) { - Con_Printf("CL_VM_Init: server requires CSQC, but \"%s\" wasn't found\n", csqc_progname.string); + if (cls.demoplayback) + Con_Printf("CL_VM_Init: demo requires CSQC, but \"%s\" wasn't found\n", csqc_progname.string); + else + Con_Printf("CL_VM_Init: server requires CSQC, but \"%s\" wasn't found\n", csqc_progname.string); CL_Disconnect(); } return; @@ -540,16 +553,8 @@ void CL_VM_Init (void) PRVM_LoadProgs(csqc_progname.string, cl_numrequiredfunc, cl_required_func, 0, NULL); - if(!sv.active && !cls.demoplayback && prog->filecrc != (unsigned short)csqc_progcrc.integer) - { - Con_Printf("^1Your %s is not the same version as the server (CRC is %i but should be %i)\n", prog->filecrc, csqc_progcrc.integer); - PRVM_ResetProg(); - CL_Disconnect(); - return; - } - if(prog->loaded) - Con_Printf("CSQC ^5loaded (crc=%i)\n", csqc_progcrc.integer); + Con_Printf("CSQC ^5loaded (crc=%i)\n", csprogsdatacrc); else { CL_VM_Error("CSQC ^2failed to load\n"); @@ -594,7 +599,7 @@ void CL_VM_Init (void) void CL_VM_ShutDown (void) { Cmd_ClearCsqcFuncs(); - Cvar_SetValueQuick(&csqc_progcrc, 0); + Cvar_SetValueQuick(&csqc_progcrc, -1); if(!csqc_loaded) return; CSQC_BEGIN diff --git a/server.h b/server.h index df8a043b..974374ef 100644 --- a/server.h +++ b/server.h @@ -68,6 +68,10 @@ typedef struct server_s int lastcheck; double lastchecktime; + // crc of clientside progs at time of level start + int csqc_progcrc; // -1 = no progs + char csqc_progname[MAX_QPATH]; // copied from csqc_progname at level start + // map name char name[64]; // maps/.bsp, for model_precache[0] diff --git a/sv_main.c b/sv_main.c index 6f8d95d3..f31fb4e9 100644 --- a/sv_main.c +++ b/sv_main.c @@ -81,7 +81,7 @@ void SV_Init (void) { // init the csqc progs cvars, since they are updated/used by the server code // TODO: fix this since this is a quick hack to make some of [515]'s broken code run ;) [9/13/2006 Black] - extern cvar_t csqc_progname; + extern cvar_t csqc_progname; //[515]: csqc crc check and right csprogs name according to progs.dat extern cvar_t csqc_progcrc; Cvar_RegisterVariable (&csqc_progname); Cvar_RegisterVariable (&csqc_progcrc); @@ -299,8 +299,6 @@ CLIENT SPAWNING ============================================================================== */ -extern cvar_t csqc_progname; //[515]: csqc crc check and right csprogs name according to progs.dat -extern cvar_t csqc_progcrc; /* ================ SV_SendServerinfo @@ -349,16 +347,21 @@ void SV_SendServerinfo (client_t *client) MSG_WriteString (&client->netconnection->message,message); //[515]: init csprogs according to version of svprogs, check the crc, etc. - if (FS_FileExists(csqc_progname.string)) + if (sv.csqc_progcrc >= 0) { prvm_eval_t *val; - MSG_WriteByte (&client->netconnection->message, svc_stufftext); + Con_DPrintf("sending csqc info to client (\"%s\" with crc %i)\n", sv.csqc_progname, sv.csqc_progcrc); //[515]: init stufftext string (it is sent before svc_serverinfo) val = PRVM_GETGLOBALFIELDVALUE(PRVM_ED_FindGlobalOffset("SV_InitCmd")); + MSG_WriteByte (&client->netconnection->message, svc_stufftext); + MSG_WriteString (&client->netconnection->message, va("csqc_progname %s\n", sv.csqc_progname)); + MSG_WriteByte (&client->netconnection->message, svc_stufftext); + MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i\n", sv.csqc_progcrc)); if (val) - MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i\n%s\n", csqc_progcrc.integer, PRVM_GetString(val->string))); - else - MSG_WriteString (&client->netconnection->message, va("csqc_progcrc %i\n", csqc_progcrc.integer)); + { + MSG_WriteByte (&client->netconnection->message, svc_stufftext); + MSG_WriteString (&client->netconnection->message, va("%s\n", PRVM_GetString(val->string))); + } } MSG_WriteByte (&client->netconnection->message, svc_serverinfo); @@ -2356,9 +2359,10 @@ prvm_required_field_t reqfields[] = void SV_VM_Setup(void) { + extern cvar_t csqc_progname; //[515]: csqc crc check and right csprogs name according to progs.dat + extern cvar_t csqc_progcrc; unsigned char *csprogsdata; fs_offset_t csprogsdatasize; - unsigned int csprogsdatacrc; PRVM_Begin; PRVM_InitProg( PRVM_SERVERPROG ); @@ -2396,14 +2400,16 @@ void SV_VM_Setup(void) PRVM_End; // see if there is a csprogs.dat installed, and if so, set the csqc_progcrc accordingly, this will be sent to connecting clients to tell them to only load a matching csprogs.dat file - csprogsdatacrc = 0; + sv.csqc_progcrc = -1; + sv.csqc_progname[0] = 0; csprogsdata = FS_LoadFile(csqc_progname.string, tempmempool, true, &csprogsdatasize); if (csprogsdata) { - csprogsdatacrc = CRC_Block(csprogsdata, csprogsdatasize); + strlcpy(sv.csqc_progname, csqc_progname.string, sizeof(sv.csqc_progname)); + sv.csqc_progcrc = CRC_Block(csprogsdata, csprogsdatasize); Mem_Free(csprogsdata); + Con_DPrintf("server detected csqc progs file \"%s\" with crc %i\n", sv.csqc_progname, sv.csqc_progcrc); } - Cvar_SetValueQuick(&csqc_progcrc, csprogsdatacrc); } void SV_VM_Begin(void) -- 2.39.2