2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // cl_parse.c -- parse a message received from the server
24 char *svc_strings[128] =
30 "svc_version", // [long] server version
31 "svc_setview", // [short] entity number
32 "svc_sound", // <see code>
33 "svc_time", // [float] server time
34 "svc_print", // [string] null terminated string
35 "svc_stufftext", // [string] stuffed into client's console buffer
36 // the string should be \n terminated
37 "svc_setangle", // [vec3] set the view angle to this absolute value
39 "svc_serverinfo", // [long] version
40 // [string] signon string
41 // [string]..[0]model cache [string]...[0]sounds cache
42 // [string]..[0]item cache
43 "svc_lightstyle", // [byte] [string]
44 "svc_updatename", // [byte] [string]
45 "svc_updatefrags", // [byte] [short]
46 "svc_clientdata", // <shortbits + data>
47 "svc_stopsound", // <see code>
48 "svc_updatecolors", // [byte] [byte]
49 "svc_particle", // [vec3] <variable>
50 "svc_damage", // [byte] impact [byte] blood [vec3] from
53 "OBSOLETE svc_spawnbinary",
56 "svc_temp_entity", // <variable>
62 "svc_spawnstaticsound",
64 "svc_finale", // [string] music [string] text
65 "svc_cdtrack", // [byte] track [byte] looptrack
68 "svc_showlmp", // [string] iconlabel [string] lmpfile [short] x [short] y
69 "svc_hidelmp", // [string] iconlabel
70 "svc_skybox", // [string] skyname
85 "svc_effect", // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
86 "svc_effect2", // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
89 //=============================================================================
91 cvar_t demo_nehahra = {0, "demo_nehahra", "0"};
93 void CL_Parse_Init(void)
95 // LordHavoc: added demo_nehahra cvar
96 Cvar_RegisterVariable (&demo_nehahra);
98 Cvar_SetValue("demo_nehahra", 1);
101 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
102 qboolean dpprotocol; // LordHavoc: whether or not the current network stream is the enhanced DarkPlaces protocol
108 This error checks and tracks the total number of entities
111 entity_t *CL_EntityNum (int num)
114 if (num >= cl.num_entities)
116 if (num >= MAX_EDICTS)
117 Host_Error ("CL_EntityNum: %i is an invalid number",num);
118 cl.num_entities = num;
119 // while (cl.num_entities <= num)
121 // cl_entities[cl.num_entities].colormap = -1; // no special coloring
122 // cl.num_entities++;
126 if (num >= MAX_EDICTS)
127 Host_Error ("CL_EntityNum: %i is an invalid number",num);
129 return &cl_entities[num];
135 CL_ParseStartSoundPacket
138 void CL_ParseStartSoundPacket(int largesoundindex)
148 field_mask = MSG_ReadByte();
150 if (field_mask & SND_VOLUME)
151 volume = MSG_ReadByte ();
153 volume = DEFAULT_SOUND_PACKET_VOLUME;
155 if (field_mask & SND_ATTENUATION)
156 attenuation = MSG_ReadByte () / 64.0;
158 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
160 channel = MSG_ReadShort ();
162 sound_num = (unsigned short) MSG_ReadShort ();
164 sound_num = MSG_ReadByte ();
166 if (sound_num >= MAX_SOUNDS)
167 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
172 if (ent > MAX_EDICTS)
173 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
175 for (i=0 ; i<3 ; i++)
176 pos[i] = MSG_ReadCoord ();
178 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
185 When the client is taking a long time to load stuff, send keepalive messages
186 so the server doesn't disconnect.
189 void CL_KeepaliveMessage (void)
192 static float lastmsg;
198 return; // no need if server is local
199 if (cls.demoplayback)
202 // read messages from server, should just be nops
204 memcpy (olddata, net_message.data, net_message.cursize);
208 ret = CL_GetMessage ();
212 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
214 break; // nothing waiting
216 Host_Error ("CL_KeepaliveMessage: received a message");
219 if (MSG_ReadByte() != svc_nop)
220 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
226 memcpy (net_message.data, olddata, net_message.cursize);
229 time = Sys_DoubleTime ();
230 if (time - lastmsg < 5)
235 Con_Printf ("--> client to server keepalive\n");
237 MSG_WriteByte (&cls.message, clc_nop);
238 NET_SendMessage (cls.netcon, &cls.message);
239 SZ_Clear (&cls.message);
242 void CL_ParseEntityLump(char *entdata)
245 char key[128], value[4096];
248 FOG_clear(); // LordHavoc: no fog until set
249 R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
250 r_farclip.value = 6144; // LordHavoc: default farclip distance
254 data = COM_Parse(data);
256 return; // valid exit
257 if (com_token[0] != '{')
261 data = COM_Parse(data);
264 if (com_token[0] == '}')
265 return; // since we're just parsing the first ent (worldspawn), exit
266 strcpy(key, com_token);
267 while (key[strlen(key)-1] == ' ') // remove trailing spaces
268 key[strlen(key)-1] = 0;
269 data = COM_Parse(data);
272 strcpy(value, com_token);
273 if (!strcmp("sky", key))
275 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
277 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
279 else if (!strcmp("farclip", key))
281 r_farclip.value = atof(value);
282 if (r_farclip.value < 64)
283 r_farclip.value = 64;
285 else if (!strcmp("fog", key))
287 scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
290 else if (!strcmp("fog_density", key))
291 fog_density = atof(value);
292 else if (!strcmp("fog_red", key))
293 fog_red = atof(value);
294 else if (!strcmp("fog_green", key))
295 fog_green = atof(value);
296 else if (!strcmp("fog_blue", key))
297 fog_blue = atof(value);
298 else if (!strcmp("wad", key)) // for HalfLife maps
303 for (i = 0;i < 4096;i++)
304 if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':')
310 // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
311 if (value[i] == '\\' || value[i] == '/' || value[i] == ':')
313 else if (value[i] == ';' || value[i] == 0)
317 strcpy(wadname, "textures/");
318 strcat(wadname, &value[j]);
319 W_LoadTextureWadFile (wadname, false);
336 void CL_ParseServerInfo (void)
340 int nummodels, numsounds;
341 char model_precache[MAX_MODELS][MAX_QPATH];
342 char sound_precache[MAX_SOUNDS][MAX_QPATH];
344 Con_DPrintf ("Serverinfo packet received.\n");
346 // wipe the client_state_t struct
350 // parse protocol version number
352 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
354 Con_Printf ("Server returned version %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
357 Nehahrademcompatibility = false;
359 Nehahrademcompatibility = true;
360 if (cls.demoplayback && demo_nehahra.value)
361 Nehahrademcompatibility = true;
362 dpprotocol = i == DPPROTOCOL_VERSION;
365 cl.maxclients = MSG_ReadByte ();
366 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
368 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
371 cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
374 cl.gametype = MSG_ReadByte ();
376 // parse signon message
377 str = MSG_ReadString ();
378 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
380 // seperate the printfs so the server message can have a color
381 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
383 Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
384 Con_Printf ("%c%s\n", 2, str);
388 // first we go through and touch all of the precache data that still
389 // happens to be in the cache, so precaching something else doesn't
390 // needlessly purge it
396 memset (cl.model_precache, 0, sizeof(cl.model_precache));
397 for (nummodels=1 ; ; nummodels++)
399 str = MSG_ReadString ();
402 if (nummodels==MAX_MODELS)
404 Con_Printf ("Server sent too many model precaches\n");
407 if (strlen(str) >= MAX_QPATH)
408 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
409 strcpy (model_precache[nummodels], str);
410 Mod_TouchModel (str);
417 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
418 for (numsounds=1 ; ; numsounds++)
420 str = MSG_ReadString ();
423 if (numsounds==MAX_SOUNDS)
425 Con_Printf ("Server sent too many sound precaches\n");
428 if (strlen(str) >= MAX_QPATH)
429 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
430 strcpy (sound_precache[numsounds], str);
435 // now we try to load everything else until a cache allocation fails
440 for (i=1 ; i<nummodels ; i++)
442 isworldmodel = i == 1; // LordHavoc: first model is the world model
443 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
447 if (cl.model_precache[i] == NULL)
449 Con_Printf("Model %s not found\n", model_precache[i]);
452 CL_KeepaliveMessage ();
457 S_BeginPrecaching ();
458 for (i=1 ; i<numsounds ; i++)
460 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
461 CL_KeepaliveMessage ();
467 cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
473 Hunk_Check (); // make sure nothing is hurt
475 noclip_anglehack = false; // noclip is turned off at start
478 void CL_ValidateState(entity_state_t *s)
485 if (s->modelindex >= MAX_MODELS)
486 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
488 // colormap is client index + 1
489 if (s->colormap > cl.maxclients)
490 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
492 model = cl.model_precache[s->modelindex];
493 if (model && s->frame >= model->numframes)
495 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
504 Parse an entity update message from the server
505 If an entities model or origin changes from frame to frame, it must be
506 relinked. Other attributes can change without relinking.
509 byte entkill[MAX_EDICTS];
510 int bitprofile[32], bitprofilecount = 0;
511 void CL_ParseUpdate (int bits)
513 int i, num, deltadie;
516 if (cls.signon == SIGNONS - 1)
517 { // first update is the final signon stage
518 cls.signon = SIGNONS;
522 if (bits & U_MOREBITS)
523 bits |= (MSG_ReadByte()<<8);
524 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
526 bits |= MSG_ReadByte() << 16;
527 if (bits & U_EXTEND2)
528 bits |= MSG_ReadByte() << 24;
531 if (bits & U_LONGENTITY)
532 num = (unsigned) MSG_ReadShort ();
534 num = (unsigned) MSG_ReadByte ();
536 if (num >= MAX_EDICTS)
537 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
539 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
541 // mark as visible (no kill)
544 ent = CL_EntityNum (num);
546 for (i = 0;i < 32;i++)
551 ent->state_previous = ent->state_current;
555 if (!ent->state_current.active)
556 deltadie = true; // was not present in previous frame, leave hidden until next full update
559 ent->state_current = ent->state_baseline;
561 ent->state_current.time = cl.mtime[0];
563 ent->state_current.flags = 0;
564 ent->state_current.active = true;
565 if (bits & U_MODEL) ent->state_current.modelindex = (ent->state_current.modelindex & 0xFF00) | MSG_ReadByte();
566 if (bits & U_FRAME) ent->state_current.frame = (ent->state_current.frame & 0xFF00) | MSG_ReadByte();
567 if (bits & U_COLORMAP) ent->state_current.colormap = MSG_ReadByte();
568 if (bits & U_SKIN) ent->state_current.skin = MSG_ReadByte();
569 if (bits & U_EFFECTS) ent->state_current.effects = (ent->state_current.effects & 0xFF00) | MSG_ReadByte();
570 if (bits & U_ORIGIN1) ent->state_current.origin[0] = MSG_ReadCoord();
571 if (bits & U_ANGLE1) ent->state_current.angles[0] = MSG_ReadAngle();
572 if (bits & U_ORIGIN2) ent->state_current.origin[1] = MSG_ReadCoord();
573 if (bits & U_ANGLE2) ent->state_current.angles[1] = MSG_ReadAngle();
574 if (bits & U_ORIGIN3) ent->state_current.origin[2] = MSG_ReadCoord();
575 if (bits & U_ANGLE3) ent->state_current.angles[2] = MSG_ReadAngle();
576 if (bits & U_STEP) ent->state_current.flags |= RENDER_STEP;
577 if (bits & U_ALPHA) ent->state_current.alpha = MSG_ReadByte();
578 if (bits & U_SCALE) ent->state_current.scale = MSG_ReadByte();
579 if (bits & U_EFFECTS2) ent->state_current.effects = (ent->state_current.effects & 0x00FF) | (MSG_ReadByte() << 8);
580 if (bits & U_GLOWSIZE) ent->state_current.glowsize = MSG_ReadByte();
581 if (bits & U_GLOWCOLOR) ent->state_current.glowcolor = MSG_ReadByte();
582 if (bits & U_GLOWTRAIL) ent->state_current.flags |= RENDER_GLOWTRAIL;
583 if (bits & U_COLORMOD) ent->state_current.colormod = MSG_ReadByte();
584 if (bits & U_FRAME2) ent->state_current.frame = (ent->state_current.frame & 0x00FF) | (MSG_ReadByte() << 8);
585 if (bits & U_MODEL2) ent->state_current.modelindex = (ent->state_current.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
586 if (bits & U_VIEWMODEL) ent->state_current.flags |= RENDER_VIEWMODEL;
587 if (bits & U_EXTERIORMODEL) ent->state_current.flags |= RENDER_EXTERIORMODEL;
589 // LordHavoc: to allow playback of the Nehahra movie
590 if (Nehahrademcompatibility && (bits & U_EXTEND1))
592 // LordHavoc: evil format
593 int i = MSG_ReadFloat();
594 int j = MSG_ReadFloat() * 255.0f;
598 ent->state_current.effects |= EF_FULLBRIGHT;
601 ent->state_current.alpha = 0;
602 else if (j == 0 || j >= 255)
603 ent->state_current.alpha = 255;
605 ent->state_current.alpha = j;
611 ent->state_current.active = false;
615 CL_ValidateState(&ent->state_current);
618 if (!ent->state_current.active)
623 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i %i\n", num, ent->state_previous.modelindex, ent->state_current.modelindex);
625 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i\n", num, ent->state_previous.modelindex);
630 Con_Printf("CL_ParseUpdate: NULL model on %i: %i %i\n", num, ent->state_baseline.modelindex, ent->state_current.modelindex);
632 Con_Printf("CL_ParseUpdate: NULL model on %i: %i\n", num, ent->state_baseline.modelindex);
639 char *bitprofilenames[32] =
675 void CL_BitProfile_f(void)
678 Con_Printf("bitprofile: %i updates\n");
680 for (i = 0;i < 32;i++)
681 // if (bitprofile[i])
682 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
684 for (i = 0;i < 32;i++)
689 void CL_EntityUpdateSetup(void)
691 memset(entkill, 1, MAX_EDICTS);
694 void CL_EntityUpdateEnd(void)
697 for (i = 1;i < MAX_EDICTS;i++)
699 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
707 void CL_ParseBaseline (entity_t *ent, int large)
711 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
712 ent->state_baseline.active = true;
715 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
716 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
720 ent->state_baseline.modelindex = MSG_ReadByte ();
721 ent->state_baseline.frame = MSG_ReadByte ();
723 ent->state_baseline.colormap = MSG_ReadByte();
724 ent->state_baseline.skin = MSG_ReadByte();
725 for (i = 0;i < 3;i++)
727 ent->state_baseline.origin[i] = MSG_ReadCoord ();
728 ent->state_baseline.angles[i] = MSG_ReadAngle ();
730 ent->state_baseline.alpha = 255;
731 ent->state_baseline.scale = 16;
732 ent->state_baseline.glowsize = 0;
733 ent->state_baseline.glowcolor = 254;
734 ent->state_baseline.colormod = 255;
735 ent->state_previous = ent->state_current = ent->state_baseline;
737 CL_ValidateState(&ent->state_baseline);
745 Server information pertaining to this client only
748 void CL_ParseClientdata (int bits)
753 if (bits & SU_EXTEND1)
754 bits |= (MSG_ReadByte() << 16);
755 if (bits & SU_EXTEND2)
756 bits |= (MSG_ReadByte() << 24);
758 if (bits & SU_VIEWHEIGHT)
759 cl.viewheight = MSG_ReadChar ();
761 cl.viewheight = DEFAULT_VIEWHEIGHT;
763 if (bits & SU_IDEALPITCH)
764 cl.idealpitch = MSG_ReadChar ();
768 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
769 for (i=0 ; i<3 ; i++)
771 if (bits & (SU_PUNCH1<<i) )
774 cl.punchangle[i] = MSG_ReadPreciseAngle();
776 cl.punchangle[i] = MSG_ReadChar();
779 cl.punchangle[i] = 0;
780 if (bits & (SU_PUNCHVEC1<<i))
781 cl.punchvector[i] = MSG_ReadFloatCoord();
783 cl.punchvector[i] = 0;
784 if (bits & (SU_VELOCITY1<<i) )
785 cl.mvelocity[0][i] = MSG_ReadChar()*16;
787 cl.mvelocity[0][i] = 0;
793 for (j=0 ; j<32 ; j++)
794 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
795 cl.item_gettime[j] = cl.time;
799 cl.onground = (bits & SU_ONGROUND) != 0;
800 cl.inwater = (bits & SU_INWATER) != 0;
802 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
803 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
804 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
805 cl.stats[STAT_HEALTH] = MSG_ReadShort();
806 cl.stats[STAT_AMMO] = MSG_ReadByte();
808 cl.stats[STAT_SHELLS] = MSG_ReadByte();
809 cl.stats[STAT_NAILS] = MSG_ReadByte();
810 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
811 cl.stats[STAT_CELLS] = MSG_ReadByte();
816 cl.stats[STAT_ACTIVEWEAPON] = i;
818 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
822 =====================
824 =====================
826 void CL_ParseStatic (int large)
830 if (cl.num_statics >= MAX_STATIC_ENTITIES)
831 Host_Error ("Too many static entities");
832 ent = &cl_static_entities[cl.num_statics++];
833 CL_ParseBaseline (ent, large);
835 // copy it to the current state
836 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
837 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
838 ent->render.framelerp = 0;
839 ent->render.lerp_starttime = -1;
840 // make torchs play out of sync
841 ent->render.frame1start = ent->render.frame2start = -(rand() & 32767);
842 ent->render.colormap = -1; // no special coloring
843 ent->render.skinnum = ent->state_baseline.skin;
844 ent->render.effects = ent->state_baseline.effects;
845 ent->render.alpha = 1;
846 ent->render.scale = 1;
847 ent->render.alpha = 1;
848 ent->render.colormod[0] = ent->render.colormod[1] = ent->render.colormod[2] = 1;
850 VectorCopy (ent->state_baseline.origin, ent->render.origin);
851 VectorCopy (ent->state_baseline.angles, ent->render.angles);
859 void CL_ParseStaticSound (int large)
862 int sound_num, vol, atten;
866 sound_num = (unsigned short) MSG_ReadShort ();
868 sound_num = MSG_ReadByte ();
869 vol = MSG_ReadByte ();
870 atten = MSG_ReadByte ();
872 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
875 void CL_ParseEffect (void)
878 int modelindex, startframe, framecount, framerate;
881 modelindex = MSG_ReadByte ();
882 startframe = MSG_ReadByte ();
883 framecount = MSG_ReadByte ();
884 framerate = MSG_ReadByte ();
886 CL_Effect(org, modelindex, startframe, framecount, framerate);
889 void CL_ParseEffect2 (void)
892 int modelindex, startframe, framecount, framerate;
895 modelindex = MSG_ReadShort ();
896 startframe = MSG_ReadShort ();
897 framecount = MSG_ReadByte ();
898 framerate = MSG_ReadByte ();
900 CL_Effect(org, modelindex, startframe, framecount, framerate);
904 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
907 =====================
908 CL_ParseServerMessage
909 =====================
911 void CL_ParseServerMessage (void)
914 int i, entitiesupdated;
916 char *cmdlogname[32], *temp;
917 int cmdindex, cmdcount = 0;
920 // if recording demos, copy the message out
922 if (cl_shownet.value == 1)
923 Con_Printf ("%i ",net_message.cursize);
924 else if (cl_shownet.value == 2)
925 Con_Printf ("------------------\n");
927 cl.onground = false; // unless the server says otherwise
933 entitiesupdated = false;
934 CL_EntityUpdateSetup();
939 Host_Error ("CL_ParseServerMessage: Bad server message");
941 cmd = MSG_ReadByte ();
945 SHOWNET("END OF MESSAGE");
946 break; // end of message
949 cmdindex = cmdcount & 31;
951 cmdlog[cmdindex] = cmd;
953 // if the high bit of the command byte is set, it is a fast update
956 // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
958 cmdlogname[cmdindex] = temp;
959 SHOWNET("fast update");
960 CL_ParseUpdate (cmd&127);
964 SHOWNET(svc_strings[cmd]);
965 cmdlogname[cmdindex] = svc_strings[cmd];
966 if (!cmdlogname[cmdindex])
968 // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
970 cmdlogname[cmdindex] = temp;
978 char description[32*64], temp[64];
980 strcpy(description, "packet dump: ");
984 count = cmdcount - i;
988 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
989 strcat(description, temp);
994 description[strlen(description)-1] = '\n'; // replace the last space with a newline
995 Con_Printf(description);
996 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1001 // Con_Printf ("svc_nop\n");
1005 // handle old protocols which do not have entity update ranges
1006 entitiesupdated = true;
1007 cl.mtime[1] = cl.mtime[0];
1008 cl.mtime[0] = MSG_ReadFloat ();
1011 case svc_clientdata:
1012 i = MSG_ReadShort ();
1013 CL_ParseClientdata (i);
1017 i = MSG_ReadLong ();
1018 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
1019 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
1020 Nehahrademcompatibility = false;
1022 Nehahrademcompatibility = true;
1023 if (cls.demoplayback && demo_nehahra.value)
1024 Nehahrademcompatibility = true;
1025 dpprotocol = i == DPPROTOCOL_VERSION;
1028 case svc_disconnect:
1029 Host_EndGame ("Server disconnected\n");
1032 Con_Printf ("%s", MSG_ReadString ());
1035 case svc_centerprint:
1036 SCR_CenterPrint (MSG_ReadString ());
1040 Cbuf_AddText (MSG_ReadString ());
1047 case svc_serverinfo:
1048 CL_ParseServerInfo ();
1049 vid.recalc_refdef = true; // leave intermission full screen
1053 for (i=0 ; i<3 ; i++)
1054 cl.viewangles[i] = MSG_ReadAngle ();
1058 cl.viewentity = MSG_ReadShort ();
1061 case svc_lightstyle:
1062 i = MSG_ReadByte ();
1063 if (i >= MAX_LIGHTSTYLES)
1064 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1065 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1066 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1067 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1071 CL_ParseStartSoundPacket(false);
1075 CL_ParseStartSoundPacket(true);
1079 i = MSG_ReadShort();
1080 S_StopSound(i>>3, i&7);
1083 case svc_updatename:
1084 i = MSG_ReadByte ();
1085 if (i >= cl.maxclients)
1086 Host_Error ("CL_ParseServerMessage: svc_updatename >= MAX_SCOREBOARD");
1087 strcpy (cl.scores[i].name, MSG_ReadString ());
1090 case svc_updatefrags:
1091 i = MSG_ReadByte ();
1092 if (i >= cl.maxclients)
1093 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= MAX_SCOREBOARD");
1094 cl.scores[i].frags = MSG_ReadShort ();
1097 case svc_updatecolors:
1098 i = MSG_ReadByte ();
1099 if (i >= cl.maxclients)
1100 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= MAX_SCOREBOARD");
1101 cl.scores[i].colors = MSG_ReadByte ();
1105 R_ParseParticleEffect ();
1116 case svc_spawnbaseline:
1117 i = MSG_ReadShort ();
1118 // must use CL_EntityNum() to force cl.num_entities up
1119 CL_ParseBaseline (CL_EntityNum(i), false);
1121 case svc_spawnbaseline2:
1122 i = MSG_ReadShort ();
1123 // must use CL_EntityNum() to force cl.num_entities up
1124 CL_ParseBaseline (CL_EntityNum(i), true);
1126 case svc_spawnstatic:
1127 CL_ParseStatic (false);
1129 case svc_spawnstatic2:
1130 CL_ParseStatic (true);
1132 case svc_temp_entity:
1137 cl.paused = MSG_ReadByte ();
1145 i = MSG_ReadByte ();
1146 if (i <= cls.signon)
1147 Host_Error ("Received signon %i when at %i", i, cls.signon);
1152 case svc_killedmonster:
1153 cl.stats[STAT_MONSTERS]++;
1156 case svc_foundsecret:
1157 cl.stats[STAT_SECRETS]++;
1160 case svc_updatestat:
1161 i = MSG_ReadByte ();
1162 if (i < 0 || i >= MAX_CL_STATS)
1163 Host_Error ("svc_updatestat: %i is invalid", i);
1164 cl.stats[i] = MSG_ReadLong ();
1167 case svc_spawnstaticsound:
1168 CL_ParseStaticSound (false);
1171 case svc_spawnstaticsound2:
1172 CL_ParseStaticSound (true);
1176 cl.cdtrack = MSG_ReadByte ();
1177 cl.looptrack = MSG_ReadByte ();
1178 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1179 CDAudio_Play ((byte)cls.forcetrack, true);
1181 CDAudio_Play ((byte)cl.cdtrack, true);
1184 case svc_intermission:
1185 cl.intermission = 1;
1186 cl.completed_time = cl.time;
1187 vid.recalc_refdef = true; // go to full screen
1191 cl.intermission = 2;
1192 cl.completed_time = cl.time;
1193 vid.recalc_refdef = true; // go to full screen
1194 SCR_CenterPrint (MSG_ReadString ());
1198 cl.intermission = 3;
1199 cl.completed_time = cl.time;
1200 vid.recalc_refdef = true; // go to full screen
1201 SCR_CenterPrint (MSG_ReadString ());
1204 case svc_sellscreen:
1205 Cmd_ExecuteString ("help", src_command);
1208 SHOWLMP_decodehide();
1211 SHOWLMP_decodeshow();
1214 R_SetSkyBox(MSG_ReadString());
1219 if (entitiesupdated)
1220 CL_EntityUpdateEnd();