X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=cl_parse.c;h=a76646ae73c8fed4deef43597bec14120dfe0278;hp=50c84767b4b1a36092bc848d33bc263d8c6dc22d;hb=c65b6faa99d227bcd00107311acfb66a95be02c6;hpb=0c1460315f5926dfb855b72acd12c6bebd148ebb diff --git a/cl_parse.c b/cl_parse.c index 50c84767..a76646ae 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -35,7 +35,7 @@ char *svc_strings[128] = "svc_stufftext", // [string] stuffed into client's console buffer // the string should be \n terminated "svc_setangle", // [vec3] set the view angle to this absolute value - + "svc_serverinfo", // [long] version // [string] signon string // [string]..[0]model cache [string]...[0]sounds cache @@ -48,11 +48,11 @@ char *svc_strings[128] = "svc_updatecolors", // [byte] [byte] "svc_particle", // [vec3] "svc_damage", // [byte] impact [byte] blood [vec3] from - + "svc_spawnstatic", "OBSOLETE svc_spawnbinary", "svc_spawnbaseline", - + "svc_temp_entity", // "svc_setpause", "svc_signonnum", @@ -67,7 +67,7 @@ char *svc_strings[128] = "svc_cutscene", "svc_showlmp", // [string] iconlabel [string] lmpfile [short] x [short] y "svc_hidelmp", // [string] iconlabel - "", // 37 + "svc_skybox", // [string] skyname "", // 38 "", // 39 "", // 40 @@ -80,26 +80,32 @@ char *svc_strings[128] = "", // 47 "", // 48 "", // 49 - "", // 50 - "svc_fog", // 51 - "svc_effect", // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate - "svc_effect2", // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate + "svc_cgame", // 50 // [short] length [bytes] data + "svc_fog", // 51 // unfinished and obsolete + "svc_effect", // 52 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate + "svc_effect2", // 53 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate + "svc_sound2", // 54 // short soundindex instead of byte + "svc_spawnbaseline2", // 55 // short modelindex instead of byte + "svc_spawnstatic2", // 56 // short modelindex instead of byte + "svc_entities", // 57 // [int] deltaframe [int] thisframe [float vector] eye [variable length] entitydata + "svc_unusedlh3", // 58 + "svc_spawnstaticsound2", // 59 // [coord3] [short] samp [byte] vol [byte] aten }; //============================================================================= -cvar_t demo_nehahra = {"demo_nehahra", "0"}; +cvar_t demo_nehahra = {0, "demo_nehahra", "0"}; void CL_Parse_Init(void) { // LordHavoc: added demo_nehahra cvar Cvar_RegisterVariable (&demo_nehahra); - if (nehahra) + if (gamemode == GAME_NEHAHRA) Cvar_SetValue("demo_nehahra", 1); } qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments -qboolean dpprotocol; // LordHavoc: whether or not the current network stream is the enhanced DarkPlaces protocol +int dpprotocol; // LordHavoc: version of network protocol, or 0 if not DarkPlaces /* =============== @@ -174,7 +180,7 @@ void CL_ParseStartSoundPacket(int largesoundindex) for (i=0 ; i<3 ; i++) pos[i] = MSG_ReadCoord (); - + S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation); } @@ -243,17 +249,14 @@ void CL_ParseEntityLump(char *entdata) { char *data; char key[128], value[4096]; - char wadname[128]; - int i, j, k; FOG_clear(); // LordHavoc: no fog until set - skyname[0] = 0; // LordHavoc: no enviroment mapped sky until set - r_farclip.value = 6144; // LordHavoc: default farclip distance + R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set data = entdata; if (!data) return; data = COM_Parse(data); if (!data) - return; // valid exit + return; // error if (com_token[0] != '{') return; // error while (1) @@ -262,8 +265,11 @@ void CL_ParseEntityLump(char *entdata) if (!data) return; // error if (com_token[0] == '}') - return; // since we're just parsing the first ent (worldspawn), exit - strcpy(key, com_token); + break; // end of worldspawn + if (com_token[0] == '_') + strcpy(key, com_token + 1); + else + strcpy(key, com_token); while (key[strlen(key)-1] == ' ') // remove trailing spaces key[strlen(key)-1] = 0; data = COM_Parse(data); @@ -276,17 +282,8 @@ void CL_ParseEntityLump(char *entdata) R_SetSkyBox(value); else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK) R_SetSkyBox(value); - else if (!strcmp("farclip", key)) - { - r_farclip.value = atof(value); - if (r_farclip.value < 64) - r_farclip.value = 64; - } else if (!strcmp("fog", key)) - { - scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue); - j = 0; - } + sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue); else if (!strcmp("fog_density", key)) fog_density = atof(value); else if (!strcmp("fog_red", key)) @@ -295,36 +292,56 @@ void CL_ParseEntityLump(char *entdata) fog_green = atof(value); else if (!strcmp("fog_blue", key)) fog_blue = atof(value); - else if (!strcmp("wad", key)) // for HalfLife maps + } +} + +/* +===================== +CL_SignonReply + +An svc_signonnum has been received, perform a client side setup +===================== +*/ +static void CL_SignonReply (void) +{ + char str[8192]; + +Con_DPrintf ("CL_SignonReply: %i\n", cls.signon); + + switch (cls.signon) + { + case 1: + MSG_WriteByte (&cls.message, clc_stringcmd); + MSG_WriteString (&cls.message, "prespawn"); + break; + + case 2: + MSG_WriteByte (&cls.message, clc_stringcmd); + MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string)); + + MSG_WriteByte (&cls.message, clc_stringcmd); + MSG_WriteString (&cls.message, va("color %i %i\n", cl_color.integer >> 4, cl_color.integer & 15)); + + if (cl_pmodel.integer) { - if (hlbsp) - { - j = 0; - for (i = 0;i < 4096;i++) - if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':') - break; - if (value[i]) - { - for (;i < 4096;i++) - { - // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'... - if (value[i] == '\\' || value[i] == '/' || value[i] == ':') - j = i+1; - else if (value[i] == ';' || value[i] == 0) - { - k = value[i]; - value[i] = 0; - strcpy(wadname, "textures/"); - strcat(wadname, &value[j]); - W_LoadTextureWadFile (wadname, false); - j = i+1; - if (!k) - break; - } - } - } - } + MSG_WriteByte (&cls.message, clc_stringcmd); + MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer)); } + + MSG_WriteByte (&cls.message, clc_stringcmd); + sprintf (str, "spawn %s", cls.spawnparms); + MSG_WriteString (&cls.message, str); + break; + + case 3: + MSG_WriteByte (&cls.message, clc_stringcmd); + MSG_WriteString (&cls.message, "begin"); + break; + + case 4: +// SCR_EndLoadingPlaque (); // allow normal screen updates + Con_ClearNotify(); + break; } } @@ -340,7 +357,7 @@ void CL_ParseServerInfo (void) int nummodels, numsounds; char model_precache[MAX_MODELS][MAX_QPATH]; char sound_precache[MAX_SOUNDS][MAX_QPATH]; - + Con_DPrintf ("Serverinfo packet received.\n"); // // wipe the client_state_t struct @@ -349,17 +366,19 @@ void CL_ParseServerInfo (void) // parse protocol version number i = MSG_ReadLong (); - if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250) + if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250) { - Con_Printf ("Server returned version %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION); + Con_Printf ("Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION); return; } Nehahrademcompatibility = false; if (i == 250) Nehahrademcompatibility = true; - if (cls.demoplayback && demo_nehahra.value) + if (cls.demoplayback && demo_nehahra.integer) Nehahrademcompatibility = true; - dpprotocol = i == DPPROTOCOL_VERSION; + dpprotocol = i; + if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2) + dpprotocol = 0; // parse maxclients cl.maxclients = MSG_ReadByte (); @@ -368,7 +387,7 @@ void CL_ParseServerInfo (void) Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients); return; } - cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores"); + cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores)); // parse gametype cl.gametype = MSG_ReadByte (); @@ -390,6 +409,10 @@ void CL_ParseServerInfo (void) // needlessly purge it // + Mem_CheckSentinelsGlobal(); + + Mod_ClearUsed(); + // precache models memset (cl.model_precache, 0, sizeof(cl.model_precache)); for (nummodels=1 ; ; nummodels++) @@ -399,7 +422,7 @@ void CL_ParseServerInfo (void) break; if (nummodels==MAX_MODELS) { - Con_Printf ("Server sent too many model precaches\n"); + Host_Error ("Server sent too many model precaches\n"); return; } if (strlen(str) >= MAX_QPATH) @@ -417,7 +440,7 @@ void CL_ParseServerInfo (void) break; if (numsounds==MAX_SOUNDS) { - Con_Printf ("Server sent too many sound precaches\n"); + Host_Error ("Server sent too many sound precaches\n"); return; } if (strlen(str) >= MAX_QPATH) @@ -426,22 +449,29 @@ void CL_ParseServerInfo (void) S_TouchSound (str); } + Mod_PurgeUnused(); + // // now we try to load everything else until a cache allocation fails // + Mem_CheckSentinelsGlobal(); + for (i=1 ; i cl.maxclients (%i)", s->colormap, cl.maxclients); model = cl.model_precache[s->modelindex]; + Mod_CheckLoaded(model); if (model && s->frame >= model->numframes) { - Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name); + Con_Printf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name); s->frame = 0; } + if (model && s->skin > 0 && s->skin >= model->numskins) + { + Con_Printf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name); + s->skin = 0; + } } /* @@ -498,12 +539,7 @@ void CL_ParseUpdate (int bits) { int i, num, deltadie; entity_t *ent; - - if (cls.signon == SIGNONS - 1) - { // first update is the final signon stage - cls.signon = SIGNONS; - CL_SignonReply (); - } + entity_state_t new; if (bits & U_MOREBITS) bits |= (MSG_ReadByte()<<8); @@ -514,7 +550,7 @@ void CL_ParseUpdate (int bits) bits |= MSG_ReadByte() << 24; } - if (bits & U_LONGENTITY) + if (bits & U_LONGENTITY) num = (unsigned) MSG_ReadShort (); else num = (unsigned) MSG_ReadByte (); @@ -534,43 +570,48 @@ void CL_ParseUpdate (int bits) bitprofile[i]++; bitprofilecount++; - ent->state_previous = ent->state_current; deltadie = false; if (bits & U_DELTA) { - if (!ent->state_current.active) + new = ent->state_current; + if (!new.active) deltadie = true; // was not present in previous frame, leave hidden until next full update } else - ent->state_current = ent->state_baseline; - - ent->state_current.time = cl.mtime[0]; - - ent->state_current.flags = 0; - ent->state_current.active = true; - if (bits & U_MODEL) ent->state_current.modelindex = (ent->state_current.modelindex & 0xFF00) | MSG_ReadByte(); - if (bits & U_FRAME) ent->state_current.frame = (ent->state_current.frame & 0xFF00) | MSG_ReadByte(); - if (bits & U_COLORMAP) ent->state_current.colormap = MSG_ReadByte(); - if (bits & U_SKIN) ent->state_current.skin = MSG_ReadByte(); - if (bits & U_EFFECTS) ent->state_current.effects = (ent->state_current.effects & 0xFF00) | MSG_ReadByte(); - if (bits & U_ORIGIN1) ent->state_current.origin[0] = MSG_ReadCoord(); - if (bits & U_ANGLE1) ent->state_current.angles[0] = MSG_ReadAngle(); - if (bits & U_ORIGIN2) ent->state_current.origin[1] = MSG_ReadCoord(); - if (bits & U_ANGLE2) ent->state_current.angles[1] = MSG_ReadAngle(); - if (bits & U_ORIGIN3) ent->state_current.origin[2] = MSG_ReadCoord(); - if (bits & U_ANGLE3) ent->state_current.angles[2] = MSG_ReadAngle(); - if (bits & U_STEP) ent->state_current.flags |= RENDER_STEP; - if (bits & U_ALPHA) ent->state_current.alpha = MSG_ReadByte(); - if (bits & U_SCALE) ent->state_current.scale = MSG_ReadByte(); - if (bits & U_EFFECTS2) ent->state_current.effects = (ent->state_current.effects & 0x00FF) | (MSG_ReadByte() << 8); - if (bits & U_GLOWSIZE) ent->state_current.glowsize = MSG_ReadByte(); - if (bits & U_GLOWCOLOR) ent->state_current.glowcolor = MSG_ReadByte(); - if (bits & U_GLOWTRAIL) ent->state_current.flags |= RENDER_GLOWTRAIL; - if (bits & U_COLORMOD) ent->state_current.colormod = MSG_ReadByte(); - if (bits & U_FRAME2) ent->state_current.frame = (ent->state_current.frame & 0x00FF) | (MSG_ReadByte() << 8); - if (bits & U_MODEL2) ent->state_current.modelindex = (ent->state_current.modelindex & 0x00FF) | (MSG_ReadByte() << 8); - if (bits & U_VIEWMODEL) ent->state_current.flags |= RENDER_VIEWMODEL; - if (bits & U_EXTERIORMODEL) ent->state_current.flags |= RENDER_EXTERIORMODEL; + new = ent->state_baseline; + + new.time = cl.mtime[0]; + + new.flags = 0; + new.active = true; + if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte(); + if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte(); + if (bits & U_COLORMAP) new.colormap = MSG_ReadByte(); + if (bits & U_SKIN) new.skin = MSG_ReadByte(); + if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte(); + if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord(); + if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle(); + if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord(); + if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle(); + if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord(); + if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle(); + if (bits & U_STEP) new.flags |= RENDER_STEP; + if (bits & U_ALPHA) new.alpha = MSG_ReadByte(); + if (bits & U_SCALE) new.scale = MSG_ReadByte(); + if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8); + if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte(); + if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte(); +#if 0 + if (bits & U_COLORMOD) {int i = MSG_ReadByte();float r = (((int) i >> 5) & 7) * 1.0 / 7, g = (((int) i >> 2) & 7) * 1.0 / 7, b = ((int) i & 3) * 1.0 / 3;Con_Printf("warning: U_COLORMOD %i (%1.2f %1.2f %1.2f) ignored\n", i, r, g, b);} +#else + // apparently the dpcrush demo uses this (unintended, and it uses white anyway) + if (bits & U_COLORMOD) MSG_ReadByte(); +#endif + if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL; + if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8); + if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8); + if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL; + if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL; // LordHavoc: to allow playback of the Nehahra movie if (Nehahrademcompatibility && (bits & U_EXTEND1)) @@ -581,47 +622,67 @@ void CL_ParseUpdate (int bits) if (i == 2) { if (MSG_ReadFloat()) - ent->state_current.effects |= EF_FULLBRIGHT; + new.effects |= EF_FULLBRIGHT; } if (j < 0) - ent->state_current.alpha = 0; + new.alpha = 0; else if (j == 0 || j >= 255) - ent->state_current.alpha = 255; + new.alpha = 255; else - ent->state_current.alpha = j; + new.alpha = j; } if (deltadie) { // hide the entity - ent->state_current.active = false; + new.active = false; } else - { - CL_ValidateState(&ent->state_current); + CL_ValidateState(&new); - /* - if (!ent->state_current.active) + if (new.flags & RENDER_STEP) // FIXME: rename this flag? + { + // make time identical for memcmp + new.time = ent->state_current.time; + if (memcmp(&new, &ent->state_current, sizeof(entity_state_t))) { - if (bits & U_DELTA) - { - if (bits & U_MODEL) - Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i %i\n", num, ent->state_previous.modelindex, ent->state_current.modelindex); - else - Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i\n", num, ent->state_previous.modelindex); - } - else - { - if (bits & U_MODEL) - Con_Printf("CL_ParseUpdate: NULL model on %i: %i %i\n", num, ent->state_baseline.modelindex, ent->state_current.modelindex); - else - Con_Printf("CL_ParseUpdate: NULL model on %i: %i\n", num, ent->state_baseline.modelindex); - } + // set it back to what it should be + new.time = cl.mtime[0] + 0.1; + // state has changed + ent->state_previous = ent->state_current; + ent->state_current = new; + // assume 10fps animation + //ent->state_previous.time = cl.mtime[0] - 0.1; } - */ + } + else + { + ent->state_previous = ent->state_current; + ent->state_current = new; } } +void CL_ReadEntityFrame(void) +{ + entity_t *ent; + entity_state_t *s; + entity_frame_t entityframe; + int i; + EntityFrame_Read(&cl.entitydatabase); + EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe); + for (i = 0;i < entityframe.numentities;i++) + { + s = &entityframe.entitydata[i]; + entkill[s->number] = 0; + ent = &cl_entities[s->number]; + memcpy(&ent->state_previous, &ent->state_current, sizeof(*s)); + memcpy(&ent->state_current, s, sizeof(*s)); + ent->state_current.time = cl.mtime[0]; + } + VectorCopy(cl.viewentoriginnew, cl.viewentoriginold); + VectorCopy(entityframe.eye, cl.viewentoriginnew); +} + char *bitprofilenames[32] = { "U_MOREBITS", @@ -646,7 +707,7 @@ char *bitprofilenames[32] = "U_EFFECTS2", "U_GLOWSIZE", "U_GLOWCOLOR", - "U_COLORMOD", + "obsolete U_COLORMOD", "U_EXTEND2", "U_GLOWTRAIL", "U_VIEWMODEL", @@ -717,7 +778,6 @@ void CL_ParseBaseline (entity_t *ent, int large) ent->state_baseline.scale = 16; ent->state_baseline.glowsize = 0; ent->state_baseline.glowcolor = 254; - ent->state_baseline.colormod = 255; ent->state_previous = ent->state_current = ent->state_baseline; CL_ValidateState(&ent->state_baseline); @@ -750,7 +810,7 @@ void CL_ParseClientdata (int bits) cl.idealpitch = MSG_ReadChar (); else cl.idealpitch = 0; - + VectorCopy (cl.mvelocity[0], cl.mvelocity[1]); for (i=0 ; i<3 ; i++) { @@ -764,7 +824,7 @@ void CL_ParseClientdata (int bits) else cl.punchangle[i] = 0; if (bits & (SU_PUNCHVEC1<= MAX_STATIC_ENTITIES) Host_Error ("Too many static entities"); ent = &cl_static_entities[cl.num_statics++]; @@ -822,16 +894,14 @@ void CL_ParseStatic (int large) ent->render.model = cl.model_precache[ent->state_baseline.modelindex]; ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame; ent->render.framelerp = 0; - ent->render.lerp_starttime = -1; // make torchs play out of sync - ent->render.frame1start = ent->render.frame2start = -(rand() & 32767); + ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1); ent->render.colormap = -1; // no special coloring ent->render.skinnum = ent->state_baseline.skin; ent->render.effects = ent->state_baseline.effects; ent->render.alpha = 1; ent->render.scale = 1; ent->render.alpha = 1; - ent->render.colormod[0] = ent->render.colormod[1] = ent->render.colormod[2] = 1; VectorCopy (ent->state_baseline.origin, ent->render.origin); VectorCopy (ent->state_baseline.angles, ent->render.angles); @@ -854,7 +924,7 @@ void CL_ParseStaticSound (int large) sound_num = MSG_ReadByte (); vol = MSG_ReadByte (); atten = MSG_ReadByte (); - + S_StaticSound (cl.sound_precache[sound_num], org, vol, atten); } @@ -887,7 +957,9 @@ void CL_ParseEffect2 (void) } -#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); +#define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); + +static byte cgamenetbuffer[65536]; /* ===================== @@ -901,16 +973,16 @@ void CL_ParseServerMessage (void) byte cmdlog[32]; char *cmdlogname[32], *temp; int cmdindex, cmdcount = 0; - + // // if recording demos, copy the message out // - if (cl_shownet.value == 1) + if (cl_shownet.integer == 1) Con_Printf ("%i ",net_message.cursize); - else if (cl_shownet.value == 2) + else if (cl_shownet.integer == 2) Con_Printf ("------------------\n"); - - cl.onground = false; // unless the server says otherwise + + cl.onground = false; // unless the server says otherwise // // parse the message // @@ -918,7 +990,7 @@ void CL_ParseServerMessage (void) entitiesupdated = false; CL_EntityUpdateSetup(); - + while (1) { if (msg_badread) @@ -943,6 +1015,11 @@ void CL_ParseServerMessage (void) temp = "entity"; cmdlogname[cmdindex] = temp; SHOWNET("fast update"); + if (cls.signon == SIGNONS - 1) + { // first update is the final signon stage + cls.signon = SIGNONS; + CL_SignonReply (); + } CL_ParseUpdate (cmd&127); continue; } @@ -955,7 +1032,7 @@ void CL_ParseServerMessage (void) temp = ""; cmdlogname[cmdindex] = temp; } - + // other commands switch (cmd) { @@ -978,72 +1055,74 @@ void CL_ParseServerMessage (void) i &= 31; } description[strlen(description)-1] = '\n'; // replace the last space with a newline - Con_Printf(description); + Con_Printf("%s", description); Host_Error ("CL_ParseServerMessage: Illegible server message\n"); } break; - + case svc_nop: // Con_Printf ("svc_nop\n"); break; - + case svc_time: // handle old protocols which do not have entity update ranges entitiesupdated = true; cl.mtime[1] = cl.mtime[0]; - cl.mtime[0] = MSG_ReadFloat (); + cl.mtime[0] = MSG_ReadFloat (); break; - + case svc_clientdata: i = MSG_ReadShort (); CL_ParseClientdata (i); break; - + case svc_version: i = MSG_ReadLong (); - if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250) - Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION); + if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != 250) + Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, PROTOCOL_VERSION); Nehahrademcompatibility = false; if (i == 250) Nehahrademcompatibility = true; - if (cls.demoplayback && demo_nehahra.value) + if (cls.demoplayback && demo_nehahra.integer) Nehahrademcompatibility = true; - dpprotocol = i == DPPROTOCOL_VERSION; + dpprotocol = i; + if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2) + dpprotocol = 0; break; - + case svc_disconnect: Host_EndGame ("Server disconnected\n"); case svc_print: Con_Printf ("%s", MSG_ReadString ()); break; - + case svc_centerprint: SCR_CenterPrint (MSG_ReadString ()); break; - + case svc_stufftext: Cbuf_AddText (MSG_ReadString ()); break; - + case svc_damage: V_ParseDamage (); break; - + case svc_serverinfo: CL_ParseServerInfo (); - vid.recalc_refdef = true; // leave intermission full screen +// vid.recalc_refdef = true; // leave intermission full screen break; - + case svc_setangle: for (i=0 ; i<3 ; i++) cl.viewangles[i] = MSG_ReadAngle (); break; - + case svc_setview: cl.viewentity = MSG_ReadShort (); break; - + case svc_lightstyle: i = MSG_ReadByte (); if (i >= MAX_LIGHTSTYLES) @@ -1052,7 +1131,7 @@ void CL_ParseServerMessage (void) cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0; cl_lightstyle[i].length = strlen(cl_lightstyle[i].map); break; - + case svc_sound: CL_ParseStartSoundPacket(false); break; @@ -1065,30 +1144,30 @@ void CL_ParseServerMessage (void) i = MSG_ReadShort(); S_StopSound(i>>3, i&7); break; - + case svc_updatename: i = MSG_ReadByte (); if (i >= cl.maxclients) - Host_Error ("CL_ParseServerMessage: svc_updatename >= MAX_SCOREBOARD"); + Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients"); strcpy (cl.scores[i].name, MSG_ReadString ()); break; - + case svc_updatefrags: i = MSG_ReadByte (); if (i >= cl.maxclients) - Host_Error ("CL_ParseServerMessage: svc_updatefrags >= MAX_SCOREBOARD"); + Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients"); cl.scores[i].frags = MSG_ReadShort (); - break; + break; case svc_updatecolors: i = MSG_ReadByte (); if (i >= cl.maxclients) - Host_Error ("CL_ParseServerMessage: svc_updatecolors >= MAX_SCOREBOARD"); + Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients"); cl.scores[i].colors = MSG_ReadByte (); break; - + case svc_particle: - R_ParseParticleEffect (); + CL_ParseParticleEffect (); break; case svc_effect: @@ -1126,7 +1205,7 @@ void CL_ParseServerMessage (void) else CDAudio_Resume (); break; - + case svc_signonnum: i = MSG_ReadByte (); if (i <= cls.signon) @@ -1149,7 +1228,7 @@ void CL_ParseServerMessage (void) Host_Error ("svc_updatestat: %i is invalid", i); cl.stats[i] = MSG_ReadLong (); break; - + case svc_spawnstaticsound: CL_ParseStaticSound (false); break; @@ -1170,21 +1249,21 @@ void CL_ParseServerMessage (void) case svc_intermission: cl.intermission = 1; cl.completed_time = cl.time; - vid.recalc_refdef = true; // go to full screen +// vid.recalc_refdef = true; // go to full screen break; case svc_finale: cl.intermission = 2; cl.completed_time = cl.time; - vid.recalc_refdef = true; // go to full screen - SCR_CenterPrint (MSG_ReadString ()); +// vid.recalc_refdef = true; // go to full screen + SCR_CenterPrint (MSG_ReadString ()); break; case svc_cutscene: cl.intermission = 3; cl.completed_time = cl.time; - vid.recalc_refdef = true; // go to full screen - SCR_CenterPrint (MSG_ReadString ()); +// vid.recalc_refdef = true; // go to full screen + SCR_CenterPrint (MSG_ReadString ()); break; case svc_sellscreen: @@ -1196,6 +1275,36 @@ void CL_ParseServerMessage (void) case svc_showlmp: SHOWLMP_decodeshow(); break; + case svc_skybox: + R_SetSkyBox(MSG_ReadString()); + break; + case svc_cgame: + { + int length; + length = (int) ((unsigned short) MSG_ReadShort()); + /* + if (cgamenetbuffersize < length) + { + cgamenetbuffersize = length; + if (cgamenetbuffer) + Mem_Free(cgamenetbuffer); + cgamenetbuffer = Mem_Alloc(cgamenetbuffersize); + } + */ + for (i = 0;i < length;i++) + cgamenetbuffer[i] = MSG_ReadByte(); + if (!msg_badread) + CL_CGVM_ParseNetwork(cgamenetbuffer, length); + } + break; + case svc_entities: + if (cls.signon == SIGNONS - 1) + { // first update is the final signon stage + cls.signon = SIGNONS; + CL_SignonReply (); + } + CL_ReadEntityFrame(); + break; } }