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
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 = {"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 skyname[0] = 0; // LordHavoc: no enviroment 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
394 memset (cl.model_precache, 0, sizeof(cl.model_precache));
395 for (nummodels=1 ; ; nummodels++)
397 str = MSG_ReadString ();
400 if (nummodels==MAX_MODELS)
402 Con_Printf ("Server sent too many model precaches\n");
405 if (strlen(str) >= MAX_QPATH)
406 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
407 strcpy (model_precache[nummodels], str);
408 Mod_TouchModel (str);
412 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
413 for (numsounds=1 ; ; numsounds++)
415 str = MSG_ReadString ();
418 if (numsounds==MAX_SOUNDS)
420 Con_Printf ("Server sent too many sound precaches\n");
423 if (strlen(str) >= MAX_QPATH)
424 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
425 strcpy (sound_precache[numsounds], str);
430 // now we try to load everything else until a cache allocation fails
433 for (i=1 ; i<nummodels ; i++)
435 isworldmodel = i == 1; // LordHavoc: first model is the world model
436 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
437 if (cl.model_precache[i] == NULL)
439 Con_Printf("Model %s not found\n", model_precache[i]);
442 CL_KeepaliveMessage ();
445 S_BeginPrecaching ();
446 for (i=1 ; i<numsounds ; i++)
448 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
449 CL_KeepaliveMessage ();
455 cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
459 Hunk_Check (); // make sure nothing is hurt
461 noclip_anglehack = false; // noclip is turned off at start
464 void CL_ValidateState(entity_state_t *s)
471 if (s->modelindex >= MAX_MODELS)
472 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
474 // colormap is client index + 1
475 if (s->colormap > cl.maxclients)
476 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
478 model = cl.model_precache[s->modelindex];
479 if (model && s->frame >= model->numframes)
481 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
490 Parse an entity update message from the server
491 If an entities model or origin changes from frame to frame, it must be
492 relinked. Other attributes can change without relinking.
495 byte entkill[MAX_EDICTS];
496 int bitprofile[32], bitprofilecount = 0;
497 void CL_ParseUpdate (int bits)
499 int i, num, deltadie;
502 if (cls.signon == SIGNONS - 1)
503 { // first update is the final signon stage
504 cls.signon = SIGNONS;
508 if (bits & U_MOREBITS)
509 bits |= (MSG_ReadByte()<<8);
510 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
512 bits |= MSG_ReadByte() << 16;
513 if (bits & U_EXTEND2)
514 bits |= MSG_ReadByte() << 24;
517 if (bits & U_LONGENTITY)
518 num = (unsigned) MSG_ReadShort ();
520 num = (unsigned) MSG_ReadByte ();
522 if (num >= MAX_EDICTS)
523 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
525 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
527 // mark as visible (no kill)
530 ent = CL_EntityNum (num);
532 for (i = 0;i < 32;i++)
537 ent->state_previous = ent->state_current;
541 if (!ent->state_current.active)
542 deltadie = true; // was not present in previous frame, leave hidden until next full update
545 ent->state_current = ent->state_baseline;
547 ent->state_current.time = cl.mtime[0];
549 ent->state_current.flags = 0;
550 ent->state_current.active = true;
551 if (bits & U_MODEL) ent->state_current.modelindex = (ent->state_current.modelindex & 0xFF00) | MSG_ReadByte();
552 if (bits & U_FRAME) ent->state_current.frame = (ent->state_current.frame & 0xFF00) | MSG_ReadByte();
553 if (bits & U_COLORMAP) ent->state_current.colormap = MSG_ReadByte();
554 if (bits & U_SKIN) ent->state_current.skin = MSG_ReadByte();
555 if (bits & U_EFFECTS) ent->state_current.effects = (ent->state_current.effects & 0xFF00) | MSG_ReadByte();
556 if (bits & U_ORIGIN1) ent->state_current.origin[0] = MSG_ReadCoord();
557 if (bits & U_ANGLE1) ent->state_current.angles[0] = MSG_ReadAngle();
558 if (bits & U_ORIGIN2) ent->state_current.origin[1] = MSG_ReadCoord();
559 if (bits & U_ANGLE2) ent->state_current.angles[1] = MSG_ReadAngle();
560 if (bits & U_ORIGIN3) ent->state_current.origin[2] = MSG_ReadCoord();
561 if (bits & U_ANGLE3) ent->state_current.angles[2] = MSG_ReadAngle();
562 if (bits & U_STEP) ent->state_current.flags |= RENDER_STEP;
563 if (bits & U_ALPHA) ent->state_current.alpha = MSG_ReadByte();
564 if (bits & U_SCALE) ent->state_current.scale = MSG_ReadByte();
565 if (bits & U_EFFECTS2) ent->state_current.effects = (ent->state_current.effects & 0x00FF) | (MSG_ReadByte() << 8);
566 if (bits & U_GLOWSIZE) ent->state_current.glowsize = MSG_ReadByte();
567 if (bits & U_GLOWCOLOR) ent->state_current.glowcolor = MSG_ReadByte();
568 if (bits & U_GLOWTRAIL) ent->state_current.flags |= RENDER_GLOWTRAIL;
569 if (bits & U_COLORMOD) ent->state_current.colormod = MSG_ReadByte();
570 if (bits & U_FRAME2) ent->state_current.frame = (ent->state_current.frame & 0x00FF) | (MSG_ReadByte() << 8);
571 if (bits & U_MODEL2) ent->state_current.modelindex = (ent->state_current.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
572 if (bits & U_VIEWMODEL) ent->state_current.flags |= RENDER_VIEWMODEL;
573 if (bits & U_EXTERIORMODEL) ent->state_current.flags |= RENDER_EXTERIORMODEL;
575 // LordHavoc: to allow playback of the Nehahra movie
576 if (Nehahrademcompatibility && (bits & U_EXTEND1))
578 // LordHavoc: evil format
579 int i = MSG_ReadFloat();
580 int j = MSG_ReadFloat() * 255.0f;
584 ent->state_current.effects |= EF_FULLBRIGHT;
587 ent->state_current.alpha = 0;
588 else if (j == 0 || j >= 255)
589 ent->state_current.alpha = 255;
591 ent->state_current.alpha = j;
597 ent->state_current.active = false;
601 CL_ValidateState(&ent->state_current);
604 if (!ent->state_current.active)
609 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i %i\n", num, ent->state_previous.modelindex, ent->state_current.modelindex);
611 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i\n", num, ent->state_previous.modelindex);
616 Con_Printf("CL_ParseUpdate: NULL model on %i: %i %i\n", num, ent->state_baseline.modelindex, ent->state_current.modelindex);
618 Con_Printf("CL_ParseUpdate: NULL model on %i: %i\n", num, ent->state_baseline.modelindex);
625 char *bitprofilenames[32] =
661 void CL_BitProfile_f(void)
664 Con_Printf("bitprofile: %i updates\n");
666 for (i = 0;i < 32;i++)
667 // if (bitprofile[i])
668 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
670 for (i = 0;i < 32;i++)
675 void CL_EntityUpdateSetup(void)
677 memset(entkill, 1, MAX_EDICTS);
680 void CL_EntityUpdateEnd(void)
683 for (i = 1;i < MAX_EDICTS;i++)
685 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
693 void CL_ParseBaseline (entity_t *ent, int large)
697 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
698 ent->state_baseline.active = true;
701 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
702 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
706 ent->state_baseline.modelindex = MSG_ReadByte ();
707 ent->state_baseline.frame = MSG_ReadByte ();
709 ent->state_baseline.colormap = MSG_ReadByte();
710 ent->state_baseline.skin = MSG_ReadByte();
711 for (i = 0;i < 3;i++)
713 ent->state_baseline.origin[i] = MSG_ReadCoord ();
714 ent->state_baseline.angles[i] = MSG_ReadAngle ();
716 ent->state_baseline.alpha = 255;
717 ent->state_baseline.scale = 16;
718 ent->state_baseline.glowsize = 0;
719 ent->state_baseline.glowcolor = 254;
720 ent->state_baseline.colormod = 255;
721 ent->state_previous = ent->state_current = ent->state_baseline;
723 CL_ValidateState(&ent->state_baseline);
731 Server information pertaining to this client only
734 void CL_ParseClientdata (int bits)
739 if (bits & SU_EXTEND1)
740 bits |= (MSG_ReadByte() << 16);
741 if (bits & SU_EXTEND2)
742 bits |= (MSG_ReadByte() << 24);
744 if (bits & SU_VIEWHEIGHT)
745 cl.viewheight = MSG_ReadChar ();
747 cl.viewheight = DEFAULT_VIEWHEIGHT;
749 if (bits & SU_IDEALPITCH)
750 cl.idealpitch = MSG_ReadChar ();
754 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
755 for (i=0 ; i<3 ; i++)
757 if (bits & (SU_PUNCH1<<i) )
760 cl.punchangle[i] = MSG_ReadPreciseAngle();
762 cl.punchangle[i] = MSG_ReadChar();
765 cl.punchangle[i] = 0;
766 if (bits & (SU_PUNCHVEC1<<i))
767 cl.punchvector[i] = MSG_ReadFloatCoord();
769 cl.punchvector[i] = 0;
770 if (bits & (SU_VELOCITY1<<i) )
771 cl.mvelocity[0][i] = MSG_ReadChar()*16;
773 cl.mvelocity[0][i] = 0;
779 for (j=0 ; j<32 ; j++)
780 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
781 cl.item_gettime[j] = cl.time;
785 cl.onground = (bits & SU_ONGROUND) != 0;
786 cl.inwater = (bits & SU_INWATER) != 0;
788 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
789 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
790 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
791 cl.stats[STAT_HEALTH] = MSG_ReadShort();
792 cl.stats[STAT_AMMO] = MSG_ReadByte();
794 cl.stats[STAT_SHELLS] = MSG_ReadByte();
795 cl.stats[STAT_NAILS] = MSG_ReadByte();
796 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
797 cl.stats[STAT_CELLS] = MSG_ReadByte();
802 cl.stats[STAT_ACTIVEWEAPON] = i;
804 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
808 =====================
810 =====================
812 void CL_ParseStatic (int large)
816 if (cl.num_statics >= MAX_STATIC_ENTITIES)
817 Host_Error ("Too many static entities");
818 ent = &cl_static_entities[cl.num_statics++];
819 CL_ParseBaseline (ent, large);
821 // copy it to the current state
822 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
823 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
824 ent->render.framelerp = 0;
825 ent->render.lerp_starttime = -1;
826 // make torchs play out of sync
827 ent->render.frame1start = ent->render.frame2start = -(rand() & 32767);
828 ent->render.colormap = -1; // no special coloring
829 ent->render.skinnum = ent->state_baseline.skin;
830 ent->render.effects = ent->state_baseline.effects;
831 ent->render.alpha = 1;
832 ent->render.scale = 1;
833 ent->render.alpha = 1;
834 ent->render.glowsize = 0;
835 ent->render.glowcolor = 254;
836 ent->render.colormod[0] = ent->render.colormod[1] = ent->render.colormod[2] = 1;
838 VectorCopy (ent->state_baseline.origin, ent->render.origin);
839 VectorCopy (ent->state_baseline.angles, ent->render.angles);
847 void CL_ParseStaticSound (int large)
850 int sound_num, vol, atten;
854 sound_num = (unsigned short) MSG_ReadShort ();
856 sound_num = MSG_ReadByte ();
857 vol = MSG_ReadByte ();
858 atten = MSG_ReadByte ();
860 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
863 void CL_ParseEffect (void)
866 int modelindex, startframe, framecount, framerate;
869 modelindex = MSG_ReadByte ();
870 startframe = MSG_ReadByte ();
871 framecount = MSG_ReadByte ();
872 framerate = MSG_ReadByte ();
874 CL_Effect(org, modelindex, startframe, framecount, framerate);
877 void CL_ParseEffect2 (void)
880 int modelindex, startframe, framecount, framerate;
883 modelindex = MSG_ReadShort ();
884 startframe = MSG_ReadShort ();
885 framecount = MSG_ReadByte ();
886 framerate = MSG_ReadByte ();
888 CL_Effect(org, modelindex, startframe, framecount, framerate);
892 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
895 =====================
896 CL_ParseServerMessage
897 =====================
899 void CL_ParseServerMessage (void)
902 int i, entitiesupdated;
904 char *cmdlogname[32], *temp;
905 int cmdindex, cmdcount = 0;
908 // if recording demos, copy the message out
910 if (cl_shownet.value == 1)
911 Con_Printf ("%i ",net_message.cursize);
912 else if (cl_shownet.value == 2)
913 Con_Printf ("------------------\n");
915 cl.onground = false; // unless the server says otherwise
921 entitiesupdated = false;
922 CL_EntityUpdateSetup();
927 Host_Error ("CL_ParseServerMessage: Bad server message");
929 cmd = MSG_ReadByte ();
933 SHOWNET("END OF MESSAGE");
934 break; // end of message
937 cmdindex = cmdcount & 31;
939 cmdlog[cmdindex] = cmd;
941 // if the high bit of the command byte is set, it is a fast update
944 // 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)
946 cmdlogname[cmdindex] = temp;
947 SHOWNET("fast update");
948 CL_ParseUpdate (cmd&127);
952 SHOWNET(svc_strings[cmd]);
953 cmdlogname[cmdindex] = svc_strings[cmd];
954 if (!cmdlogname[cmdindex])
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;
966 char description[32*64], temp[64];
968 strcpy(description, "packet dump: ");
972 count = cmdcount - i;
976 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
977 strcat(description, temp);
982 description[strlen(description)-1] = '\n'; // replace the last space with a newline
983 Con_Printf(description);
984 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
989 // Con_Printf ("svc_nop\n");
993 // handle old protocols which do not have entity update ranges
994 entitiesupdated = true;
995 cl.mtime[1] = cl.mtime[0];
996 cl.mtime[0] = MSG_ReadFloat ();
1000 i = MSG_ReadShort ();
1001 CL_ParseClientdata (i);
1005 i = MSG_ReadLong ();
1006 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
1007 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
1008 Nehahrademcompatibility = false;
1010 Nehahrademcompatibility = true;
1011 if (cls.demoplayback && demo_nehahra.value)
1012 Nehahrademcompatibility = true;
1013 dpprotocol = i == DPPROTOCOL_VERSION;
1016 case svc_disconnect:
1017 Host_EndGame ("Server disconnected\n");
1020 Con_Printf ("%s", MSG_ReadString ());
1023 case svc_centerprint:
1024 SCR_CenterPrint (MSG_ReadString ());
1028 Cbuf_AddText (MSG_ReadString ());
1035 case svc_serverinfo:
1036 CL_ParseServerInfo ();
1037 vid.recalc_refdef = true; // leave intermission full screen
1041 for (i=0 ; i<3 ; i++)
1042 cl.viewangles[i] = MSG_ReadAngle ();
1046 cl.viewentity = MSG_ReadShort ();
1049 case svc_lightstyle:
1050 i = MSG_ReadByte ();
1051 if (i >= MAX_LIGHTSTYLES)
1052 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1053 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1054 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1055 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1059 CL_ParseStartSoundPacket(false);
1063 CL_ParseStartSoundPacket(true);
1067 i = MSG_ReadShort();
1068 S_StopSound(i>>3, i&7);
1071 case svc_updatename:
1072 i = MSG_ReadByte ();
1073 if (i >= cl.maxclients)
1074 Host_Error ("CL_ParseServerMessage: svc_updatename >= MAX_SCOREBOARD");
1075 strcpy (cl.scores[i].name, MSG_ReadString ());
1078 case svc_updatefrags:
1079 i = MSG_ReadByte ();
1080 if (i >= cl.maxclients)
1081 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= MAX_SCOREBOARD");
1082 cl.scores[i].frags = MSG_ReadShort ();
1085 case svc_updatecolors:
1086 i = MSG_ReadByte ();
1087 if (i >= cl.maxclients)
1088 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= MAX_SCOREBOARD");
1089 cl.scores[i].colors = MSG_ReadByte ();
1093 R_ParseParticleEffect ();
1104 case svc_spawnbaseline:
1105 i = MSG_ReadShort ();
1106 // must use CL_EntityNum() to force cl.num_entities up
1107 CL_ParseBaseline (CL_EntityNum(i), false);
1109 case svc_spawnbaseline2:
1110 i = MSG_ReadShort ();
1111 // must use CL_EntityNum() to force cl.num_entities up
1112 CL_ParseBaseline (CL_EntityNum(i), true);
1114 case svc_spawnstatic:
1115 CL_ParseStatic (false);
1117 case svc_spawnstatic2:
1118 CL_ParseStatic (true);
1120 case svc_temp_entity:
1125 cl.paused = MSG_ReadByte ();
1133 i = MSG_ReadByte ();
1134 if (i <= cls.signon)
1135 Host_Error ("Received signon %i when at %i", i, cls.signon);
1140 case svc_killedmonster:
1141 cl.stats[STAT_MONSTERS]++;
1144 case svc_foundsecret:
1145 cl.stats[STAT_SECRETS]++;
1148 case svc_updatestat:
1149 i = MSG_ReadByte ();
1150 if (i < 0 || i >= MAX_CL_STATS)
1151 Host_Error ("svc_updatestat: %i is invalid", i);
1152 cl.stats[i] = MSG_ReadLong ();
1155 case svc_spawnstaticsound:
1156 CL_ParseStaticSound (false);
1159 case svc_spawnstaticsound2:
1160 CL_ParseStaticSound (true);
1164 cl.cdtrack = MSG_ReadByte ();
1165 cl.looptrack = MSG_ReadByte ();
1166 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1167 CDAudio_Play ((byte)cls.forcetrack, true);
1169 CDAudio_Play ((byte)cl.cdtrack, true);
1172 case svc_intermission:
1173 cl.intermission = 1;
1174 cl.completed_time = cl.time;
1175 vid.recalc_refdef = true; // go to full screen
1179 cl.intermission = 2;
1180 cl.completed_time = cl.time;
1181 vid.recalc_refdef = true; // go to full screen
1182 SCR_CenterPrint (MSG_ReadString ());
1186 cl.intermission = 3;
1187 cl.completed_time = cl.time;
1188 vid.recalc_refdef = true; // go to full screen
1189 SCR_CenterPrint (MSG_ReadString ());
1192 case svc_sellscreen:
1193 Cmd_ExecuteString ("help", src_command);
1196 SHOWLMP_decodehide();
1199 SHOWLMP_decodeshow();
1204 if (entitiesupdated)
1205 CL_EntityUpdateEnd();