1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
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.
8 
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.
12 
13 See the GNU General Public License for more details.
14 
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.
18 
19 */
20 // common.c -- misc functions used in client and server
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include "qcommon.h"
27 
28 #include <setjmp.h>
29 
30 //zlib currently not needed server-side (FOR NOW!)
31 //Also, due to the ld flags for zlib not being used server side, it won't
32 //compile without this workaround.
33 #ifdef DEDICATED_ONLY
34 #undef HAVE_ZLIB
35 #endif
36 
37 #ifdef HAVE_ZLIB
38 #include <zlib.h>
39 #endif
40 
41 #define	MAXPRINTMSG	8192
42 
43 #define MAX_NUM_ARGVS	50
44 
45 #ifndef DEDICATED_ONLY
46 extern void S_StartMenuMusic( void );
47 #endif
48 
49 extern void CL_Disconnect(void);
50 
51 int		com_argc;
52 char	*com_argv[MAX_NUM_ARGVS+1];
53 
54 int		realtime;
55 
56 jmp_buf abortframe;		// an ERR_DROP occured, exit the entire frame
57 
58 
59 FILE	*log_stats_file;
60 
61 cvar_t	*host_speeds;
62 cvar_t	*log_stats;
63 cvar_t	*developer;
64 cvar_t	*timescale;
65 cvar_t	*fixedtime;
66 cvar_t	*logfile_active;	// 1 = buffer log, 2 = flush after each print
67 cvar_t	*logfile_name;
68 cvar_t	*showtrace;
69 cvar_t	*dedicated;
70 
71 FILE	*logfile;
72 
73 int			server_state;
74 
75 // host_speeds times
76 int		time_before_game;
77 int		time_after_game;
78 int		time_before_ref;
79 int		time_after_ref;
80 
81 /*
82 ============================================================================
83 
84 CLIENT / SERVER interactions
85 
86 ============================================================================
87 */
88 
89 static int	rd_target;
90 static char	*rd_buffer;
91 static int	rd_buffersize;
92 static void	(*rd_flush)(int target, char *buffer);
93 
Com_BeginRedirect(int target,char * buffer,int buffersize,void (* flush))94 void Com_BeginRedirect (int target, char *buffer, int buffersize, void (*flush))
95 {
96 	if (!target || !buffer || !buffersize || !flush)
97 		return;
98 	rd_target = target;
99 	rd_buffer = buffer;
100 	rd_buffersize = buffersize;
101 	rd_flush = flush;
102 
103 	*rd_buffer = 0;
104 }
105 
Com_EndRedirect(void)106 void Com_EndRedirect (void)
107 {
108 	rd_flush(rd_target, rd_buffer);
109 
110 	rd_target = 0;
111 	rd_buffer = NULL;
112 	rd_buffersize = 0;
113 	rd_flush = NULL;
114 }
115 
116 /*
117 =============
118 Com_Printf
119 
120 Both client and server can use this, and it will output
121 to the apropriate place.
122 =============
123 */
Com_Printf(char * fmt,...)124 void Com_Printf (char *fmt, ...)
125 {
126 	va_list		argptr;
127 	char		msg[MAXPRINTMSG];
128 
129 	va_start (argptr,fmt);
130 	vsnprintf(msg, sizeof(msg), fmt, argptr);
131 	va_end (argptr);
132 
133 	if (rd_target)
134 	{
135 		if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1))
136 		{
137 			rd_flush(rd_target, rd_buffer);
138 			*rd_buffer = 0;
139 		}
140 		strcat (rd_buffer, msg);
141 		return;
142 	}
143 
144 	CON_Print( msg );
145 
146 	// also echo to debugging console
147 	Sys_ConsoleOutput (msg);
148 
149 #if defined WIN32_VARIANT
150 	// Also echo to dedicated console
151 	Sys_Print(msg);
152 #endif
153 
154 	// if logfile_active or logfile_name have been modified, close the current log file
155 	if ( ( (logfile_active && logfile_active->modified)
156 			|| (logfile_name && logfile_name->modified) ) && logfile )
157 	{
158 		fclose (logfile);
159 		logfile = NULL;
160 		if (logfile_active) {
161 			logfile_active->modified = false;
162 		}
163 		if (logfile_name) {
164 			logfile_name->modified = false;
165 		}
166 	}
167 
168 	// logfile
169 	if (logfile_active && logfile_active->value)
170 	{
171 		char		name[MAX_OSPATH];
172 		const char 	*f_name;
173 
174 		if (!logfile)
175 		{
176 			f_name = logfile_name ? logfile_name->string : "qconsole.log";
177 			Com_sprintf (name, sizeof(name), "%s/%s", FS_Gamedir (), f_name);
178 
179 			if (logfile_active->value > 2)
180 				logfile = fopen (name, "a");
181 			else
182 				logfile = fopen (name, "w");
183 		}
184 		if (logfile) {
185 			fprintf (logfile, "%s", msg);
186 			if (logfile_active->value > 1)
187 				fflush (logfile);		// force it to save every time
188 		}
189 	}
190 }
191 
192 
193 /*
194 ================
195 Com_DPrintf
196 
197 A Com_Printf that only shows up if the "developer" cvar is set
198 ================
199 */
Com_DPrintf(char * fmt,...)200 void Com_DPrintf (char *fmt, ...)
201 {
202 	va_list		argptr;
203 	char		msg[MAXPRINTMSG];
204 
205 	if (!developer || !developer->value)
206 		return;			// don't confuse non-developers with techie stuff...
207 
208 	va_start (argptr,fmt);
209 	vsnprintf(msg, sizeof(msg), fmt, argptr);
210 	va_end (argptr);
211 
212 	Com_Printf ("%s", msg);
213 }
214 
215 
216 /*
217 =============
218 Com_Error
219 
220 Both client and server can use this, and it will
221 do the apropriate things.
222 =============
223 */
Com_Error(int code,char * fmt,...)224 void Com_Error (int code, char *fmt, ...)
225 {
226 	va_list		argptr;
227 	static char		msg[MAXPRINTMSG];
228 	static	qboolean	recursive = false;
229 
230 	if (recursive)
231 		Sys_Error ("recursive error after: %s", msg);
232 	recursive = true;
233 
234 	va_start (argptr,fmt);
235 	vsnprintf(msg, sizeof(msg), fmt, argptr);
236 	va_end (argptr);
237 
238 	if (code == ERR_DISCONNECT)
239 	{
240 		CL_Drop ();
241 		recursive = false;
242 		longjmp (abortframe, -1);
243 	}
244 	else if (code == ERR_DROP)
245 	{
246 		Com_Printf ("********************\nERROR: %s\n********************\n", msg);
247 		SV_Shutdown (va("Server crashed: %s\n", msg), false);
248 		CL_Drop ();
249 		recursive = false;
250 		longjmp (abortframe, -1);
251 	}
252 	else
253 	{
254 		SV_Shutdown (va("Server fatal crashed: %s\n", msg), false);
255 		CL_Shutdown ();
256 	}
257 
258 	if (logfile)
259 	{
260 		fclose (logfile);
261 		logfile = NULL;
262 	}
263 
264 	Sys_Error ("%s", msg);
265 }
266 
267 
268 /*
269 =============
270 Com_Quit
271 
272 Both client and server can use this, and it will
273 do the apropriate things.
274 =============
275 */
Com_Quit(void)276 void Com_Quit (void)
277 {
278 	SV_Shutdown ("Server quit\n", false);
279 	CL_Shutdown ();
280 
281 	if (logfile)
282 	{
283 		fclose (logfile);
284 		logfile = NULL;
285 	}
286 
287 	Sys_Quit ();
288 }
289 
290 
291 /*
292 ==================
293 Com_ServerState
294 ==================
295 */
Com_ServerState(void)296 int Com_ServerState (void)
297 {
298 	return server_state;
299 }
300 
301 /*
302 ==================
303 Com_SetServerState
304 ==================
305 */
Com_SetServerState(int state)306 void Com_SetServerState (int state)
307 {
308 	server_state = state;
309 }
310 
311 
312 /*
313 ==============================================================================
314 
315 			MESSAGE IO FUNCTIONS
316 
317 Handles byte ordering and avoids alignment errors
318 ==============================================================================
319 */
320 
321 vec3_t	bytedirs[NUMVERTEXNORMALS] =
322 {
323 #include "../client/anorms.h"
324 };
325 
326 //
327 // writing functions
328 //
329 
MSG_WriteChar(sizebuf_t * sb,int c)330 void MSG_WriteChar (sizebuf_t *sb, int c)
331 {
332 	byte	*buf;
333 
334 #ifdef PARANOID
335 	if (c < -128 || c > 127)
336 	{
337 		// Com_Printf( "MSG_WriteChar: range error: %i\n", c);
338 		Com_Error (ERR_FATAL, "MSG_WriteChar: range error");
339 	}
340 #endif
341 
342 	buf = SZ_GetSpace (sb, 1);
343 	buf[0] = c;
344 }
345 
MSG_WriteByte(sizebuf_t * sb,int c)346 void MSG_WriteByte (sizebuf_t *sb, int c)
347 {
348 	byte	*buf;
349 
350 #ifdef PARANOID
351 	if (c < 0 || c > 255) {
352 		//Com_Printf( "MSG_WriteByte: range error: %i\n", c );
353 		Com_Error (ERR_FATAL, "MSG_WriteByte: range error");
354 	}
355 #endif
356 
357 	buf = SZ_GetSpace (sb, 1);
358 	buf[0] = c;
359 }
360 
MSG_WriteShort(sizebuf_t * sb,int c)361 void MSG_WriteShort (sizebuf_t *sb, int c)
362 {
363 #if 0
364 	/* Original Version */
365 	byte	*buf;
366 
367 #ifdef PARANOID
368 	if ( c > 65535 )
369 	{ // unsigned short actually
370 		//Com_Printf("MSG_WriteShort: range error: %i \n", c);
371 		Com_Error (ERR_FATAL, "MSG_WriteShort: range error");
372 	}
373 #endif
374 
375 	buf = SZ_GetSpace (sb, 2);
376 	buf[0] = c&0xff;
377 	buf[1] = c>>8;
378 #else
379 	/* Experimental Version */
380 	short *buf;
381 
382 	buf  = (short*)SZ_GetSpace( sb , 2 );
383 	*buf = LittleShort( c );
384 #endif
385 }
386 
MSG_WriteLong(sizebuf_t * sb,int c)387 void MSG_WriteLong (sizebuf_t *sb, int c)
388 {
389 #if 0
390 	/* Original Version */
391 	byte	*buf;
392 
393 	buf = SZ_GetSpace (sb, 4);
394 	buf[0] = c&0xff;
395 	buf[1] = (c>>8)&0xff;
396 	buf[2] = (c>>16)&0xff;
397 	buf[3] = c>>24;
398 #else
399 	/* Experimental Version */
400 	int *buf;
401 
402 	buf  = (int*)SZ_GetSpace( sb, 4 );
403 	*buf = LittleLong( c );
404 #endif
405 }
406 
MSG_WriteSizeInt(sizebuf_t * sb,int bytes,int c)407 void MSG_WriteSizeInt (sizebuf_t *sb, int bytes, int c)
408 {
409 	byte		*buf;
410 	int			i;
411 
412 	// manually construct two's complement encoding with appropriate bit depth
413 	if (c < 0 && bytes != sizeof(c))
414 		c += 1<<(8*bytes);
415 
416 	buf = SZ_GetSpace (sb, bytes);
417 	for (i = 0; i < bytes; i++)
418 		buf[i] = (byte)((c>>(8*i))&0xff);
419 }
420 
MSG_WriteFloat(sizebuf_t * sb,float f)421 void MSG_WriteFloat (sizebuf_t *sb, float f)
422 {
423 	union
424 	{
425 		float	f;
426 		int	l;
427 	} dat;
428 
429 
430 	dat.f = f;
431 	dat.l = LittleLong (dat.l);
432 
433 	SZ_Write (sb, &dat.l, 4);
434 }
435 
MSG_WriteString(sizebuf_t * sb,char * s)436 void MSG_WriteString (sizebuf_t *sb, char *s)
437 {
438 	if (!s)
439 		SZ_Write (sb, "", 1);
440 	else
441 		SZ_Write (sb, s, strlen(s)+1);
442 }
443 
MSG_WriteCoord(sizebuf_t * sb,float f)444 void MSG_WriteCoord (sizebuf_t *sb, float f)
445 {
446 	MSG_WriteSizeInt (sb, coord_bytes, (int)(f*8));
447 }
448 
MSG_WritePos(sizebuf_t * sb,vec3_t pos)449 void MSG_WritePos (sizebuf_t *sb, vec3_t pos)
450 {
451 	MSG_WriteSizeInt (sb, coord_bytes, (int)(pos[0]*8));
452 	MSG_WriteSizeInt (sb, coord_bytes, (int)(pos[1]*8));
453 	MSG_WriteSizeInt (sb, coord_bytes, (int)(pos[2]*8));
454 }
455 
MSG_WriteAngle(sizebuf_t * sb,float f)456 void MSG_WriteAngle (sizebuf_t *sb, float f)
457 {
458 	MSG_WriteByte (sb, (int)(f*256/360) & 255);
459 }
460 
MSG_WriteAngle16(sizebuf_t * sb,float f)461 void MSG_WriteAngle16 (sizebuf_t *sb, float f)
462 {
463 	MSG_WriteShort (sb, ANGLE2SHORT(f));
464 }
465 
466 
MSG_WriteDeltaUsercmd(sizebuf_t * buf,usercmd_t * from,usercmd_t * cmd)467 void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
468 {
469 	int		bits;
470 
471 //
472 // send the movement message
473 //
474 	bits = 0;
475 	if (cmd->angles[0] != from->angles[0])
476 		bits |= CM_ANGLE1;
477 	if (cmd->angles[1] != from->angles[1])
478 		bits |= CM_ANGLE2;
479 	if (cmd->angles[2] != from->angles[2])
480 		bits |= CM_ANGLE3;
481 	if (cmd->forwardmove != from->forwardmove)
482 		bits |= CM_FORWARD;
483 	if (cmd->sidemove != from->sidemove)
484 		bits |= CM_SIDE;
485 	if (cmd->upmove != from->upmove)
486 		bits |= CM_UP;
487 	if (cmd->buttons != from->buttons)
488 		bits |= CM_BUTTONS;
489 	if (cmd->impulse != from->impulse)
490 		bits |= CM_IMPULSE;
491 
492     MSG_WriteByte (buf, bits);
493 
494 	if (bits & CM_ANGLE1)
495 		MSG_WriteShort (buf, cmd->angles[0]);
496 	if (bits & CM_ANGLE2)
497 		MSG_WriteShort (buf, cmd->angles[1]);
498 	if (bits & CM_ANGLE3)
499 		MSG_WriteShort (buf, cmd->angles[2]);
500 
501 	if (bits & CM_FORWARD)
502 		MSG_WriteShort (buf, cmd->forwardmove);
503 	if (bits & CM_SIDE)
504 	  	MSG_WriteShort (buf, cmd->sidemove);
505 	if (bits & CM_UP)
506 		MSG_WriteShort (buf, cmd->upmove);
507 
508  	if (bits & CM_BUTTONS)
509 	  	MSG_WriteByte (buf, cmd->buttons);
510  	if (bits & CM_IMPULSE)
511 	    MSG_WriteByte (buf, cmd->impulse);
512 
513     MSG_WriteByte (buf, cmd->msec);
514 	MSG_WriteByte (buf, cmd->lightlevel);
515 }
516 
517 
MSG_WriteDir(sizebuf_t * sb,vec3_t dir)518 void MSG_WriteDir (sizebuf_t *sb, vec3_t dir)
519 {
520 	int		i, best;
521 	float	d,x,y,z;
522 
523 	if (!dir)
524 	{
525 		MSG_WriteByte (sb, 0);
526 		return;
527 	}
528 
529 	x = dir[0];
530 	y = dir[1];
531 	z = dir[2];
532 	best = 0;
533 
534 	d = (x*x) + (y*y) + (z*z);
535 	// sometimes dir is {0,0,0}
536 	if ( d == 0.0f )
537 	{
538 		MSG_WriteByte( sb, 0 );
539 		return;
540 	}
541 	// sometimes dir is not normalized
542 	if ( d < 0.999f || d > 1.001f )
543 	{
544 		d = 1.0 / sqrt( d );
545 		x *= d;
546 		y *= d;
547 		z *= d;
548 	}
549 	// frequently occurring axial cases, use known best index
550 	if ( x == 0.0f && y == 0.0f )
551 	{
552 		best = ( z >= 0.999f ) ? 5  : 84;
553 	}
554 	else if ( x == 0.0f && z == 0.0f )
555 	{
556 		best = ( y >= 0.999f ) ? 32 : 104;
557 	}
558 	else if ( y == 0.0f && z == 0.0f )
559 	{
560 		best = ( x >= 0.999f ) ? 52 : 143;
561 	}
562 	else
563 	{ // general case
564 		float bestd = 0.0f;
565 		for ( i = 0 ; i < NUMVERTEXNORMALS ; i++ )
566 		{ // search for closest match
567 			d = (x*bytedirs[i][0]) + (y*bytedirs[i][1]) + (z*bytedirs[i][2]);
568 			if ( d > 0.998f )
569 			{ // no other entry could be a closer match
570 				//  0.9679495 is max dot product between anorm.h entries
571 				best = i;
572 				break;
573 			}
574 			if ( d > bestd )
575 			{
576 				bestd = d;
577 				best = i;
578 			}
579 		}
580 	}
581 
582 	MSG_WriteByte (sb, best);
583 }
584 
585 
MSG_ReadDir(sizebuf_t * sb,vec3_t dir)586 void MSG_ReadDir (sizebuf_t *sb, vec3_t dir)
587 {
588 	int		b;
589 
590 	b = MSG_ReadByte (sb);
591 	if (b >= NUMVERTEXNORMALS)
592 		Com_Error (ERR_DROP, "MSG_ReadDir: out of range");
593 	VectorCopy (bytedirs[b], dir);
594 }
595 
596 
597 /*
598 ==================
599 MSG_WriteDeltaEntity
600 
601 Writes part of a packetentities message.
602 Can delta from either a baseline or a previous packet_entity
603 ==================
604 */
MSG_WriteDeltaEntity(entity_state_t * from,entity_state_t * to,sizebuf_t * msg,qboolean force,qboolean newentity)605 void MSG_WriteDeltaEntity (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, qboolean newentity)
606 {
607 	int		bits;
608 
609 	if (!to->number)
610 		Com_Error (ERR_FATAL, "Unset entity number");
611 	if (to->number >= MAX_EDICTS)
612 		Com_Error (ERR_FATAL, "Entity number >= MAX_EDICTS");
613 
614 // send an update
615 	bits = 0;
616 
617 	if (to->number >= 256)
618 		bits |= U_NUMBER16;		// number8 is implicit otherwise
619 
620 	if (to->origin[0] != from->origin[0])
621 		bits |= U_ORIGIN1;
622 	if (to->origin[1] != from->origin[1])
623 		bits |= U_ORIGIN2;
624 	if (to->origin[2] != from->origin[2])
625 		bits |= U_ORIGIN3;
626 
627 	if ( to->angles[0] != from->angles[0] )
628 		bits |= U_ANGLE1;
629 	if ( to->angles[1] != from->angles[1] )
630 		bits |= U_ANGLE2;
631 	if ( to->angles[2] != from->angles[2] )
632 		bits |= U_ANGLE3;
633 
634 	if ( to->skinnum != from->skinnum )
635 	{
636 		if ((unsigned)to->skinnum < 256)
637 			bits |= U_SKIN8;
638 		else if ((unsigned)to->skinnum < 0x10000)
639 			bits |= U_SKIN16;
640 		else
641 			bits |= (U_SKIN8|U_SKIN16);
642 	}
643 
644 	if ( to->frame != from->frame )
645 	{
646 		if (to->frame < 256)
647 			bits |= U_FRAME8;
648 		else
649 			bits |= U_FRAME16;
650 	}
651 
652 	if ( to->effects != from->effects )
653 	{
654 		if (to->effects < 256)
655 			bits |= U_EFFECTS8;
656 		else if (to->effects < 0x8000)
657 			bits |= U_EFFECTS16;
658 		else
659 			bits |= U_EFFECTS8|U_EFFECTS16;
660 	}
661 
662 	if ( to->renderfx != from->renderfx )
663 	{
664 		if (to->renderfx < 256)
665 			bits |= U_RENDERFX8;
666 		else if (to->renderfx < 0x8000)
667 			bits |= U_RENDERFX16;
668 		else
669 			bits |= U_RENDERFX8|U_RENDERFX16;
670 	}
671 
672 	if ( to->solid != from->solid )
673 		bits |= U_SOLID;
674 
675 	// event is not delta compressed, just 0 compressed
676 	if ( to->event  )
677 		bits |= U_EVENT;
678 
679 	if ( to->modelindex != from->modelindex )
680 		bits |= U_MODEL;
681 	if ( to->modelindex2 != from->modelindex2 )
682 		bits |= U_MODEL2;
683 	if ( to->modelindex3 != from->modelindex3 )
684 		bits |= U_MODEL3;
685 	if ( to->modelindex4 != from->modelindex4 )
686 		bits |= U_MODEL4;
687 
688 	if ( to->sound != from->sound )
689 		bits |= U_SOUND;
690 
691 	if (newentity || (to->renderfx & RF_BEAM))
692 		bits |= U_OLDORIGIN;
693 
694 	//
695 	// write the message
696 	//
697 	if (!bits && !force)
698 		return;		// nothing to send!
699 
700 	//----------
701 
702 	if (bits & 0xff000000)
703 		bits |= U_MOREBITS3 | U_MOREBITS2 | U_MOREBITS1;
704 	else if (bits & 0x00ff0000)
705 		bits |= U_MOREBITS2 | U_MOREBITS1;
706 	else if (bits & 0x0000ff00)
707 		bits |= U_MOREBITS1;
708 
709 	MSG_WriteByte (msg,	bits&255 );
710 
711 	if (bits & 0xff000000)
712 	{
713 		MSG_WriteByte (msg,	(bits>>8)&255 );
714 		MSG_WriteByte (msg,	(bits>>16)&255 );
715 		MSG_WriteByte (msg,	(bits>>24)&255 );
716 	}
717 	else if (bits & 0x00ff0000)
718 	{
719 		MSG_WriteByte (msg,	(bits>>8)&255 );
720 		MSG_WriteByte (msg,	(bits>>16)&255 );
721 	}
722 	else if (bits & 0x0000ff00)
723 	{
724 		MSG_WriteByte (msg,	(bits>>8)&255 );
725 	}
726 
727 	//----------
728 
729 	if (bits & U_NUMBER16)
730 		MSG_WriteShort (msg, to->number);
731 	else
732 		MSG_WriteByte (msg,	to->number);
733 
734 	if (bits & U_MODEL)
735 		MSG_WriteByte (msg,	to->modelindex);
736 	if (bits & U_MODEL2)
737 		MSG_WriteByte (msg,	to->modelindex2);
738 	if (bits & U_MODEL3)
739 		MSG_WriteByte (msg,	to->modelindex3);
740 	if (bits & U_MODEL4)
741 		MSG_WriteByte (msg,	to->modelindex4);
742 
743 	if (bits & U_FRAME8)
744 		MSG_WriteByte (msg, to->frame);
745 	if (bits & U_FRAME16)
746 		MSG_WriteShort (msg, to->frame);
747 
748 	if ((bits & U_SKIN8) && (bits & U_SKIN16))		//used for laser colors
749 		MSG_WriteLong (msg, to->skinnum);
750 	else if (bits & U_SKIN8)
751 		MSG_WriteByte (msg, to->skinnum);
752 	else if (bits & U_SKIN16)
753 		MSG_WriteShort (msg, to->skinnum);
754 
755 
756 	if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) )
757 		MSG_WriteLong (msg, to->effects);
758 	else if (bits & U_EFFECTS8)
759 		MSG_WriteByte (msg, to->effects);
760 	else if (bits & U_EFFECTS16)
761 		MSG_WriteShort (msg, to->effects);
762 
763 	if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) )
764 		MSG_WriteLong (msg, to->renderfx);
765 	else if (bits & U_RENDERFX8)
766 		MSG_WriteByte (msg, to->renderfx);
767 	else if (bits & U_RENDERFX16)
768 		MSG_WriteShort (msg, to->renderfx);
769 
770 	if (bits & U_ORIGIN1)
771 		MSG_WriteCoord (msg, to->origin[0]);
772 	if (bits & U_ORIGIN2)
773 		MSG_WriteCoord (msg, to->origin[1]);
774 	if (bits & U_ORIGIN3)
775 		MSG_WriteCoord (msg, to->origin[2]);
776 
777 	if (bits & U_ANGLE1)
778 		MSG_WriteAngle(msg, to->angles[0]);
779 	if (bits & U_ANGLE2)
780 		MSG_WriteAngle(msg, to->angles[1]);
781 	if (bits & U_ANGLE3)
782 		MSG_WriteAngle(msg, to->angles[2]);
783 
784 	if (bits & U_OLDORIGIN)
785 	{
786 		MSG_WriteCoord (msg, to->old_origin[0]);
787 		MSG_WriteCoord (msg, to->old_origin[1]);
788 		MSG_WriteCoord (msg, to->old_origin[2]);
789 	}
790 
791 	if (bits & U_SOUND)
792 		MSG_WriteByte (msg, to->sound);
793 	if (bits & U_EVENT)
794 		MSG_WriteByte (msg, to->event);
795 	if (bits & U_SOLID)
796 		MSG_WriteShort (msg, to->solid);
797 }
798 
799 
800 //============================================================
801 
802 //
803 // reading functions
804 //
805 
MSG_BeginReading(sizebuf_t * msg)806 void MSG_BeginReading (sizebuf_t *msg)
807 {
808 	msg->readcount = 0;
809 }
810 
811 // returns -1 if no more characters are available
MSG_ReadChar(sizebuf_t * msg_read)812 int MSG_ReadChar (sizebuf_t *msg_read)
813 {
814 	int	c;
815 
816 	if (msg_read->readcount+1 > msg_read->cursize)
817 		c = -1;
818 	else
819 		c = (signed char)msg_read->data[msg_read->readcount];
820 	msg_read->readcount++;
821 
822 	return c;
823 }
824 
MSG_ReadByte(sizebuf_t * msg_read)825 int MSG_ReadByte (sizebuf_t *msg_read)
826 {
827 	int	c;
828 
829 	if (msg_read->readcount+1 > msg_read->cursize)
830 		c = -1;
831 	else
832 		c = (unsigned char)msg_read->data[msg_read->readcount];
833 	msg_read->readcount++;
834 
835 	return c;
836 }
837 
MSG_ReadShort(sizebuf_t * msg_read)838 int MSG_ReadShort (sizebuf_t *msg_read)
839 {
840 #if 0
841 	/* Origninal Version */
842 	int	c;
843 
844 	if (msg_read->readcount+2 > msg_read->cursize)
845 		c = -1;
846 	else
847 		c = (short)(msg_read->data[msg_read->readcount]
848 		+ (msg_read->data[msg_read->readcount+1]<<8));
849 
850 	msg_read->readcount += 2;
851 
852 	return c;
853 #else
854 	/* Experimental Version */
855 	int c     = -1;
856 	int rc    = msg_read->readcount;
857 	short *pi = (short*)(&msg_read->data[ rc ]);
858 
859 	rc += 2;
860 	if ( rc <= msg_read->cursize )
861 	{
862 		c = LittleShort( *pi );
863 		msg_read->readcount = rc;
864 	}
865 
866 	return c;
867 #endif
868 }
869 
MSG_ReadLong(sizebuf_t * msg_read)870 int MSG_ReadLong (sizebuf_t *msg_read)
871 {
872 #if 0
873 	/* Original Version */
874 	int	c;
875 
876 	if (msg_read->readcount+4 > msg_read->cursize)
877 		c = -1;
878 	else
879 		c = msg_read->data[msg_read->readcount]
880 		+ (msg_read->data[msg_read->readcount+1]<<8)
881 		+ (msg_read->data[msg_read->readcount+2]<<16)
882 		+ (msg_read->data[msg_read->readcount+3]<<24);
883 
884 	msg_read->readcount += 4;
885 
886 	return c;
887 #else
888 	/* Experimental Version */
889 	int c   = -1;
890 	int rc  = msg_read->readcount;
891 	int *pi = (int*)(&msg_read->data[rc]);
892 
893 	rc += 4;
894 	if ( rc <= msg_read->cursize )
895 	{
896 		c = LittleLong( *pi );
897 		msg_read->readcount = rc;
898 	}
899 
900 	return c;
901 #endif
902 }
903 
MSG_ReadSizeInt(sizebuf_t * msg_read,int bytes)904 int MSG_ReadSizeInt (sizebuf_t *msg_read, int bytes)
905 {
906 	int c, i;
907 
908 	if (msg_read->readcount+bytes > msg_read->cursize)
909 		c = -1;
910 	else
911 	{
912 		c = 0;
913 		for (i = 0; i < bytes; i++)
914 			c += msg_read->data[msg_read->readcount++] << (8*i);
915 		// check sign bit and sign-extend to 32 bits if needed
916 		if (bytes != sizeof(c) && (c & 1<<(8*bytes-1)))
917 			for (; i < sizeof(c); i++)
918 				c += 0xff<<(8*i);
919 	}
920 
921 	return c;
922 }
923 
MSG_ReadFloat(sizebuf_t * msg_read)924 float MSG_ReadFloat (sizebuf_t *msg_read)
925 {
926 	union
927 	{
928 		byte	b[4];
929 		float	f;
930 		int	l;
931 	} dat;
932 
933 	if (msg_read->readcount+4 > msg_read->cursize)
934 		dat.f = -1;
935 	else
936 	{
937 		dat.b[0] =	msg_read->data[msg_read->readcount];
938 		dat.b[1] =	msg_read->data[msg_read->readcount+1];
939 		dat.b[2] =	msg_read->data[msg_read->readcount+2];
940 		dat.b[3] =	msg_read->data[msg_read->readcount+3];
941 	}
942 	msg_read->readcount += 4;
943 
944 	dat.l = LittleLong (dat.l);
945 
946 	return dat.f;
947 }
948 
MSG_ReadString(sizebuf_t * msg_read)949 char *MSG_ReadString (sizebuf_t *msg_read)
950 {
951 	static char	string[2048];
952 	int		l,c;
953 
954 	l = 0;
955 	do
956 	{
957 		// sku - replaced MSG_ReadChar with MSG_ReadByte to avoid
958 		// potentional vulnerability
959 		c = MSG_ReadByte (msg_read);
960 		if (c == -1 || c == 0)
961 			break;
962 		string[l] = c;
963 		l++;
964 	} while (l < sizeof(string)-1);
965 
966 	string[l] = 0;
967 
968 	return string;
969 }
970 
MSG_ReadStringLine(sizebuf_t * msg_read)971 char *MSG_ReadStringLine (sizebuf_t *msg_read)
972 {
973 	static char	string[2048];
974 	int		l,c;
975 
976 	l = 0;
977 	do
978 	{
979 		// sku - replaced MSG_ReadChar with MSG_ReadByte to avoid
980 		// potentional vulnerability
981 		c = MSG_ReadByte (msg_read);
982 		if (c == -1 || c == 0 || c == '\n')
983 			break;
984 		string[l] = c;
985 		l++;
986 	} while (l < sizeof(string)-1);
987 
988 	string[l] = 0;
989 
990 	return string;
991 }
992 
MSG_ReadCoord(sizebuf_t * msg_read)993 float MSG_ReadCoord (sizebuf_t *msg_read)
994 {
995 	return MSG_ReadSizeInt(msg_read, coord_bytes) * (1.0/8);
996 }
997 
MSG_ReadPos(sizebuf_t * msg_read,vec3_t pos)998 void MSG_ReadPos (sizebuf_t *msg_read, vec3_t pos)
999 {
1000 	pos[0] = MSG_ReadSizeInt(msg_read, coord_bytes) * (1.0/8);
1001 	pos[1] = MSG_ReadSizeInt(msg_read, coord_bytes) * (1.0/8);
1002 	pos[2] = MSG_ReadSizeInt(msg_read, coord_bytes) * (1.0/8);
1003 }
1004 
MSG_ReadAngle(sizebuf_t * msg_read)1005 float MSG_ReadAngle (sizebuf_t *msg_read)
1006 {
1007 	return MSG_ReadChar(msg_read) * (360.0/256);
1008 }
1009 
MSG_ReadAngle16(sizebuf_t * msg_read)1010 float MSG_ReadAngle16 (sizebuf_t *msg_read)
1011 {
1012 	return SHORT2ANGLE(MSG_ReadShort(msg_read));
1013 }
1014 
MSG_ReadDeltaUsercmd(sizebuf_t * msg_read,usercmd_t * from,usercmd_t * move)1015 void MSG_ReadDeltaUsercmd (sizebuf_t *msg_read, usercmd_t *from, usercmd_t *move)
1016 {
1017 	int bits;
1018 
1019 	memcpy (move, from, sizeof(*move));
1020 
1021 	bits = MSG_ReadByte (msg_read);
1022 
1023 // read current angles
1024 	if (bits & CM_ANGLE1)
1025 		move->angles[0] = MSG_ReadShort (msg_read);
1026 	if (bits & CM_ANGLE2)
1027 		move->angles[1] = MSG_ReadShort (msg_read);
1028 	if (bits & CM_ANGLE3)
1029 		move->angles[2] = MSG_ReadShort (msg_read);
1030 
1031 // read movement
1032 	if (bits & CM_FORWARD)
1033 		move->forwardmove = MSG_ReadShort (msg_read);
1034 	if (bits & CM_SIDE)
1035 		move->sidemove = MSG_ReadShort (msg_read);
1036 	if (bits & CM_UP)
1037 		move->upmove = MSG_ReadShort (msg_read);
1038 
1039 // read buttons
1040 	if (bits & CM_BUTTONS)
1041 		move->buttons = MSG_ReadByte (msg_read);
1042 
1043 	if (bits & CM_IMPULSE)
1044 		move->impulse = MSG_ReadByte (msg_read);
1045 
1046 // read time to run command
1047 	move->msec = MSG_ReadByte (msg_read);
1048 
1049 // read the light level
1050 	move->lightlevel = MSG_ReadByte (msg_read);
1051 }
1052 
1053 
MSG_ReadData(sizebuf_t * msg_read,void * data,int len)1054 void MSG_ReadData (sizebuf_t *msg_read, void *data, int len)
1055 {
1056 	int		i;
1057 
1058 	for (i=0 ; i<len ; i++)
1059 		((byte *)data)[i] = MSG_ReadByte (msg_read);
1060 }
1061 
1062 
1063 //===========================================================================
1064 
SZ_Init(sizebuf_t * buf,byte * data,int length)1065 void SZ_Init (sizebuf_t *buf, byte *data, int length)
1066 {
1067 	memset (buf, 0, sizeof(*buf));
1068 	buf->data = data;
1069 	buf->maxsize = length;
1070 }
1071 
1072 #ifdef	BUFFER_DEBUG
SZ_SetName(sizebuf_t * buf,const char * name,qboolean print_it)1073 void SZ_SetName(sizebuf_t * buf, const char * name, qboolean print_it)
1074 {
1075 	strncpy(buf->name, name, sizeof(buf->name) - 1);
1076 	if ( print_it )
1077 		Com_DPrintf("SZ_SetName: buffer '%s' (address = 0x%.12x) initialised\n", buf->name, buf);
1078 }
1079 #endif	//BUFFER_DEBUG
1080 
SZ_Clear(sizebuf_t * buf)1081 void SZ_Clear (sizebuf_t *buf)
1082 {
1083 	buf->cursize = 0;
1084 	buf->overflowed = false;
1085 }
1086 
SZ_GetSpace(sizebuf_t * buf,int length)1087 void *SZ_GetSpace (sizebuf_t *buf, int length)
1088 {
1089 	void	*data;
1090 
1091 	if (buf->cursize + length > buf->maxsize)
1092 	{
1093 		if (!buf->allowoverflow)
1094 			Com_Error (ERR_FATAL, "SZ_GetSpace: overflow without allowoverflow set");
1095 
1096 		if (length > buf->maxsize)
1097 			Com_Error (ERR_FATAL, "SZ_GetSpace: %i is > full buffer size", length);
1098 
1099 #ifdef	BUFFER_DEBUG
1100 		Com_Printf ("SZ_GetSpace (%s at 0x%.12x): overflow\n", buf->name, buf);
1101 #else	//BUFFER_DEBUG
1102 		Com_Printf ("SZ_GetSpace: overflow\n");
1103 #endif	//BUFFER_DEBUG
1104 		SZ_Clear (buf);
1105 		buf->overflowed = true;
1106 	}
1107 
1108 	data = buf->data + buf->cursize;
1109 	buf->cursize += length;
1110 
1111 	return data;
1112 }
1113 
SZ_Write(sizebuf_t * buf,void * data,int length)1114 void SZ_Write (sizebuf_t *buf, void *data, int length)
1115 {
1116 	memcpy (SZ_GetSpace(buf,length),data,length);
1117 }
1118 
SZ_Print(sizebuf_t * buf,char * data)1119 void SZ_Print (sizebuf_t *buf, char *data)
1120 {
1121 	int		len;
1122 
1123 	len = strlen(data)+1;
1124 
1125 	if (buf->cursize)
1126 	{
1127 		if (buf->data[buf->cursize-1])
1128 			memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0
1129 		else
1130 			memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0
1131 	}
1132 	else
1133 		memcpy ((byte *)SZ_GetSpace(buf, len),data,len);
1134 }
1135 
1136 
1137 //============================================================================
1138 
1139 
1140 /*
1141 ================
1142 COM_CheckParm
1143 
1144 Returns the position (1 to argc-1) in the program's argument list
1145 where the given parameter apears, or 0 if not present
1146 ================
1147 */
COM_CheckParm(char * parm)1148 int COM_CheckParm (char *parm)
1149 {
1150 	int		i;
1151 
1152 	for (i=1 ; i<com_argc ; i++)
1153 	{
1154 		if (!strcmp (parm,com_argv[i]))
1155 			return i;
1156 	}
1157 
1158 	return 0;
1159 }
1160 
COM_Argc(void)1161 int COM_Argc (void)
1162 {
1163 	return com_argc;
1164 }
1165 
COM_Argv(int arg)1166 char *COM_Argv (int arg)
1167 {
1168 	if (arg < 0 || arg >= com_argc || !com_argv[arg])
1169 		return "";
1170 	return com_argv[arg];
1171 }
1172 
COM_ClearArgv(int arg)1173 void COM_ClearArgv (int arg)
1174 {
1175 	if (arg < 0 || arg >= com_argc || !com_argv[arg])
1176 		return;
1177 	com_argv[arg] = "";
1178 }
1179 
1180 
1181 /*
1182 ================
1183 COM_InitArgv
1184 ================
1185 */
COM_InitArgv(int argc,char ** argv)1186 void COM_InitArgv (int argc, char **argv)
1187 {
1188 	int		i;
1189 
1190 	if (argc > MAX_NUM_ARGVS)
1191 		Com_Error (ERR_FATAL, "argc > MAX_NUM_ARGVS");
1192 	com_argc = argc;
1193 	for (i=0 ; i<argc ; i++)
1194 	{
1195 		if (!argv[i] || strlen(argv[i]) >= MAX_TOKEN_CHARS )
1196 			com_argv[i] = "";
1197 		else
1198 			com_argv[i] = argv[i];
1199 	}
1200 }
1201 
1202 /*
1203 ================
1204 COM_AddParm
1205 
1206 Adds the given string at the end of the current argument list
1207 ================
1208 */
COM_AddParm(char * parm)1209 void COM_AddParm (char *parm)
1210 {
1211 	if (com_argc == MAX_NUM_ARGVS)
1212 		Com_Error (ERR_FATAL, "COM_AddParm: MAX_NUM)ARGS");
1213 	com_argv[com_argc++] = parm;
1214 }
1215 
1216 
1217 
1218 
1219 /// just for debugging
memsearch(byte * start,int count,int search)1220 int	memsearch (byte *start, int count, int search)
1221 {
1222 	int		i;
1223 
1224 	for (i=0 ; i<count ; i++)
1225 		if (start[i] == search)
1226 			return i;
1227 	return -1;
1228 }
1229 
1230 
CopyString(const char * in)1231 char *CopyString (const char *in)
1232 {
1233 	char	*out;
1234 
1235 	out = Z_Malloc (strlen(in)+1);
1236 	strcpy (out, in);
1237 	return out;
1238 }
1239 
1240 
1241 
Info_Print(char * s)1242 void Info_Print (char *s)
1243 {
1244 	char	key[512];
1245 	char	value[512];
1246 	char	*o;
1247 	int		l, i;
1248 
1249 	if (*s == '\\')
1250 		s++;
1251 	while (*s)
1252 	{
1253 		o = key;
1254 		i = 512;
1255 		while (--i && *s && *s != '\\')
1256 			*o++ = *s++;
1257 		if (*s && *s != '\\')
1258 		{
1259 			Com_Printf ("KEY TOO LONG\n");
1260 			return;
1261 		}
1262 
1263 		l = o - key;
1264 		if (l < 20)
1265 		{
1266 			memset (o, ' ', 20-l);
1267 			key[20] = 0;
1268 		}
1269 		else
1270 			*o = 0;
1271 		Com_Printf ("%s", key);
1272 
1273 		if (!*s)
1274 		{
1275 			Com_Printf ("MISSING VALUE\n");
1276 			return;
1277 		}
1278 
1279 		o = value;
1280 		s++;
1281 		i = 512;
1282 		while (--i && *s && *s != '\\')
1283 			*o++ = *s++;
1284 		if (*s && *s != '\\')
1285 		{
1286 			Com_Printf ("VALUE TOO LONG\n");
1287 			return;
1288 		}
1289 		*o = 0;
1290 
1291 		if (*s)
1292 			s++;
1293 		Com_Printf ("%s\n", value);
1294 	}
1295 }
1296 
1297 
1298 /*
1299 ==============================================================================
1300 
1301 						ZONE MEMORY ALLOCATION
1302 
1303 just cleared malloc with counters now...
1304 
1305 ==============================================================================
1306 */
1307 
1308 #define	Z_MAGIC		0x1d1d
1309 
1310 
1311 typedef struct zhead_s
1312 {
1313 	struct zhead_s	*prev, *next;
1314 	short	magic;
1315 	short	tag;			// for group free
1316 	int		size;
1317 } zhead_t;
1318 
1319 zhead_t		z_chain;
1320 int		z_count, z_bytes;
1321 
1322 /*
1323 ========================
1324 Z_Free
1325 ========================
1326 */
Z_Free(void * ptr)1327 void Z_Free (void *ptr)
1328 {
1329 	zhead_t	*z;
1330 
1331 	z = ((zhead_t *)ptr) - 1;
1332 
1333 	if (z->magic != Z_MAGIC)
1334 		Com_Error (ERR_FATAL, "Z_Free: bad magic");
1335 
1336 	z->prev->next = z->next;
1337 	z->next->prev = z->prev;
1338 
1339 	z_count--;
1340 	z_bytes -= z->size;
1341 	free (z);
1342 }
1343 
1344 
1345 /*
1346 ========================
1347 Z_Stats_f
1348 ========================
1349 */
Z_Stats_f(void)1350 void Z_Stats_f (void)
1351 {
1352 	Com_Printf ("%i bytes in %i blocks\n", z_bytes, z_count);
1353 }
1354 
1355 /*
1356 ========================
1357 Z_FreeTags
1358 ========================
1359 */
Z_FreeTags(int tag)1360 void Z_FreeTags (int tag)
1361 {
1362 	zhead_t	*z, *next;
1363 
1364 	for (z=z_chain.next ; z != &z_chain ; z=next)
1365 	{
1366 		next = z->next;
1367 		if (z->tag == tag)
1368 			Z_Free ((void *)(z+1));
1369 	}
1370 }
1371 
1372 /*
1373 ========================
1374 Z_TagMalloc
1375 ========================
1376 */
Z_TagMalloc(int size,int tag)1377 void *Z_TagMalloc (int size, int tag)
1378 {
1379 	zhead_t	*z;
1380 
1381 	size = size + sizeof(zhead_t);
1382 	z = malloc(size);
1383 	if (!z)
1384 		Com_Error (ERR_FATAL, "Z_Malloc: failed on allocation of %i bytes",size);
1385 	memset (z, 0, size);
1386 	z_count++;
1387 	z_bytes += size;
1388 	z->magic = Z_MAGIC;
1389 	z->tag = tag;
1390 	z->size = size;
1391 
1392 	z->next = z_chain.next;
1393 	z->prev = &z_chain;
1394 	z_chain.next->prev = z;
1395 	z_chain.next = z;
1396 
1397 	return (void *)(z+1);
1398 }
1399 
1400 /*
1401 ========================
1402 Z_Malloc
1403 ========================
1404 */
Z_Malloc(int size)1405 void *Z_Malloc (int size)
1406 {
1407 	return Z_TagMalloc (size, 0);
1408 }
1409 
1410 
1411 //============================================================================
1412 
1413 
1414 /*
1415 ====================
1416 COM_BlockSequenceCheckByte
1417 
1418 For proxy protecting
1419 
1420 // THIS IS MASSIVELY BROKEN!  CHALLENGE MAY BE NEGATIVE
1421 // DON'T USE THIS FUNCTION!!!!!
1422 
1423 ====================
1424 */
COM_BlockSequenceCheckByte(byte * base,int length,int sequence,int challenge)1425 byte	COM_BlockSequenceCheckByte (byte *base, int length, int sequence, int challenge)
1426 {
1427 	Sys_Error("COM_BlockSequenceCheckByte called\n");
1428 
1429 #if 0
1430 	int		checksum;
1431 	byte	buf[68];
1432 	byte	*p;
1433 	float temp;
1434 	byte c;
1435 
1436 	temp = bytedirs[(sequence/3) % NUMVERTEXNORMALS][sequence % 3];
1437 	temp = LittleFloat(temp);
1438 	p = ((byte *)&temp);
1439 
1440 	if (length > 60)
1441 		length = 60;
1442 	memcpy (buf, base, length);
1443 
1444 	buf[length] = (sequence & 0xff) ^ p[0];
1445 	buf[length+1] = p[1];
1446 	buf[length+2] = ((sequence>>8) & 0xff) ^ p[2];
1447 	buf[length+3] = p[3];
1448 
1449 	temp = bytedirs[((sequence+challenge)/3) % NUMVERTEXNORMALS][(sequence+challenge) % 3];
1450 	temp = LittleFloat(temp);
1451 	p = ((byte *)&temp);
1452 
1453 	buf[length+4] = (sequence & 0xff) ^ p[3];
1454 	buf[length+5] = (challenge & 0xff) ^ p[2];
1455 	buf[length+6] = ((sequence>>8) & 0xff) ^ p[1];
1456 	buf[length+7] = ((challenge >> 7) & 0xff) ^ p[0];
1457 
1458 	length += 8;
1459 
1460 	checksum = LittleLong(Com_BlockChecksum (buf, length));
1461 
1462 	checksum &= 0xff;
1463 
1464 	return checksum;
1465 #endif
1466 	return 0;
1467 }
1468 
1469 static byte chktbl[1024] = {
1470 0x84, 0x47, 0x51, 0xc1, 0x93, 0x22, 0x21, 0x24, 0x2f, 0x66, 0x60, 0x4d, 0xb0, 0x7c, 0xda,
1471 0x88, 0x54, 0x15, 0x2b, 0xc6, 0x6c, 0x89, 0xc5, 0x9d, 0x48, 0xee, 0xe6, 0x8a, 0xb5, 0xf4,
1472 0xcb, 0xfb, 0xf1, 0x0c, 0x2e, 0xa0, 0xd7, 0xc9, 0x1f, 0xd6, 0x06, 0x9a, 0x09, 0x41, 0x54,
1473 0x67, 0x46, 0xc7, 0x74, 0xe3, 0xc8, 0xb6, 0x5d, 0xa6, 0x36, 0xc4, 0xab, 0x2c, 0x7e, 0x85,
1474 0xa8, 0xa4, 0xa6, 0x4d, 0x96, 0x19, 0x19, 0x9a, 0xcc, 0xd8, 0xac, 0x39, 0x5e, 0x3c, 0xf2,
1475 0xf5, 0x5a, 0x72, 0xe5, 0xa9, 0xd1, 0xb3, 0x23, 0x82, 0x6f, 0x29, 0xcb, 0xd1, 0xcc, 0x71,
1476 0xfb, 0xea, 0x92, 0xeb, 0x1c, 0xca, 0x4c, 0x70, 0xfe, 0x4d, 0xc9, 0x67, 0x43, 0x47, 0x94,
1477 0xb9, 0x47, 0xbc, 0x3f, 0x01, 0xab, 0x7b, 0xa6, 0xe2, 0x76, 0xef, 0x5a, 0x7a, 0x29, 0x0b,
1478 0x51, 0x54, 0x67, 0xd8, 0x1c, 0x14, 0x3e, 0x29, 0xec, 0xe9, 0x2d, 0x48, 0x67, 0xff, 0xed,
1479 0x54, 0x4f, 0x48, 0xc0, 0xaa, 0x61, 0xf7, 0x78, 0x12, 0x03, 0x7a, 0x9e, 0x8b, 0xcf, 0x83,
1480 0x7b, 0xae, 0xca, 0x7b, 0xd9, 0xe9, 0x53, 0x2a, 0xeb, 0xd2, 0xd8, 0xcd, 0xa3, 0x10, 0x25,
1481 0x78, 0x5a, 0xb5, 0x23, 0x06, 0x93, 0xb7, 0x84, 0xd2, 0xbd, 0x96, 0x75, 0xa5, 0x5e, 0xcf,
1482 0x4e, 0xe9, 0x50, 0xa1, 0xe6, 0x9d, 0xb1, 0xe3, 0x85, 0x66, 0x28, 0x4e, 0x43, 0xdc, 0x6e,
1483 0xbb, 0x33, 0x9e, 0xf3, 0x0d, 0x00, 0xc1, 0xcf, 0x67, 0x34, 0x06, 0x7c, 0x71, 0xe3, 0x63,
1484 0xb7, 0xb7, 0xdf, 0x92, 0xc4, 0xc2, 0x25, 0x5c, 0xff, 0xc3, 0x6e, 0xfc, 0xaa, 0x1e, 0x2a,
1485 0x48, 0x11, 0x1c, 0x36, 0x68, 0x78, 0x86, 0x79, 0x30, 0xc3, 0xd6, 0xde, 0xbc, 0x3a, 0x2a,
1486 0x6d, 0x1e, 0x46, 0xdd, 0xe0, 0x80, 0x1e, 0x44, 0x3b, 0x6f, 0xaf, 0x31, 0xda, 0xa2, 0xbd,
1487 0x77, 0x06, 0x56, 0xc0, 0xb7, 0x92, 0x4b, 0x37, 0xc0, 0xfc, 0xc2, 0xd5, 0xfb, 0xa8, 0xda,
1488 0xf5, 0x57, 0xa8, 0x18, 0xc0, 0xdf, 0xe7, 0xaa, 0x2a, 0xe0, 0x7c, 0x6f, 0x77, 0xb1, 0x26,
1489 0xba, 0xf9, 0x2e, 0x1d, 0x16, 0xcb, 0xb8, 0xa2, 0x44, 0xd5, 0x2f, 0x1a, 0x79, 0x74, 0x87,
1490 0x4b, 0x00, 0xc9, 0x4a, 0x3a, 0x65, 0x8f, 0xe6, 0x5d, 0xe5, 0x0a, 0x77, 0xd8, 0x1a, 0x14,
1491 0x41, 0x75, 0xb1, 0xe2, 0x50, 0x2c, 0x93, 0x38, 0x2b, 0x6d, 0xf3, 0xf6, 0xdb, 0x1f, 0xcd,
1492 0xff, 0x14, 0x70, 0xe7, 0x16, 0xe8, 0x3d, 0xf0, 0xe3, 0xbc, 0x5e, 0xb6, 0x3f, 0xcc, 0x81,
1493 0x24, 0x67, 0xf3, 0x97, 0x3b, 0xfe, 0x3a, 0x96, 0x85, 0xdf, 0xe4, 0x6e, 0x3c, 0x85, 0x05,
1494 0x0e, 0xa3, 0x2b, 0x07, 0xc8, 0xbf, 0xe5, 0x13, 0x82, 0x62, 0x08, 0x61, 0x69, 0x4b, 0x47,
1495 0x62, 0x73, 0x44, 0x64, 0x8e, 0xe2, 0x91, 0xa6, 0x9a, 0xb7, 0xe9, 0x04, 0xb6, 0x54, 0x0c,
1496 0xc5, 0xa9, 0x47, 0xa6, 0xc9, 0x08, 0xfe, 0x4e, 0xa6, 0xcc, 0x8a, 0x5b, 0x90, 0x6f, 0x2b,
1497 0x3f, 0xb6, 0x0a, 0x96, 0xc0, 0x78, 0x58, 0x3c, 0x76, 0x6d, 0x94, 0x1a, 0xe4, 0x4e, 0xb8,
1498 0x38, 0xbb, 0xf5, 0xeb, 0x29, 0xd8, 0xb0, 0xf3, 0x15, 0x1e, 0x99, 0x96, 0x3c, 0x5d, 0x63,
1499 0xd5, 0xb1, 0xad, 0x52, 0xb8, 0x55, 0x70, 0x75, 0x3e, 0x1a, 0xd5, 0xda, 0xf6, 0x7a, 0x48,
1500 0x7d, 0x44, 0x41, 0xf9, 0x11, 0xce, 0xd7, 0xca, 0xa5, 0x3d, 0x7a, 0x79, 0x7e, 0x7d, 0x25,
1501 0x1b, 0x77, 0xbc, 0xf7, 0xc7, 0x0f, 0x84, 0x95, 0x10, 0x92, 0x67, 0x15, 0x11, 0x5a, 0x5e,
1502 0x41, 0x66, 0x0f, 0x38, 0x03, 0xb2, 0xf1, 0x5d, 0xf8, 0xab, 0xc0, 0x02, 0x76, 0x84, 0x28,
1503 0xf4, 0x9d, 0x56, 0x46, 0x60, 0x20, 0xdb, 0x68, 0xa7, 0xbb, 0xee, 0xac, 0x15, 0x01, 0x2f,
1504 0x20, 0x09, 0xdb, 0xc0, 0x16, 0xa1, 0x89, 0xf9, 0x94, 0x59, 0x00, 0xc1, 0x76, 0xbf, 0xc1,
1505 0x4d, 0x5d, 0x2d, 0xa9, 0x85, 0x2c, 0xd6, 0xd3, 0x14, 0xcc, 0x02, 0xc3, 0xc2, 0xfa, 0x6b,
1506 0xb7, 0xa6, 0xef, 0xdd, 0x12, 0x26, 0xa4, 0x63, 0xe3, 0x62, 0xbd, 0x56, 0x8a, 0x52, 0x2b,
1507 0xb9, 0xdf, 0x09, 0xbc, 0x0e, 0x97, 0xa9, 0xb0, 0x82, 0x46, 0x08, 0xd5, 0x1a, 0x8e, 0x1b,
1508 0xa7, 0x90, 0x98, 0xb9, 0xbb, 0x3c, 0x17, 0x9a, 0xf2, 0x82, 0xba, 0x64, 0x0a, 0x7f, 0xca,
1509 0x5a, 0x8c, 0x7c, 0xd3, 0x79, 0x09, 0x5b, 0x26, 0xbb, 0xbd, 0x25, 0xdf, 0x3d, 0x6f, 0x9a,
1510 0x8f, 0xee, 0x21, 0x66, 0xb0, 0x8d, 0x84, 0x4c, 0x91, 0x45, 0xd4, 0x77, 0x4f, 0xb3, 0x8c,
1511 0xbc, 0xa8, 0x99, 0xaa, 0x19, 0x53, 0x7c, 0x02, 0x87, 0xbb, 0x0b, 0x7c, 0x1a, 0x2d, 0xdf,
1512 0x48, 0x44, 0x06, 0xd6, 0x7d, 0x0c, 0x2d, 0x35, 0x76, 0xae, 0xc4, 0x5f, 0x71, 0x85, 0x97,
1513 0xc4, 0x3d, 0xef, 0x52, 0xbe, 0x00, 0xe4, 0xcd, 0x49, 0xd1, 0xd1, 0x1c, 0x3c, 0xd0, 0x1c,
1514 0x42, 0xaf, 0xd4, 0xbd, 0x58, 0x34, 0x07, 0x32, 0xee, 0xb9, 0xb5, 0xea, 0xff, 0xd7, 0x8c,
1515 0x0d, 0x2e, 0x2f, 0xaf, 0x87, 0xbb, 0xe6, 0x52, 0x71, 0x22, 0xf5, 0x25, 0x17, 0xa1, 0x82,
1516 0x04, 0xc2, 0x4a, 0xbd, 0x57, 0xc6, 0xab, 0xc8, 0x35, 0x0c, 0x3c, 0xd9, 0xc2, 0x43, 0xdb,
1517 0x27, 0x92, 0xcf, 0xb8, 0x25, 0x60, 0xfa, 0x21, 0x3b, 0x04, 0x52, 0xc8, 0x96, 0xba, 0x74,
1518 0xe3, 0x67, 0x3e, 0x8e, 0x8d, 0x61, 0x90, 0x92, 0x59, 0xb6, 0x1a, 0x1c, 0x5e, 0x21, 0xc1,
1519 0x65, 0xe5, 0xa6, 0x34, 0x05, 0x6f, 0xc5, 0x60, 0xb1, 0x83, 0xc1, 0xd5, 0xd5, 0xed, 0xd9,
1520 0xc7, 0x11, 0x7b, 0x49, 0x7a, 0xf9, 0xf9, 0x84, 0x47, 0x9b, 0xe2, 0xa5, 0x82, 0xe0, 0xc2,
1521 0x88, 0xd0, 0xb2, 0x58, 0x88, 0x7f, 0x45, 0x09, 0x67, 0x74, 0x61, 0xbf, 0xe6, 0x40, 0xe2,
1522 0x9d, 0xc2, 0x47, 0x05, 0x89, 0xed, 0xcb, 0xbb, 0xb7, 0x27, 0xe7, 0xdc, 0x7a, 0xfd, 0xbf,
1523 0xa8, 0xd0, 0xaa, 0x10, 0x39, 0x3c, 0x20, 0xf0, 0xd3, 0x6e, 0xb1, 0x72, 0xf8, 0xe6, 0x0f,
1524 0xef, 0x37, 0xe5, 0x09, 0x33, 0x5a, 0x83, 0x43, 0x80, 0x4f, 0x65, 0x2f, 0x7c, 0x8c, 0x6a,
1525 0xa0, 0x82, 0x0c, 0xd4, 0xd4, 0xfa, 0x81, 0x60, 0x3d, 0xdf, 0x06, 0xf1, 0x5f, 0x08, 0x0d,
1526 0x6d, 0x43, 0xf2, 0xe3, 0x11, 0x7d, 0x80, 0x32, 0xc5, 0xfb, 0xc5, 0xd9, 0x27, 0xec, 0xc6,
1527 0x4e, 0x65, 0x27, 0x76, 0x87, 0xa6, 0xee, 0xee, 0xd7, 0x8b, 0xd1, 0xa0, 0x5c, 0xb0, 0x42,
1528 0x13, 0x0e, 0x95, 0x4a, 0xf2, 0x06, 0xc6, 0x43, 0x33, 0xf4, 0xc7, 0xf8, 0xe7, 0x1f, 0xdd,
1529 0xe4, 0x46, 0x4a, 0x70, 0x39, 0x6c, 0xd0, 0xed, 0xca, 0xbe, 0x60, 0x3b, 0xd1, 0x7b, 0x57,
1530 0x48, 0xe5, 0x3a, 0x79, 0xc1, 0x69, 0x33, 0x53, 0x1b, 0x80, 0xb8, 0x91, 0x7d, 0xb4, 0xf6,
1531 0x17, 0x1a, 0x1d, 0x5a, 0x32, 0xd6, 0xcc, 0x71, 0x29, 0x3f, 0x28, 0xbb, 0xf3, 0x5e, 0x71,
1532 0xb8, 0x43, 0xaf, 0xf8, 0xb9, 0x64, 0xef, 0xc4, 0xa5, 0x6c, 0x08, 0x53, 0xc7, 0x00, 0x10,
1533 0x39, 0x4f, 0xdd, 0xe4, 0xb6, 0x19, 0x27, 0xfb, 0xb8, 0xf5, 0x32, 0x73, 0xe5, 0xcb, 0x32
1534 };
1535 
1536 /*
1537 ====================
1538 COM_BlockSequenceCRCByte
1539 
1540 For proxy protecting
1541 ====================
1542 */
COM_BlockSequenceCRCByte(byte * base,int length,int sequence)1543 byte	COM_BlockSequenceCRCByte (byte *base, int length, int sequence)
1544 {
1545 	int		n;
1546 	byte	*p;
1547 	int		x;
1548 	byte chkb[60 + 4];
1549 	unsigned short crc;
1550 
1551 
1552 	if (sequence < 0)
1553 		Sys_Error("sequence < 0, this shouldn't happen\n");
1554 
1555 	p = chktbl + (sequence % (sizeof(chktbl) - 4));
1556 
1557 	if (length > 60)
1558 		length = 60;
1559 	memcpy (chkb, base, length);
1560 
1561 	chkb[length] = p[0];
1562 	chkb[length+1] = p[1];
1563 	chkb[length+2] = p[2];
1564 	chkb[length+3] = p[3];
1565 
1566 	length += 4;
1567 
1568 	crc = CRC_Block(chkb, length);
1569 
1570 	for (x=0, n=0; n<length; n++)
1571 		x += chkb[n];
1572 
1573 	crc = (crc ^ x) & 0xff;
1574 
1575 	return crc;
1576 }
1577 
1578 //========================================================
1579 
frand(void)1580 float	frand(void)
1581 {
1582 	return (rand()&32767)* (1.0/32767);
1583 }
1584 
crand(void)1585 float	crand(void)
1586 {
1587 	return (rand()&32767)* (2.0/32767) - 1;
1588 }
1589 
1590 void Key_Init (void);
1591 void SCR_EndLoadingPlaque (void);
1592 
1593 /*
1594 =============
1595 Com_Error_f
1596 
1597 Just throw a fatal error to
1598 test error shutdown procedures
1599 =============
1600 */
Com_Error_f(void)1601 void Com_Error_f (void)
1602 {
1603 	Com_Error (ERR_FATAL, "%s", Cmd_Argv(1));
1604 }
1605 
1606 
1607 /*
1608 =================
1609 Qcommon_Init
1610 =================
1611 */
Qcommon_Init(int argc,char ** argv)1612 void Qcommon_Init (int argc, char **argv)
1613 {
1614 	char	*s;
1615 
1616 	if (setjmp (abortframe) )
1617 		Sys_Error ("Error during initialization");
1618 
1619 	z_chain.next = z_chain.prev = &z_chain;
1620 
1621 	// prepare enough of the subsystems to handle
1622 	// cvar and command buffer management
1623 	COM_InitArgv (argc, argv);
1624 
1625 	Swap_Init ();
1626 	Cbuf_Init ();
1627 
1628 	Cmd_Init ();
1629 	Cvar_Init ();
1630 
1631 	Key_Init ();
1632 
1633 	// we need to add the early commands twice, because
1634 	// a basedir needs to be set before execing
1635 	// config files, but we want other parms to override
1636 	// the settings of the config files
1637 	Cbuf_AddEarlyCommands (false);
1638 	Cbuf_Execute ();
1639 
1640 	FS_InitFilesystem ();
1641 
1642 	Cbuf_AddText ("exec default.cfg\n");
1643 	Cbuf_AddText ("exec config.cfg\n");
1644 	Cbuf_AddText ("exec profile.cfg\n");
1645 
1646 	Cbuf_AddEarlyCommands (true);
1647 	Cbuf_Execute ();
1648 
1649 	//
1650 	// init commands and vars
1651 	//
1652     Cmd_AddCommand ("z_stats", Z_Stats_f);
1653     Cmd_AddCommand ("error", Com_Error_f);
1654 
1655 	host_speeds = Cvar_Get ("host_speeds", "0", 0);
1656 	log_stats = Cvar_Get ("log_stats", "0", 0);
1657 	developer = Cvar_Get ("developer", "0", 0);
1658 	timescale = Cvar_Get ("timescale", "1", 0);
1659 	fixedtime = Cvar_Get ("fixedtime", "0", 0);
1660 	// 2010-08 logfile default to "1" to prevent unbounded growth (also no flush on write)
1661 	// rationale: expert user can figure out when "2" or "3" are appropriate
1662 	logfile_active = Cvar_Get ("logfile", "1", CVAR_ARCHIVE);
1663 	logfile_name = Cvar_Get ("logname", "qconsole.log", CVAR_ARCHIVE);
1664 	showtrace = Cvar_Get ("showtrace", "0", 0);
1665 #ifdef DEDICATED_ONLY
1666 	dedicated = Cvar_Get ("dedicated", "1", CVAR_NOSET);
1667 #else
1668 	dedicated = Cvar_Get ("dedicated", "0", CVAR_LATCH);
1669 #endif
1670 
1671 	s = va("%s %s %s %s", VERSION, CPUSTRING, __DATE__, BUILDSTRING);
1672 	Cvar_Get ("version", s, CVAR_SERVERINFO|CVAR_NOSET);
1673 
1674 	if (dedicated->value)
1675 		Cmd_AddCommand ("quit", Com_Quit);
1676 
1677 	Sys_Init ();
1678 
1679 	NET_Init ();
1680 	Netchan_Init ();
1681 
1682 	SV_Init ();
1683 
1684 	dedicated->modified = false;
1685 
1686 	if(!dedicated->value)
1687 		CL_Init ();
1688 
1689 	// add + commands from command line
1690 	if (!Cbuf_AddLateCommands ())
1691 	{	// if the user didn't give any commands, run default action
1692 		if (!dedicated->value)
1693 			Cbuf_AddText("menu_main\n");
1694 		else
1695 			Cbuf_AddText ("dedicated_start\n");
1696 		Cbuf_Execute ();
1697 	}
1698 	else
1699 	{	// the user asked for something explicit
1700 		// so drop the loading plaque
1701 		SCR_EndLoadingPlaque ();
1702 	}
1703 
1704 	//drop console, to get it into menu
1705 	SCR_EndLoadingPlaque ();
1706 	// clear any lines of console text
1707 	Cbuf_AddText ("clear\n");
1708 #ifndef DEDICATED_ONLY
1709 	//play music
1710 	if (!dedicated->value)
1711 		S_StartMenuMusic();
1712 #endif
1713 	Com_Printf ("======== Alien Arena Initialized ========\n\n");
1714 }
1715 
1716 /*
1717 =================
1718 Qcommon_Frame
1719 =================
1720 */
Qcommon_Frame(int msec)1721 void Qcommon_Frame (int msec)
1722 {
1723 
1724 	int		time_before=0, time_between=0, time_after=0;
1725 #if defined UNIX_VARIANT
1726 	char	*s;
1727 #endif
1728 
1729 	if (setjmp (abortframe) )
1730 		return;			// an ERR_DROP was thrown
1731 
1732 	if ( log_stats->modified )
1733 	{
1734 		log_stats->modified = false;
1735 		if ( log_stats->value )
1736 		{
1737 			if ( log_stats_file )
1738 			{
1739 				fclose( log_stats_file );
1740 				log_stats_file = 0;
1741 			}
1742 			log_stats_file = fopen( "stats.log", "w" );
1743 			if ( log_stats_file )
1744 				fprintf( log_stats_file, "entities,dlights,parts,frame time\n" );
1745 		}
1746 		else
1747 		{
1748 			if ( log_stats_file )
1749 			{
1750 				fclose( log_stats_file );
1751 				log_stats_file = 0;
1752 			}
1753 		}
1754 	}
1755 
1756 	if (fixedtime->value)
1757 		msec = fixedtime->value;
1758 	else if (timescale->value)
1759 	{
1760 		msec *= timescale->value;
1761 		if (msec < 1)
1762 			msec = 1;
1763 	}
1764 
1765 	if (showtrace->value)
1766 	{
1767 		extern	int c_traces, c_brush_traces;
1768 		extern	int	c_pointcontents;
1769 
1770 		if ( c_traces > 0 || c_brush_traces > 0 || c_pointcontents > 0 )
1771 		{
1772 			Com_Printf ("%4i traces %4i brush %4i points\n", c_traces, c_brush_traces, c_pointcontents);
1773 			c_traces = 0;
1774 			c_brush_traces = 0;
1775 			c_pointcontents = 0;
1776 		}
1777 	}
1778 
1779 #if defined UNIX_VARIANT
1780 	do
1781 	{
1782 		s = Sys_ConsoleInput ();
1783 		if (s)
1784 			Cbuf_AddText (va("%s\n",s));
1785 	} while (s);
1786 #else
1787 
1788 	// Get input from dedicated server console
1789 	if (dedicated->integer){
1790 		char	*cmd;
1791 
1792 		cmd = Sys_GetCommand();
1793 		if (cmd){
1794 			Cbuf_AddText(cmd);
1795 			Cbuf_AddText("\n");
1796 		}
1797 	}
1798 #endif
1799 
1800 	Cbuf_Execute ();
1801 
1802 	if (host_speeds->value)
1803 		time_before = Sys_Milliseconds ();
1804 
1805 	SV_Frame (msec);
1806 
1807 #if defined WIN32_VARIANT
1808 	// not good for Linux when run from menu or icon without a terminal
1809 	if(dedicated->modified) {
1810 		dedicated->modified = false;
1811 		if ( dedicated->value ) {
1812 			//shutdown the client
1813 			CL_Shutdown();
1814 		}
1815 	}
1816 #endif
1817 
1818 	if (host_speeds->value)
1819 		time_between = Sys_Milliseconds ();
1820 
1821 	CL_Frame (msec);
1822 
1823 	if (host_speeds->value)
1824 		time_after = Sys_Milliseconds ();
1825 
1826 
1827 	if (host_speeds->value)
1828 	{
1829 		int			all, sv, gm, cl, rf;
1830 
1831 		all = time_after - time_before;
1832 		sv = time_between - time_before;
1833 		cl = time_after - time_between;
1834 		gm = time_after_game - time_before_game;
1835 		rf = time_after_ref - time_before_ref;
1836 		sv -= gm;
1837 		cl -= rf;
1838 		Com_Printf ("all:%3i sv:%3i gm:%3i cl:%3i rf:%3i\n",
1839 			all, sv, gm, cl, rf);
1840 	}
1841 }
1842 
1843 /*
1844 =================
1845 Qcommon_Shutdown
1846 =================
1847 */
Qcommon_Shutdown(void)1848 void Qcommon_Shutdown (void)
1849 {
1850 }
1851 
1852 
1853 
1854 
1855 
1856 
1857 
1858 
1859 
1860 #ifdef HAVE_ZLIB
1861 //This compression code was originally from the Lua branch. More of it will
1862 //eventually be merged when packet compression is added, but currently we
1863 //are only decompressing zlib data and only need it on the client side.
1864 
1865 //Following function ripped off from R1Q2, then modified to use sizebufs
ZLibDecompress(sizebuf_t * in,sizebuf_t * out,int wbits)1866 int ZLibDecompress (sizebuf_t *in, sizebuf_t *out, int wbits) {
1867 	z_stream zs;
1868 	char *err_summary;
1869 	int result;
1870 
1871 	memset (&zs, 0, sizeof(zs));
1872 
1873 
1874 	zs.next_in = in->data + in->readcount;
1875 	zs.avail_in = 0;
1876 
1877 	zs.next_out = out->data + out->cursize;
1878 	zs.avail_out = out->maxsize - out->cursize;
1879 
1880 	result = inflateInit2(&zs, wbits);
1881 	if (result != Z_OK)
1882 	{
1883 		switch (result)
1884 		{
1885 			default: err_summary = "unknown"; break;
1886 			case Z_MEM_ERROR: err_summary = "system memory exhausted"; break;
1887 			case Z_STREAM_ERROR: err_summary = "invalid z_stream"; break;
1888 			case Z_VERSION_ERROR: err_summary = "incompatible zlib version"; break;
1889 		}
1890 		Com_Printf ("ZLib data error! Error %d on inflateInit.\nMessage: %s\n", result, zs.msg);
1891 		return 0;
1892 	}
1893 
1894 	zs.avail_in = in->cursize;
1895 
1896 	result = inflate(&zs, Z_FINISH);
1897 	if (result != Z_STREAM_END)
1898 	{
1899 	    switch (result)
1900 		{
1901 			default: err_summary = "unknown"; break;
1902 			case Z_STREAM_END: err_summary = "premature end of stream"; break;
1903 			case Z_NEED_DICT: err_summary = "missing preset dictionary"; break;
1904 			case Z_STREAM_ERROR: err_summary = "invalid z_stream"; break;
1905 			case Z_DATA_ERROR: err_summary = "corrupted data"; break;
1906 			case Z_BUF_ERROR: err_summary = "too much compressed data"; break;
1907 			case Z_OK: err_summary = "shouldn't happen with Z_FINISH"; break;
1908 		}
1909 		Com_Printf ("ZLib data error! Error %d (%s) on inflate.\nMessage: %s\n", result, err_summary, zs.msg);
1910 		return 0;
1911 	}
1912 
1913 	result = inflateEnd(&zs);
1914 	if (result != Z_OK)
1915 	{
1916 		switch (result)
1917 		{
1918 			default: err_summary = "unknown"; break;
1919 			case Z_STREAM_ERROR: err_summary = "invalid z_stream"; break;
1920 			case Z_DATA_ERROR: err_summary = "prematurely freed z_stream"; break;
1921 		}
1922 		Com_Printf ("ZLib data error! Error %d (%s) on inflateEnd.\nMessage: %s\n", result, err_summary, zs.msg);
1923 		return 0;
1924 	}
1925 
1926 	return zs.total_out;
1927 }
1928 #endif //HAVE_ZLIB
1929 
qdecompress(sizebuf_t * src,sizebuf_t * dst,int type)1930 void qdecompress (sizebuf_t *src, sizebuf_t *dst, int type){
1931 	int newsize = 0;
1932 
1933 	switch (type) {
1934 #ifdef HAVE_ZLIB
1935 		case compression_zlib_raw:
1936 			//raw DEFLATE data, no header/trailer
1937 			newsize = ZLibDecompress (src, dst, -15);
1938 			break;
1939 #endif
1940 #if 0
1941         case compression_lzo:
1942             newsize = LzoDecompress (src, dst);
1943             break;
1944 #endif
1945 #ifdef HAVE_ZLIB
1946 		case compression_zlib_header:
1947 			//automatically detect gzip/zlib header/trailer
1948 			newsize = ZLibDecompress (src, dst, 47);
1949 			break;
1950 #endif
1951 	}
1952 
1953 	if ( newsize == 0)
1954 		dst->cursize = 0;
1955 	else
1956 		dst->cursize += newsize;
1957 
1958 }
1959 
1960 
1961 
1962