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 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
92 qboolean dpprotocol; // LordHavoc: whether or not the current network stream is the enhanced DarkPlaces protocol
98 This error checks and tracks the total number of entities
101 entity_t *CL_EntityNum (int num)
104 if (num >= cl.num_entities)
106 if (num >= MAX_EDICTS)
107 Host_Error ("CL_EntityNum: %i is an invalid number",num);
108 cl.num_entities = num;
109 // while (cl.num_entities <= num)
111 // cl_entities[cl.num_entities].colormap = -1; // no special coloring
112 // cl.num_entities++;
116 if (num >= MAX_EDICTS)
117 Host_Error ("CL_EntityNum: %i is an invalid number",num);
119 return &cl_entities[num];
125 CL_ParseStartSoundPacket
128 void CL_ParseStartSoundPacket(int largesoundindex)
138 field_mask = MSG_ReadByte();
140 if (field_mask & SND_VOLUME)
141 volume = MSG_ReadByte ();
143 volume = DEFAULT_SOUND_PACKET_VOLUME;
145 if (field_mask & SND_ATTENUATION)
146 attenuation = MSG_ReadByte () / 64.0;
148 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
150 channel = MSG_ReadShort ();
152 sound_num = (unsigned short) MSG_ReadShort ();
154 sound_num = MSG_ReadByte ();
156 if (sound_num >= MAX_SOUNDS)
157 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
162 if (ent > MAX_EDICTS)
163 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
165 for (i=0 ; i<3 ; i++)
166 pos[i] = MSG_ReadCoord ();
168 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
175 When the client is taking a long time to load stuff, send keepalive messages
176 so the server doesn't disconnect.
179 void CL_KeepaliveMessage (void)
182 static float lastmsg;
188 return; // no need if server is local
189 if (cls.demoplayback)
192 // read messages from server, should just be nops
194 memcpy (olddata, net_message.data, net_message.cursize);
198 ret = CL_GetMessage ();
202 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
204 break; // nothing waiting
206 Host_Error ("CL_KeepaliveMessage: received a message");
209 if (MSG_ReadByte() != svc_nop)
210 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
216 memcpy (net_message.data, olddata, net_message.cursize);
219 time = Sys_DoubleTime ();
220 if (time - lastmsg < 5)
225 Con_Printf ("--> client to server keepalive\n");
227 MSG_WriteByte (&cls.message, clc_nop);
228 NET_SendMessage (cls.netcon, &cls.message);
229 SZ_Clear (&cls.message);
232 extern qboolean isworldmodel;
233 extern char skyname[];
234 extern void R_SetSkyBox (char *sky);
235 extern void FOG_clear();
236 extern cvar_t r_farclip;
238 void CL_ParseEntityLump(char *entdata)
241 char key[128], value[4096];
244 FOG_clear(); // LordHavoc: no fog until set
245 skyname[0] = 0; // LordHavoc: no enviroment mapped sky until set
246 r_farclip.value = 6144; // LordHavoc: default farclip distance
250 data = COM_Parse(data);
252 return; // valid exit
253 if (com_token[0] != '{')
257 data = COM_Parse(data);
260 if (com_token[0] == '}')
261 return; // since we're just parsing the first ent (worldspawn), exit
262 strcpy(key, com_token);
263 while (key[strlen(key)-1] == ' ') // remove trailing spaces
264 key[strlen(key)-1] = 0;
265 data = COM_Parse(data);
268 strcpy(value, com_token);
269 if (!strcmp("sky", key))
271 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
273 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
275 else if (!strcmp("farclip", key))
277 r_farclip.value = atof(value);
278 if (r_farclip.value < 64)
279 r_farclip.value = 64;
281 else if (!strcmp("fog", key))
283 scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
286 else if (!strcmp("fog_density", key))
287 fog_density = atof(value);
288 else if (!strcmp("fog_red", key))
289 fog_red = atof(value);
290 else if (!strcmp("fog_green", key))
291 fog_green = atof(value);
292 else if (!strcmp("fog_blue", key))
293 fog_blue = atof(value);
294 else if (!strcmp("wad", key)) // for HalfLife maps
299 for (i = 0;i < 4096;i++)
300 if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':')
306 // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
307 if (value[i] == '\\' || value[i] == '/' || value[i] == ':')
309 else if (value[i] == ';' || value[i] == 0)
313 strcpy(wadname, "textures/");
314 strcat(wadname, &value[j]);
315 W_LoadTextureWadFile (wadname, false);
332 extern cvar_t demo_nehahra;
333 void CL_ParseServerInfo (void)
337 int nummodels, numsounds;
338 char model_precache[MAX_MODELS][MAX_QPATH];
339 char sound_precache[MAX_SOUNDS][MAX_QPATH];
341 Con_DPrintf ("Serverinfo packet received.\n");
343 // wipe the client_state_t struct
347 // parse protocol version number
349 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
351 Con_Printf ("Server returned version %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
354 Nehahrademcompatibility = false;
356 Nehahrademcompatibility = true;
357 if (cls.demoplayback && demo_nehahra.value)
358 Nehahrademcompatibility = true;
359 dpprotocol = i == DPPROTOCOL_VERSION;
362 cl.maxclients = MSG_ReadByte ();
363 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
365 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
368 cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
371 cl.gametype = MSG_ReadByte ();
373 // parse signon message
374 str = MSG_ReadString ();
375 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
377 // seperate the printfs so the server message can have a color
378 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
380 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");
381 Con_Printf ("%c%s\n", 2, str);
385 // first we go through and touch all of the precache data that still
386 // happens to be in the cache, so precaching something else doesn't
387 // needlessly purge it
391 memset (cl.model_precache, 0, sizeof(cl.model_precache));
392 for (nummodels=1 ; ; nummodels++)
394 str = MSG_ReadString ();
397 if (nummodels==MAX_MODELS)
399 Con_Printf ("Server sent too many model precaches\n");
402 if (strlen(str) >= MAX_QPATH)
403 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
404 strcpy (model_precache[nummodels], str);
405 Mod_TouchModel (str);
409 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
410 for (numsounds=1 ; ; numsounds++)
412 str = MSG_ReadString ();
415 if (numsounds==MAX_SOUNDS)
417 Con_Printf ("Server sent too many sound precaches\n");
420 if (strlen(str) >= MAX_QPATH)
421 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
422 strcpy (sound_precache[numsounds], str);
427 // now we try to load everything else until a cache allocation fails
430 for (i=1 ; i<nummodels ; i++)
432 isworldmodel = i == 1; // LordHavoc: first model is the world model
433 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
434 if (cl.model_precache[i] == NULL)
436 Con_Printf("Model %s not found\n", model_precache[i]);
439 CL_KeepaliveMessage ();
442 S_BeginPrecaching ();
443 for (i=1 ; i<numsounds ; i++)
445 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
446 CL_KeepaliveMessage ();
452 cl_entities[0].render.model = cl.worldmodel = cl.model_precache[1];
456 Hunk_Check (); // make sure nothing is hurt
458 noclip_anglehack = false; // noclip is turned off at start
461 void CL_ValidateState(entity_state_t *s)
468 if (s->modelindex >= MAX_MODELS)
469 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
471 // colormap is client index + 1
472 if (s->colormap > cl.maxclients)
473 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
475 model = cl.model_precache[s->modelindex];
476 if (model && s->frame >= model->numframes)
478 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
487 Parse an entity update message from the server
488 If an entities model or origin changes from frame to frame, it must be
489 relinked. Other attributes can change without relinking.
492 byte entkill[MAX_EDICTS];
493 int bitprofile[32], bitprofilecount = 0;
494 void CL_ParseUpdate (int bits)
496 int i, num, deltadie;
499 if (cls.signon == SIGNONS - 1)
500 { // first update is the final signon stage
501 cls.signon = SIGNONS;
505 if (bits & U_MOREBITS)
506 bits |= (MSG_ReadByte()<<8);
507 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
509 bits |= MSG_ReadByte() << 16;
510 if (bits & U_EXTEND2)
511 bits |= MSG_ReadByte() << 24;
514 if (bits & U_LONGENTITY)
515 num = (unsigned) MSG_ReadShort ();
517 num = (unsigned) MSG_ReadByte ();
519 if (num >= MAX_EDICTS)
520 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
522 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
524 // mark as visible (no kill)
527 ent = CL_EntityNum (num);
529 for (i = 0;i < 32;i++)
534 ent->state_previous = ent->state_current;
538 if (!ent->state_current.active)
539 deltadie = true; // was not present in previous frame, leave hidden until next full update
542 ent->state_current = ent->state_baseline;
544 ent->state_current.time = cl.mtime[0];
546 ent->state_current.flags = 0;
547 ent->state_current.active = true;
548 if (bits & U_MODEL) ent->state_current.modelindex = (ent->state_current.modelindex & 0xFF00) | MSG_ReadByte();
549 if (bits & U_FRAME) ent->state_current.frame = (ent->state_current.frame & 0xFF00) | MSG_ReadByte();
550 if (bits & U_COLORMAP) ent->state_current.colormap = MSG_ReadByte();
551 if (bits & U_SKIN) ent->state_current.skin = MSG_ReadByte();
552 if (bits & U_EFFECTS) ent->state_current.effects = (ent->state_current.effects & 0xFF00) | MSG_ReadByte();
553 if (bits & U_ORIGIN1) ent->state_current.origin[0] = MSG_ReadCoord();
554 if (bits & U_ANGLE1) ent->state_current.angles[0] = MSG_ReadAngle();
555 if (bits & U_ORIGIN2) ent->state_current.origin[1] = MSG_ReadCoord();
556 if (bits & U_ANGLE2) ent->state_current.angles[1] = MSG_ReadAngle();
557 if (bits & U_ORIGIN3) ent->state_current.origin[2] = MSG_ReadCoord();
558 if (bits & U_ANGLE3) ent->state_current.angles[2] = MSG_ReadAngle();
559 if (bits & U_STEP) ent->state_current.flags |= RENDER_STEP;
560 if (bits & U_ALPHA) ent->state_current.alpha = MSG_ReadByte();
561 if (bits & U_SCALE) ent->state_current.scale = MSG_ReadByte();
562 if (bits & U_EFFECTS2) ent->state_current.effects = (ent->state_current.effects & 0x00FF) | (MSG_ReadByte() << 8);
563 if (bits & U_GLOWSIZE) ent->state_current.glowsize = MSG_ReadByte();
564 if (bits & U_GLOWCOLOR) ent->state_current.glowcolor = MSG_ReadByte();
565 if (bits & U_GLOWTRAIL) ent->state_current.flags |= RENDER_GLOWTRAIL;
566 if (bits & U_COLORMOD) ent->state_current.colormod = MSG_ReadByte();
567 if (bits & U_FRAME2) ent->state_current.frame = (ent->state_current.frame & 0x00FF) | (MSG_ReadByte() << 8);
568 if (bits & U_MODEL2) ent->state_current.modelindex = (ent->state_current.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
569 if (bits & U_VIEWMODEL) ent->state_current.flags |= RENDER_VIEWMODEL;
570 if (bits & U_EXTERIORMODEL) ent->state_current.flags |= RENDER_EXTERIORMODEL;
572 // LordHavoc: to allow playback of the Nehahra movie
573 if (Nehahrademcompatibility && (bits & U_EXTEND1))
575 // LordHavoc: evil format
576 int i = MSG_ReadFloat();
577 int j = MSG_ReadFloat() * 255.0f;
581 ent->state_current.effects |= EF_FULLBRIGHT;
584 ent->state_current.alpha = 0;
585 else if (j == 0 || j >= 255)
586 ent->state_current.alpha = 255;
588 ent->state_current.alpha = j;
594 ent->state_current.active = false;
598 CL_ValidateState(&ent->state_current);
601 if (!ent->state_current.active)
606 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i %i\n", num, ent->state_previous.modelindex, ent->state_current.modelindex);
608 Con_Printf("CL_ParseUpdate: delta NULL model on %i: %i\n", num, ent->state_previous.modelindex);
613 Con_Printf("CL_ParseUpdate: NULL model on %i: %i %i\n", num, ent->state_baseline.modelindex, ent->state_current.modelindex);
615 Con_Printf("CL_ParseUpdate: NULL model on %i: %i\n", num, ent->state_baseline.modelindex);
622 char *bitprofilenames[32] =
658 void CL_BitProfile_f(void)
661 Con_Printf("bitprofile: %i updates\n");
663 for (i = 0;i < 32;i++)
664 // if (bitprofile[i])
665 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
667 for (i = 0;i < 32;i++)
672 void CL_EntityUpdateSetup()
674 memset(entkill, 1, MAX_EDICTS);
677 void CL_EntityUpdateEnd()
680 for (i = 1;i < MAX_EDICTS;i++)
682 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
690 void CL_ParseBaseline (entity_t *ent, int large)
694 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
695 ent->state_baseline.active = true;
698 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
699 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
703 ent->state_baseline.modelindex = MSG_ReadByte ();
704 ent->state_baseline.frame = MSG_ReadByte ();
706 ent->state_baseline.colormap = MSG_ReadByte();
707 ent->state_baseline.skin = MSG_ReadByte();
708 for (i = 0;i < 3;i++)
710 ent->state_baseline.origin[i] = MSG_ReadCoord ();
711 ent->state_baseline.angles[i] = MSG_ReadAngle ();
713 ent->state_baseline.alpha = 255;
714 ent->state_baseline.scale = 16;
715 ent->state_baseline.glowsize = 0;
716 ent->state_baseline.glowcolor = 254;
717 ent->state_baseline.colormod = 255;
718 ent->state_previous = ent->state_current = ent->state_baseline;
720 CL_ValidateState(&ent->state_baseline);
728 Server information pertaining to this client only
731 void CL_ParseClientdata (int bits)
736 if (bits & SU_EXTEND1)
737 bits |= (MSG_ReadByte() << 16);
738 if (bits & SU_EXTEND2)
739 bits |= (MSG_ReadByte() << 24);
741 if (bits & SU_VIEWHEIGHT)
742 cl.viewheight = MSG_ReadChar ();
744 cl.viewheight = DEFAULT_VIEWHEIGHT;
746 if (bits & SU_IDEALPITCH)
747 cl.idealpitch = MSG_ReadChar ();
751 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
752 for (i=0 ; i<3 ; i++)
754 if (bits & (SU_PUNCH1<<i) )
757 cl.punchangle[i] = MSG_ReadPreciseAngle();
759 cl.punchangle[i] = MSG_ReadChar();
762 cl.punchangle[i] = 0;
763 if (bits & (SU_PUNCHVEC1<<i))
764 cl.punchvector[i] = MSG_ReadFloatCoord();
766 cl.punchvector[i] = 0;
767 if (bits & (SU_VELOCITY1<<i) )
768 cl.mvelocity[0][i] = MSG_ReadChar()*16;
770 cl.mvelocity[0][i] = 0;
776 for (j=0 ; j<32 ; j++)
777 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
778 cl.item_gettime[j] = cl.time;
782 cl.onground = (bits & SU_ONGROUND) != 0;
783 cl.inwater = (bits & SU_INWATER) != 0;
785 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
786 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
787 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
788 cl.stats[STAT_HEALTH] = MSG_ReadShort();
789 cl.stats[STAT_AMMO] = MSG_ReadByte();
791 cl.stats[STAT_SHELLS] = MSG_ReadByte();
792 cl.stats[STAT_NAILS] = MSG_ReadByte();
793 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
794 cl.stats[STAT_CELLS] = MSG_ReadByte();
799 cl.stats[STAT_ACTIVEWEAPON] = i;
801 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
805 =====================
807 =====================
809 void CL_ParseStatic (int large)
813 if (cl.num_statics >= MAX_STATIC_ENTITIES)
814 Host_Error ("Too many static entities");
815 ent = &cl_static_entities[cl.num_statics++];
816 CL_ParseBaseline (ent, large);
818 // copy it to the current state
819 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
820 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
821 ent->render.framelerp = 0;
822 ent->render.lerp_starttime = -1;
823 // make torchs play out of sync
824 ent->render.frame1start = ent->render.frame2start = -(rand() & 32767);
825 ent->render.colormap = -1; // no special coloring
826 ent->render.skinnum = ent->state_baseline.skin;
827 ent->render.effects = ent->state_baseline.effects;
828 ent->render.alpha = 1;
829 ent->render.scale = 1;
830 ent->render.alpha = 1;
831 ent->render.glowsize = 0;
832 ent->render.glowcolor = 254;
833 ent->render.colormod[0] = ent->render.colormod[1] = ent->render.colormod[2] = 1;
835 VectorCopy (ent->state_baseline.origin, ent->render.origin);
836 VectorCopy (ent->state_baseline.angles, ent->render.angles);
844 void CL_ParseStaticSound (int large)
847 int sound_num, vol, atten;
851 sound_num = (unsigned short) MSG_ReadShort ();
853 sound_num = MSG_ReadByte ();
854 vol = MSG_ReadByte ();
855 atten = MSG_ReadByte ();
857 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
860 void CL_ParseEffect (void)
863 int modelindex, startframe, framecount, framerate;
866 modelindex = MSG_ReadByte ();
867 startframe = MSG_ReadByte ();
868 framecount = MSG_ReadByte ();
869 framerate = MSG_ReadByte ();
871 CL_Effect(org, modelindex, startframe, framecount, framerate);
874 void CL_ParseEffect2 (void)
877 int modelindex, startframe, framecount, framerate;
880 modelindex = MSG_ReadShort ();
881 startframe = MSG_ReadShort ();
882 framecount = MSG_ReadByte ();
883 framerate = MSG_ReadByte ();
885 CL_Effect(org, modelindex, startframe, framecount, framerate);
889 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
891 extern void SHOWLMP_decodehide();
892 extern void SHOWLMP_decodeshow();
893 extern void R_SetSkyBox(char* sky);
897 =====================
898 CL_ParseServerMessage
899 =====================
901 void CL_ParseServerMessage (void)
904 int i, entitiesupdated;
906 char *cmdlogname[32], *temp;
907 int cmdindex, cmdcount = 0;
910 // if recording demos, copy the message out
912 if (cl_shownet.value == 1)
914 Con_Printf ("%i ",net_message.cursize);
917 else if (cl_shownet.value == 2)
919 Con_Printf ("------------------\n");
923 cl.onground = false; // unless the server says otherwise
929 entitiesupdated = false;
930 CL_EntityUpdateSetup();
935 Host_Error ("CL_ParseServerMessage: Bad server message");
937 cmd = MSG_ReadByte ();
941 SHOWNET("END OF MESSAGE");
942 break; // end of message
945 cmdindex = cmdcount & 31;
947 cmdlog[cmdindex] = cmd;
949 // if the high bit of the command byte is set, it is a fast update
952 // 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)
954 cmdlogname[cmdindex] = temp;
955 SHOWNET("fast update");
956 CL_ParseUpdate (cmd&127);
960 SHOWNET(svc_strings[cmd]);
961 cmdlogname[cmdindex] = svc_strings[cmd];
962 if (!cmdlogname[cmdindex])
964 // 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)
966 cmdlogname[cmdindex] = temp;
974 char description[32*64], temp[64];
976 strcpy(description, "packet dump: ");
980 count = cmdcount - i;
984 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
985 strcat(description, temp);
990 description[strlen(description)-1] = '\n'; // replace the last space with a newline
991 Con_Printf(description);
992 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
997 // Con_Printf ("svc_nop\n");
1001 // handle old protocols which do not have entity update ranges
1002 entitiesupdated = true;
1003 cl.mtime[1] = cl.mtime[0];
1004 cl.mtime[0] = MSG_ReadFloat ();
1007 case svc_clientdata:
1008 i = MSG_ReadShort ();
1009 CL_ParseClientdata (i);
1013 i = MSG_ReadLong ();
1014 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
1015 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
1016 Nehahrademcompatibility = false;
1018 Nehahrademcompatibility = true;
1019 if (cls.demoplayback && demo_nehahra.value)
1020 Nehahrademcompatibility = true;
1021 dpprotocol = i == DPPROTOCOL_VERSION;
1024 case svc_disconnect:
1025 Host_EndGame ("Server disconnected\n");
1028 Con_Printf ("%s", MSG_ReadString ());
1031 case svc_centerprint:
1032 SCR_CenterPrint (MSG_ReadString ());
1036 Cbuf_AddText (MSG_ReadString ());
1043 case svc_serverinfo:
1044 CL_ParseServerInfo ();
1045 vid.recalc_refdef = true; // leave intermission full screen
1049 for (i=0 ; i<3 ; i++)
1050 cl.viewangles[i] = MSG_ReadAngle ();
1054 cl.viewentity = MSG_ReadShort ();
1057 case svc_lightstyle:
1058 i = MSG_ReadByte ();
1059 if (i >= MAX_LIGHTSTYLES)
1060 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1061 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1062 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1063 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1067 CL_ParseStartSoundPacket(false);
1071 CL_ParseStartSoundPacket(true);
1075 i = MSG_ReadShort();
1076 S_StopSound(i>>3, i&7);
1079 case svc_updatename:
1080 i = MSG_ReadByte ();
1081 if (i >= cl.maxclients)
1082 Host_Error ("CL_ParseServerMessage: svc_updatename >= MAX_SCOREBOARD");
1083 strcpy (cl.scores[i].name, MSG_ReadString ());
1086 case svc_updatefrags:
1087 i = MSG_ReadByte ();
1088 if (i >= cl.maxclients)
1089 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= MAX_SCOREBOARD");
1090 cl.scores[i].frags = MSG_ReadShort ();
1093 case svc_updatecolors:
1094 i = MSG_ReadByte ();
1095 if (i >= cl.maxclients)
1096 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= MAX_SCOREBOARD");
1097 cl.scores[i].colors = MSG_ReadByte ();
1101 R_ParseParticleEffect ();
1112 case svc_spawnbaseline:
1113 i = MSG_ReadShort ();
1114 // must use CL_EntityNum() to force cl.num_entities up
1115 CL_ParseBaseline (CL_EntityNum(i), false);
1117 case svc_spawnbaseline2:
1118 i = MSG_ReadShort ();
1119 // must use CL_EntityNum() to force cl.num_entities up
1120 CL_ParseBaseline (CL_EntityNum(i), true);
1122 case svc_spawnstatic:
1123 CL_ParseStatic (false);
1125 case svc_spawnstatic2:
1126 CL_ParseStatic (true);
1128 case svc_temp_entity:
1133 cl.paused = MSG_ReadByte ();
1141 i = MSG_ReadByte ();
1142 if (i <= cls.signon)
1143 Host_Error ("Received signon %i when at %i", i, cls.signon);
1148 case svc_killedmonster:
1149 cl.stats[STAT_MONSTERS]++;
1152 case svc_foundsecret:
1153 cl.stats[STAT_SECRETS]++;
1156 case svc_updatestat:
1157 i = MSG_ReadByte ();
1158 if (i < 0 || i >= MAX_CL_STATS)
1159 Host_Error ("svc_updatestat: %i is invalid", i);
1160 cl.stats[i] = MSG_ReadLong ();
1163 case svc_spawnstaticsound:
1164 CL_ParseStaticSound (false);
1167 case svc_spawnstaticsound2:
1168 CL_ParseStaticSound (true);
1172 cl.cdtrack = MSG_ReadByte ();
1173 cl.looptrack = MSG_ReadByte ();
1174 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1175 CDAudio_Play ((byte)cls.forcetrack, true);
1177 CDAudio_Play ((byte)cl.cdtrack, true);
1180 case svc_intermission:
1181 cl.intermission = 1;
1182 cl.completed_time = cl.time;
1183 vid.recalc_refdef = true; // go to full screen
1187 cl.intermission = 2;
1188 cl.completed_time = cl.time;
1189 vid.recalc_refdef = true; // go to full screen
1190 SCR_CenterPrint (MSG_ReadString ());
1194 cl.intermission = 3;
1195 cl.completed_time = cl.time;
1196 vid.recalc_refdef = true; // go to full screen
1197 SCR_CenterPrint (MSG_ReadString ());
1200 case svc_sellscreen:
1201 Cmd_ExecuteString ("help", src_command);
1204 SHOWLMP_decodehide();
1207 SHOWLMP_decodeshow();
1212 if (entitiesupdated)
1213 CL_EntityUpdateEnd();