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