]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
fixed bug that caused csqc to only load after a map restart
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 6 Dec 2006 08:34:35 +0000 (08:34 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 6 Dec 2006 08:34:35 +0000 (08:34 +0000)
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
csprogs.c
server.h
sv_main.c

index 012de0db44fdb7e60075b7d471a373430131824b..50c185d634ced44d80bda2ed3262be7f66e7a3e7 100644 (file)
--- 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();
 
index b77940cbab089670fc59dfa59966929d2a2ed0d0..d212385312d6c03dacb5d3e7bcfa7b287b6ef12b 100644 (file)
--- 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
index df8a043b6d8a5b92c67aad7796c5797f914e6dd8..974374ef137f21713e5a0c3e18cd7ba6d5648fb8 100644 (file)
--- 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/<name>.bsp, for model_precache[0]
index 6f8d95d39d6cf61cc26a27112e3c663027b4f4cf..f31fb4e9cb0cbc02189ccc95e480c3490f038694 100644 (file)
--- 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)