1 #ifndef WIN32
2 #include "config.h"
3 #endif
4 
5 #include <stdio.h>
6 #include <signal.h>
7 #include <math.h>
8 
9 #ifdef HAVE_FLOAT_H
10 	#include <float.h>
11 #endif
12 
13 #ifdef HAVE_SIGINFO_H
14 	#include <siginfo.h>
15 #endif
16 
17 #ifdef HAVE_SYS_SELECT_H
18 #include <sys/select.h>
19 #endif
20 
21 #include <ctype.h>
22 
23 #if (!defined(WIN32))
24 	#ifdef TIME_WITH_SYS_TIME
25 		#include <sys/time.h>
26 		#include <time.h>
27 	#else
28 		#ifdef TM_IN_SYS_TIME
29 			#include <sys/time.h>
30 		#else
31 			#include <time.h>
32 		#endif
33 	#endif
34 #else
35 	#include <time.h>
36 #endif
37 
38 #include <errno.h>
39 #include <stdlib.h>
40 #ifndef WIN32
41 	#include <sys/types.h>
42 	#include <sys/socket.h>
43 	#include <netinet/in.h>
44 	#include <netdb.h>
45 	#ifndef __USE_GNU
46 		#define __USE_GNU
47 	#endif
48 #else
49 	#include <winsock.h>
50 #endif
51 
52 #include <string.h>
53 
54 #include "sprite.h"
55 #include "data.h"
56 #include "cfg.h"
57 #include "net.h"
58 #include "hash.h"
59 #include "time.h"
60 #include "math.h"
61 #include "getopt.h"
62 #include "error.h"
63 
64 
65 #ifdef WIN32
66 	int consoleApp=1;
67 #endif
68 
69 #define N_NAMES 18
70 #define CAN_SEE_X 60
71 #define CAN_SEE_Y 10
72 
73 /* some empty functions and variables */
c_shutdown(void)74 void c_shutdown(void){}
init_blit(void)75 void init_blit(void){}
shutdown_blit(void)76 void shutdown_blit(void){}
77 int SCREEN_X=1,SCREEN_Y=1;
78 unsigned char *screen,*screen_a;
79 #ifdef TRI_D
80 unsigned char *screen2,*screen2_a;
81 #endif
82 
83 
84 int in_signal_handler=0;
85 int level_sprites_start;
86 int level_number=-1;
87 
88 /* my health, armor, frags, deaths, ammo, ... and ID */
89 unsigned char health,armor;
90 unsigned int frags,deaths;
91 unsigned short ammo[ARMS];
92 unsigned char current_weapon;
93 unsigned char weapons;
94 int my_id;
95 
96 /* connection with server */
97 int connected=0;
98 
99 int console_ok=1;
100 
101 /* networking */
102 int fd;  /* socket */
103 struct sockaddr_in server;  /* server address */
104 
105 /* objects */
106 struct object_list objects;
107 struct object_list *last_obj;
108 struct it* hero;
109 
110 unsigned long_long game_start_offset; /* time difference between game start on this machine and on server */
111 
112 
113 struct  /* keyboard status */
114 {
115 	unsigned char right,left,jump,creep,speed,fire,weapon,down_ladder;
116 }keyboard_status;
117 
118 
119 unsigned char *names[N_NAMES]={
120 	"Terminator",
121 	"Jack The Ripper",
122 	"Rambo",
123 	"Exhumator",
124 	"Assassin",
125 	"Arnold",
126 	"Necromancer",
127 	"Predator",
128 	"Rocky",
129 	"Harvester",
130 	"Lamer",
131 	"Killme",
132 	"Looser",
133 	"Krueger",
134 	"I'll kill you",
135 	"Zombieman",
136 	"Hellraiser",
137 	"Eraser"
138 };
139 
140 int direction=0;  /* 0=stop, 1=left, 2=right */
141 int const1,const2,const3,const4;
142 unsigned short port=DEFAULT_PORT;
143 unsigned char *host;
144 int priority;
145 /* 	0=nothing
146  *	1=kill player
147  *	2=find rifle
148  *	3=find shotgun
149  *	4=find UZI
150  *	5=find grenades
151  *	6=find gun ammo
152  *	7=find shotgun ammo
153  *	8=find rifle ammo
154  *	9=find uzi ammo
155  *	10=find medikit
156  */
157 
158 /*-----------------------------------------------------------------------*/
159 
160 
161 #define  can_see(a,b)	(a<add_int(hero->x,CAN_SEE_X)&&a>sub_int(hero->x,CAN_SEE_X)&&b>sub_int(hero->y,CAN_SEE_Y)&&b<add_int(hero->y,CAN_SEE_Y))
162 
163 
odds(int p)164 int odds(int p)
165 {
166 	return (random()%1000)<p;
167 }
168 
169 
170 /* free all before exit */
clear_memory(void)171 void clear_memory(void)
172 {
173 	struct object_list *o;
174 
175 	for (o=&objects;o->next;)
176 		delete_obj(o->next->member.id);
177 	free_area();
178 	shutdown_sprites();
179 	free_sprites(0);
180 }
181 
182 
183 /* shut down the client */
shut_down(int a)184 void shut_down(int a)
185 {
186 	if (a)
187 	{
188 		clear_memory();
189 		check_memory_leaks();
190 		EXIT(0);
191 	}
192 }
193 
194 
195 /* find address of server and fill the server address structure */
find_server(char * name,unsigned short port)196 char * find_server(char *name,unsigned short port)
197 {
198 	struct hostent *h;
199 
200 	h=gethostbyname(name);
201 	if (!h)return "Error: Can't resolve server address.\n";
202 
203 	server.sin_family=AF_INET;
204 	server.sin_port=htons(port);
205 	server.sin_addr=*((struct in_addr*)(h->h_addr_list[0]));
206 	return 0;
207 }
208 
209 
210 /* initialize socket */
init_socket(void)211 char * init_socket(void)
212 {
213 	fd=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
214 	if(fd<0)return "Can't get socket.\n";
215 	return 0;
216 }
217 
218 
219 #define MAX_COUNT 32
220 
221 /* send quit request to server */
send_quit(void)222 void send_quit(void)
223 {
224 	unsigned char p;
225 	fd_set rfds;
226 	struct timeval tv;
227 	int a=sizeof(server);
228 	int count=0;
229 
230 	tv.tv_sec=2;
231 	tv.tv_usec=0;
232 	FD_ZERO(&rfds);
233 	FD_SET(fd,&rfds);
234 
235 send_again:
236 	p=P_QUIT_REQUEST;
237 	count ++;
238 	send_packet(&p,1,(struct sockaddr *)(&server),my_id,0);
239 	if (!select(fd+1,&rfds,0,0,&tv)&&count<=MAX_COUNT)goto send_again;
240 	recv_packet(&p,1,(struct sockaddr*)(&server),&a,1,my_id,0);
241 	if (p!=P_PLAYER_DELETED&&count<=MAX_COUNT)goto send_again;
242 }
243 
244 #undef MAX_COUNT
245 
246 
247 /* initiate connection with server */
contact_server(int color,unsigned char * name)248 char * contact_server(int color,unsigned char *name)
249 {
250 	static unsigned char packet[256];
251 	int l=strlen(name)+1;
252 	int a,r;
253 	int min,maj;
254 
255         fd_set fds;
256         struct timeval tv;
257         tv.tv_sec=4;
258         tv.tv_usec=0;
259         FD_ZERO(&fds);
260         FD_SET(fd,&fds);
261 
262 	packet[0]=P_NEW_PLAYER;
263 	packet[1]=0;
264 	packet[2]=VERSION_MAJOR;
265 	packet[3]=VERSION_MINOR;
266 	packet[4]=color;
267 	memcpy(packet+5,name,l);
268 
269 	send_packet(packet,l+5,(struct sockaddr*)(&server),my_id,0);
270 
271 
272         if (!select(fd+1,&fds,NULL,NULL,&tv))return "No reply within 4 seconds.\n";
273 
274 	if ((r=recv_packet(packet,256,0,0,1,0,0))<0)
275 	{
276 		if (errno==EINTR)return "Server hung up.\n";
277 		else return "Connection error.\n";
278 	}
279 
280 	switch(*packet)
281 	{
282 		case P_PLAYER_REFUSED:
283 		switch(packet[1])
284 		{
285 			case E_INCOMPATIBLE_VERSION:
286 			return "Incompatible client version. Connection refused.\n";
287 
288 			default:
289 			return "Connection refused.\n";
290 		}
291 
292 		case P_PLAYER_ACCEPTED:
293 		my_id=get_int(packet+33);
294 		if (r<39){send_quit();return "Incompatible server version. Givin' up.\n";}
295 		maj=packet[37];
296 		min=packet[38];
297 		if (maj!=VERSION_MAJOR||min<MIN_SERVER_VERSION_MINOR)
298 		{send_quit();return "Incompatible server version. Givin' up.\n";}
299 		game_start_offset=get_time();
300 		game_start_offset-=get_long_long(packet+25);
301 		health=100;
302 		armor=0;
303 		for(a=0;a<ARMS;a++)
304 			ammo[a]=0;
305 		ammo[0]=weapon[0].basic_ammo;
306 		current_weapon=0;
307 		weapons=17;  /* gun and grenades */
308 		hero=new_obj(
309 			get_int(packet+1),   /* ID */
310 			T_PLAYER,   /* type */
311 			0,  /* time to live */
312 			get_int16(packet+5),   /* sprite */
313 			0,        /* position */
314 			get_int16(packet+23),        /* status */
315 			get_float(packet+7),     /* X */
316 			get_float(packet+11),    /* Y */
317 			get_float(packet+15),    /* XSPEED */
318 			get_float(packet+19),    /* YSPEED */
319 			0
320 			);
321 		break;
322 
323 		default:
324 		return "Connection error.\n";
325 	}
326 	return 0;
327 }
328 
329 
330 /* I want to be born again */
send_reenter_game(void)331 void send_reenter_game(void)
332 {
333 	unsigned char packet;
334 	packet=P_REENTER_GAME;
335 	send_packet(&packet,1,(struct sockaddr*)(&server),my_id,0);
336 }
337 
338 
339 /* send chat message */
send_message(char * msg)340 void send_message(char *msg)
341 {
342 	static unsigned char packet[MAX_MESSAGE_LENGTH+2];
343 	int a;
344 
345 	a=strlen(msg)+1;
346 	packet[0]=P_MESSAGE;
347 	memcpy(packet+1,msg,a);
348 	send_packet(packet,a+1,(struct sockaddr *)(&server),my_id,0);
349 }
350 
351 
352 /* send end of game to server */
send_keyboard(void)353 void send_keyboard(void)
354 {
355 	unsigned char packet[3];
356 	packet[0]=P_KEYBOARD;
357 	packet[1]=	keyboard_status.right|
358 			(keyboard_status.left<<1)|
359 			(keyboard_status.jump<<2)|
360 			(keyboard_status.creep<<3)|
361 			(keyboard_status.speed<<4)|
362 			(keyboard_status.fire<<5)|
363 			(keyboard_status.down_ladder<<6);
364 	packet[2]=	keyboard_status.weapon;
365 	send_packet(packet,3,(struct sockaddr*)(&server),my_id,0);
366 }
367 
368 
reset_keyboard(void)369 void reset_keyboard(void)
370 {
371 	keyboard_status.left=0;
372 	keyboard_status.right=0;
373 	keyboard_status.speed=1;
374 	keyboard_status.jump=0;
375 	keyboard_status.creep=0;
376 	keyboard_status.fire=0;
377 	keyboard_status.weapon=0;
378 	keyboard_status.down_ladder=0;
379 }
380 
381 
test_object(struct it * obj)382 void test_object(struct it *obj)
383 {
384 	if (obj==hero)return;
385 	if (!can_see(obj->x,obj->y))return;
386 	switch(obj->type)
387 	{
388 		case T_PLAYER:
389 		if (obj->status&64)break;
390 		if (priority>1)break;
391 		priority=1;
392 		keyboard_status.fire=1;
393 		if (obj->x>hero->x)direction=2;
394 		else direction=1;
395 		if (my_abs(obj->x-hero->x)<int2double(30))direction=0;
396 		break;
397 
398 		case T_BULLET:
399 		case T_SHRAPNEL:
400 		if ((my_sgn(hero->x-obj->x)==my_sgn(obj->xspeed)||my_abs(hero->x-obj->x)<int2double(20))&&obj->y>=hero->y&&obj->y<hero->y+int2double(PLAYER_HEIGHT))
401 			keyboard_status.creep=1;
402 		break;
403 
404 		case T_RIFLE:
405 		if (priority>2)break;
406 		if ((weapons&(1<<WEAPON_RIFLE))&&ammo[WEAPON_RIFLE])break;
407 		priority=2;
408 		if (obj->x>hero->x)direction=2;
409 		else direction=1;
410 		break;
411 
412 		case T_SHOTGUN:
413 		if (priority>3)break;
414 		if ((weapons&(1<<WEAPON_SHOTGUN))&&ammo[WEAPON_SHOTGUN])break;
415 		priority=3;
416 		if (obj->x>hero->x)direction=2;
417 		else direction=1;
418 		break;
419 
420 		case T_UZI:
421 		if (priority>4)break;
422 		if ((weapons&(1<<WEAPON_UZI))&&ammo[WEAPON_UZI])break;
423 		priority=4;
424 		if (obj->x>hero->x)direction=2;
425 		else direction=1;
426 		break;
427 
428 		case T_AMMO_GRENADE:
429 		if (priority>5)break;
430 		if (!(weapons&(1<<WEAPON_GRENADE))||ammo[WEAPON_GRENADE])break;
431 		priority=5;
432 		if (obj->x>hero->x)direction=2;
433 		else direction=1;
434 		break;
435 
436 		case T_AMMO_GUN:
437 		if (priority>6)break;
438 		if (!(weapons&(1<<WEAPON_GUN))||ammo[WEAPON_GUN])break;
439 		priority=6;
440 		if (obj->x>hero->x)direction=2;
441 		else direction=1;
442 		break;
443 
444 		case T_AMMO_SHOTGUN:
445 		if (priority>7)break;
446 		if (!(weapons&(1<<WEAPON_SHOTGUN))||ammo[WEAPON_SHOTGUN])break;
447 		priority=7;
448 		if (obj->x>hero->x)direction=2;
449 		else direction=1;
450 		break;
451 
452 		case T_AMMO_RIFLE:
453 		if (priority>8)break;
454 		if (!(weapons&(1<<WEAPON_RIFLE))||ammo[WEAPON_RIFLE])break;
455 		priority=8;
456 		if (obj->x>hero->x)direction=2;
457 		else direction=1;
458 		break;
459 
460 		case T_AMMO_UZI:
461 		if (priority>9)break;
462 		if (!(weapons&(1<<WEAPON_UZI))||ammo[WEAPON_UZI])break;
463 		priority=9;
464 		if (obj->x>hero->x)direction=2;
465 		else direction=1;
466 		break;
467 
468 		case T_MEDIKIT:
469 		if (priority>10)break;
470 		if (health>70)break;
471 		priority=10;
472 		if (obj->x>hero->x)direction=2;
473 		else direction=1;
474 		break;
475 
476 	}
477 }
478 
479 
480 /* destroys all objects except hero (before level change) */
clean_memory(void)481 void clean_memory(void)
482 {
483 	struct object_list *o;
484 
485 	/* delete all objects except hero */
486 	for (o=&objects;o->next;)
487 		if ((hero->id)!=(o->next->member.id))delete_obj(o->next->member.id);
488 		else o=o->next;
489 }
490 
491 
change_level(void)492 void change_level(void)
493 {
494 	unsigned char *LEVEL;
495 	unsigned char txt[256];
496 
497 	clean_memory();
498 	free_sprites(level_sprites_start);
499 	reinit_area();
500 
501 	LEVEL=load_level(level_number);
502 	snprintf(txt,256,"Loading level \"%s\".\n",LEVEL);
503 	ERROR(txt);
504 	snprintf(txt,256,"%s%s%s",DATA_PATH,LEVEL,LEVEL_SPRITES_SUFFIX);
505 	load_sprites(txt);
506 	snprintf(txt,256,"%s%s%s",DATA_PATH,LEVEL,STATIC_DATA_SUFFIX);
507 	load_data(txt);
508 	mem_free(LEVEL);
509 }
510 
511 
512 /* recompute object positions */
update_game(void)513 void update_game(void)
514 {
515 	struct object_list *p;
516 	int w,h;
517 	unsigned char stop_x,stop_y,sy;
518 	unsigned long_long t;
519 	my_double x,y,x1,y1,DELTA_TIME;
520 
521 	for(p=&objects;p->next;p=p->next)
522 	{
523 		if (p->next->member.type==T_NOTHING)continue;
524 		if ((p->next->member.status)&1024)continue;   /* dead player */
525 		/* decrement time to live */
526 		if (p->next->member.ttl>0)
527 		{
528 			p->next->member.ttl--;
529 			if (!p->next->member.ttl)
530 			{
531 				if ((p->next->member.type)==T_PLAYER)p->next->member.status&=~16;
532 				else
533 				{
534 					if (p->next->member.type!=T_GRENADE){  /* client's waiting for P_EXPLODE_GRENADE and doesn't delete the grenade yet */
535 		                        p=p->prev;
536 					delete_obj(p->next->next->member.id);
537 					continue;}
538 				}
539 			}
540 		}
541 		test_object(&(p->next->member));
542 		/* maintain only objects that you are allowed to maintain */
543 		if (!(obj_attr[p->next->member.type].maintainer&1))continue;
544 
545 
546 		/* if not falling slow down x motion */
547 		if (!(p->next->member.status&8))p->next->member.xspeed=mul(p->next->member.xspeed,obj_attr[p->next->member.type].slow_down_x);
548 
549 		/* fall */
550 		if (obj_attr[p->next->member.type].fall)
551 		{
552 			p->next->member.status|=8;
553 			p->next->member.yspeed+=FALL_ACCEL;
554 			/* but not too fast */
555 			if (p->next->member.yspeed>MAX_Y_SPEED)p->next->member.yspeed=MAX_Y_SPEED;
556 		}
557 
558                 get_dimensions(p->next->member.type,p->next->member.status,sprites[p->next->member.sprite].positions,&w,&h);
559                 x=p->next->member.x;
560                 y=p->next->member.y;
561 		t=get_time();
562 		DELTA_TIME=float2double(((double)(long_long)(t-p->next->member.last_updated))/MICROSECONDS);
563                 update_position(
564                         &(p->next->member),
565                         p->next->member.x+mul(p->next->member.xspeed,DELTA_TIME),
566                         p->next->member.y+mul(p->next->member.yspeed,DELTA_TIME),
567                         w,h,&stop_x,&stop_y);
568 		p->next->member.last_updated=t;
569 
570 		/* walk up the stairs */
571 		if (stop_x&&p->next->member.type==T_PLAYER&&!(p->next->member.status&256))
572 		{
573 			x1=p->next->member.x;
574 			y1=p->next->member.y;
575 			p->next->member.x=x;
576 			p->next->member.y=y-int2double(1);
577 	                update_position(
578         	                &(p->next->member),
579                 	        p->next->member.x+mul(p->next->member.xspeed,DELTA_TIME),
580                         	p->next->member.y+mul(p->next->member.yspeed,DELTA_TIME),
581 	                        w,h,0,&sy);
582 			if ((p->next->member.xspeed>0&&p->next->member.x<=x1)||(p->next->member.xspeed<0&&p->next->member.x>=x1)) /* restore original values */
583 			{
584 				p->next->member.x=x1;
585 				p->next->member.y=y1;
586 			}
587 			else
588 			{
589 				stop_y=sy;
590 				stop_x=0;
591 			}
592 		}
593 
594 		if (stop_x)p->next->member.xspeed=-mul(p->next->member.xspeed,obj_attr[p->next->member.type].bounce_x);
595 		if (my_abs(p->next->member.xspeed)<MIN_X_SPEED)
596 		{
597 			p->next->member.xspeed=0;
598 			p->next->member.status&=~1;
599 		}
600 
601 
602 		if (stop_y)
603 		{
604 			p->next->member.yspeed=mul(p->next->member.yspeed,obj_attr[p->next->member.type].bounce_y);
605 			p->next->member.yspeed=-p->next->member.yspeed;
606 			if (my_abs(p->next->member.yspeed)<MIN_Y_SPEED)
607 			{
608 				p->next->member.yspeed=0;
609 				if (stop_y==1)p->next->member.status&=~8;
610 			}
611 		}
612 
613 		if ((p->next->member.type==T_SHRAPNEL||p->next->member.type==T_BULLET)&&(stop_x||stop_y))  /* bullet and shrapnel die crashing into wall */
614 		{
615 			p=p->prev;  /* deleting object makes a great mess in for cycle, so we must cheat the cycle */
616 			delete_obj(p->next->next->member.id);
617 			continue;
618 		}
619 
620 	}
621 }
622 
623 
624 /* returns number of read bytes */
process_packet(unsigned char * packet,int l)625 int process_packet(unsigned char *packet,int l)
626 {
627 	int a,n=l;
628 
629 	switch(*packet)
630 	{
631 		case P_CHUNK:
632 		for (a=1;a<l&&a<MAX_PACKET_LENGTH;a+=n)
633 			n=process_packet(packet+a,l-a);
634 		break;
635 
636 		case P_NEW_OBJ:
637 		if (l<28)break;  /* invalid packet */
638 		n=28;
639 		new_obj(
640 			get_int(packet+1), /* ID */
641 			packet[25],  /* type */
642 			get_int16(packet+26), /* time to live */
643 			get_int16(packet+5),  /* sprite */
644 			0, /* anim position */
645 			get_int16(packet+23),  /* status */
646 			get_float(packet+7),  /* x */
647 			get_float(packet+11),  /* y */
648 			get_float(packet+15),  /* xspeed */
649 			get_float(packet+19),  /* yspeed */
650 			0  /* data */
651 		);
652 		break;
653 
654 		case P_PLAYER_DELETED:
655 		n=1;
656 		shut_down(1);
657 		break;
658 
659 		case P_DELETE_OBJECT:
660 		if (l<5)break;  /* invalid packet */
661 		delete_obj(get_int(packet+1));
662 		n=5;
663 		break;
664 
665 		case P_UPDATE_OBJECT:
666 		if (l<26)break;   /* invalid packet */
667 		{
668 			struct object_list *p;
669 
670 			n=26;
671 			p=find_in_table(get_int(packet+1));
672 			if (!p)break;
673 			if(packet[5]-(p->member.update_counter)>127)break; /* throw out old updates */
674 			p->member.update_counter=packet[5];
675 			p->member.x=get_float(packet+6);
676 			p->member.y=get_float(packet+10);
677 			p->member.xspeed=get_float(packet+14);
678 			p->member.yspeed=get_float(packet+18);
679 			p->member.status=get_int16(packet+22);
680 			p->member.data=0;
681 			p->member.ttl=get_int16(packet+24);
682 			/* kdyz tasi, tak se nahodi ttl */
683 			if (p->member.type==T_PLAYER&&(p->member.status&32)&&(p->member.status&16))
684 				p->member.ttl=weapon[current_weapon].cadence+HOLD_GUN_AFTER_SHOOT;
685 		}
686 		break;
687 
688 		case P_UPDATE_OBJECT_POS:
689 		if (l<22)break;   /* invalid packet */
690 		{
691 			struct object_list *p;
692 
693 			n=22;
694 			p=find_in_table(get_int(packet+1));
695 			if (!p)break;
696 			if(packet[5]-(p->member.update_counter)>127)break; /* throw out old updates */
697 			p->member.update_counter=packet[5];
698 			p->member.x=get_float(packet+6);
699 			p->member.y=get_float(packet+10);
700 			p->member.xspeed=get_float(packet+14);
701 			p->member.yspeed=get_float(packet+18);
702 		}
703 		break;
704 
705 		case P_UPDATE_OBJECT_SPEED:
706 		if (l<14)break;   /* invalid packet */
707 		{
708 			struct object_list *p;
709 
710 			n=14;
711 			p=find_in_table(get_int(packet+1));
712 			if (!p)break;
713 			if(packet[5]-(p->member.update_counter)>127)break; /* throw out old updates */
714 			p->member.update_counter=packet[5];
715 			p->member.xspeed=get_float(packet+6);
716 			p->member.yspeed=get_float(packet+10);
717 		}
718 		break;
719 
720 		case P_UPDATE_OBJECT_COORDS:
721 		if (l<14)break;   /* invalid packet */
722 		{
723 			struct object_list *p;
724 
725 			n=14;
726 			p=find_in_table(get_int(packet+1));
727 			if (!p)break;
728 			if(packet[5]-(p->member.update_counter)>127)break; /* throw out old updates */
729 			p->member.update_counter=packet[5];
730 			p->member.x=get_float(packet+6);
731 			p->member.y=get_float(packet+10);
732 		}
733 		break;
734 
735 		case P_UPDATE_OBJECT_SPEED_STATUS:
736 		if (l<16)break;   /* invalid packet */
737 		{
738 			struct object_list *p;
739 
740 			n=16;
741 			p=find_in_table(get_int(packet+1));
742 			if (!p)break;
743 			if(packet[5]-(p->member.update_counter)>127)break; /* throw out old updates */
744 			p->member.update_counter=packet[5];
745 			p->member.xspeed=get_float(packet+6);
746 			p->member.yspeed=get_float(packet+10);
747 			p->member.status=get_int16(packet+14);
748 			/* kdyz tasi, tak se nahodi ttl */
749 			if (p->member.type==T_PLAYER&&(p->member.status&32)&&(p->member.status&16))
750 				p->member.ttl=weapon[current_weapon].cadence+HOLD_GUN_AFTER_SHOOT;
751 		}
752 		break;
753 
754 		case P_UPDATE_OBJECT_COORDS_STATUS:
755 		if (l<16)break;   /* invalid packet */
756 		{
757 			struct object_list *p;
758 
759 			n=16;
760 			p=find_in_table(get_int(packet+1));
761 			if (!p)break;
762 			if(packet[5]-(p->member.update_counter)>127)break; /* throw out old updates */
763 			p->member.update_counter=packet[5];
764 			p->member.x=get_float(packet+6);
765 			p->member.y=get_float(packet+10);
766 			p->member.status=get_int16(packet+14);
767 			/* kdyz tasi, tak se nahodi ttl */
768 			if (p->member.type==T_PLAYER&&(p->member.status&32)&&(p->member.status&16))
769 				p->member.ttl=weapon[current_weapon].cadence+HOLD_GUN_AFTER_SHOOT;
770 		}
771 		break;
772 
773 		case P_UPDATE_OBJECT_SPEED_STATUS_TTL:
774 		if (l<18)break;   /* invalid packet */
775 		{
776 			struct object_list *p;
777 
778 			n=18;
779 			p=find_in_table(get_int(packet+1));
780 			if (!p)break;
781 			if(packet[5]-(p->member.update_counter)>127)break; /* throw out old updates */
782 			p->member.update_counter=packet[5];
783 			p->member.xspeed=get_float(packet+6);
784 			p->member.yspeed=get_float(packet+10);
785 			p->member.status=get_int16(packet+14);
786 			p->member.ttl=get_int16(packet+16);
787 			/* kdyz tasi, tak se nahodi ttl */
788 			if (p->member.type==T_PLAYER&&(p->member.status&32)&&(p->member.status&16))
789 				p->member.ttl=weapon[current_weapon].cadence+HOLD_GUN_AFTER_SHOOT;
790 		}
791 		break;
792 
793 		case P_UPDATE_OBJECT_COORDS_STATUS_TTL:
794 		if (l<18)break;   /* invalid packet */
795 		{
796 			struct object_list *p;
797 
798 			n=18;
799 			p=find_in_table(get_int(packet+1));
800 			if (!p)break;
801 			if(packet[5]-(p->member.update_counter)>127)break; /* throw out old updates */
802 			p->member.update_counter=packet[5];
803 			p->member.x=get_float(packet+6);
804 			p->member.y=get_float(packet+10);
805 			p->member.status=get_int16(packet+14);
806 			p->member.ttl=get_int16(packet+16);
807 			/* kdyz tasi, tak se nahodi ttl */
808 			if (p->member.type==T_PLAYER&&(p->member.status&32)&&(p->member.status&16))
809 				p->member.ttl=weapon[current_weapon].cadence+HOLD_GUN_AFTER_SHOOT;
810 		}
811 		break;
812 
813 		case P_UPDATE_STATUS:
814 		if (l<7)break;   /* invalid packet */
815 		{
816 			struct object_list *p;
817 
818 			n=7;
819 			p=find_in_table(get_int(packet+1));
820 			if (!p)break;  /* ignore objects we don't have */
821 			p->member.status=get_int16(packet+5);
822 			/* kdyz tasi, tak se nahodi ttl */
823 			if (p->member.type==T_PLAYER&&(p->member.status&32)&&(p->member.status&16))
824 				p->member.ttl=weapon[current_weapon].cadence+HOLD_GUN_AFTER_SHOOT;
825 		}
826 		break;
827 
828 		case P_HIT:
829 		if (l<8)break;    /* invalid packet */
830 		{
831 			struct object_list *p;
832 
833 			n=8;
834 			p=find_in_table(get_int(packet+1));
835 			if (!p)break;  /* ignore objects we don't have */
836 			p->member.status|=128;
837 			p->member.data=(void*)((packet[5]<<16)+(packet[7]<<8)+(packet[6]));
838 			/* kdyz tasi, tak se nahodi ttl */
839 			if (p->member.type==T_PLAYER&&(p->member.status&32)&&(p->member.status&16))
840 				p->member.ttl=weapon[current_weapon].cadence+HOLD_GUN_AFTER_SHOOT;
841 		}
842 		break;
843 
844 		case P_UPDATE_PLAYER:
845 		if (l<23)break;  /* invalid packet */
846 		health=packet[1];
847 		armor=packet[2];
848 		for (a=0;a<ARMS;a++)
849 			ammo[a]=get_int16(packet+3+(a<<1));
850 		frags=get_int(packet+3+ARMS*2);
851 		deaths=get_int(packet+7+ARMS*2);
852 		current_weapon=packet[11+2*ARMS];
853 		weapons=packet[12+2*ARMS];
854 		n=23;
855 		break;
856 
857 		case P_MESSAGE:
858 		if (l<2)break;   /* invalid packet */
859 		n=2+strlen(packet+1);
860 		break;
861 
862 		case P_END:
863 		if (l<2)printf("Game terminated.\n");
864 		else printf("Game terminated by %s.\n",packet+1);
865 		n=2+strlen(packet+1);
866 		shut_down(1);
867 
868 		case P_INFO:
869 		if (l<=5)break;
870 		l=6;
871 		for (a=0;a<packet[5]&&a<TOP_PLAYERS_N;a++)
872 		{
873 			int x;
874 			x=strlen(packet+l+9)+1;
875 			l+=x+9;
876 		}
877 		n=l;
878 		break;
879 
880 		case P_EXPLODE_GRENADE:
881 		{
882 			unsigned int i,j;
883 			struct object_list *p;
884 			int b;
885 
886 			if (l<9)break;
887 			n=9;
888 			i=get_int(packet+1);
889 			j=get_int(packet+5);
890 			p=find_in_table(j);
891 			if (!p)break;
892 
893 			for (b=0;b<N_SHRAPNELS_EXPLODE;b++)
894 			{
895 				double angle=(double)b*2*M_PI/N_SHRAPNELS_EXPLODE;
896 				my_double spd=add_int(mul_int(my_and(mul_int(weapon[WEAPON_GRENADE].speed,b+1),15),16),100);
897 
898 				new_obj(
899 					i,
900 					T_SHRAPNEL,
901 					SHRAPNEL_TTL,
902 					0,
903 					0,
904 					WEAPON_GRENADE,
905 					p->member.x,
906 					p->member.y,
907 					p->member.xspeed+mul(spd,float2double(cos(angle))),
908 					p->member.yspeed+mul(spd,float2double(sin(angle))),
909 					0);
910 				i++;
911 			}
912 			delete_obj(j);
913 
914 		}
915 		break;
916 
917 		case P_CHANGE_LEVEL:
918 		{
919 			unsigned char *md5;
920 			int a;
921 			char p;
922 
923 			if (l<38)break;   /* invalid packet */
924 			a=get_int(packet+1);
925 			if (level_number==a)goto level_changed;
926 			level_number=a;
927 
928 			md5=md5_level(level_number);
929 			if (strcmp(md5,packet+5))   /* MD5s differ */
930 			{
931 				mem_free(md5);
932 				ERROR("Invalid MD5 sum. Can't change level. Exiting...");
933 				send_quit();
934 				shut_down(1);
935 			}
936 			mem_free(md5);
937 
938 			/* OK we can change it */
939 			change_level();
940 level_changed:
941 
942 			p=P_LEVEL_ACCEPTED;
943 			send_packet(&p,1,(struct sockaddr *)(&server),my_id,0);
944 			n=38;
945 		}
946 		break;
947 
948 	}
949 	return n;
950 }
951 
952 
953 /* read packet from socket */
read_data(void)954 void read_data(void)
955 {
956         fd_set rfds;
957         struct timeval tv;
958         struct sockaddr_in client;
959         static unsigned char packet[MAX_PACKET_LENGTH];
960         int a=sizeof(client);
961 	int l;
962 
963         tv.tv_sec=0;
964         tv.tv_usec=0;
965         FD_ZERO(&rfds);
966         FD_SET(fd,&rfds);
967 	while(select(fd+1,&rfds,0,0,&tv))
968 	{
969 	        if ((l=recv_packet(packet,MAX_PACKET_LENGTH,(struct sockaddr*)(&client),&a,1,my_id,0))<0)
970 			return;   /* something's strange */
971 		process_packet(packet,l);
972 
973 	}
974 }
975 
976 
977 /* handle fatal signal (sigabrt, sigsegv, ...) */
signal_handler(int signum)978 void signal_handler(int signum)
979 {
980 
981 	if (connected)send_quit();
982 	shut_down(0);
983 	clear_memory();
984 #ifdef HAVE_PSIGNAL
985 	psignal(signum,"Exiting on signal");
986 #else
987 	fprintf(stderr, "Exiting on signal: %d\n", signum);
988 #endif
989 	if (!in_signal_handler){in_signal_handler=1;check_memory_leaks();}
990 	EXIT(1);
991 }
992 
993 
994 /* print command line help */
print_help(void)995 void print_help(void)
996 {
997         printf(
998 		"0verkill bot"
999 		".\n"
1000                 "(c)2000 Brainsoft\n"
1001                 "Usage: bot [-h] -a <server address> [-p <port>]"
1002 		"\n"
1003 	);
1004 }
1005 
1006 
parse_command_line(int argc,char ** argv)1007 void parse_command_line(int argc,char **argv)
1008 {
1009         int a;
1010 	char *e;
1011 
1012         while(1)
1013         {
1014                 a=getopt(argc,argv,"hp:a:");
1015                 switch(a)
1016                 {
1017                         case EOF:
1018                         return;
1019 
1020                         case '?':
1021                         case ':':
1022                         EXIT(1);
1023 
1024                         case 'h':
1025                         print_help();
1026                         EXIT(0);
1027 
1028 			case 'a':
1029 			host=optarg;
1030 			break;
1031 
1032 			case 'p':
1033 			port=strtoul(optarg,&e,10);
1034 			if (*e){ERROR("Error: Decimal number expected.\n");EXIT(1);}
1035 			break;
1036                 }
1037         }
1038 }
1039 
1040 
select_name(void)1041 unsigned char * select_name(void)
1042 {
1043 	return names[(random())%N_NAMES];
1044 }
1045 
1046 
where2go(void)1047 void where2go(void)
1048 {
1049 	if (!direction)
1050 	{
1051 		if (odds(20+const2))direction=2;
1052 		if (odds(20+const2))direction=1;
1053 	}
1054 	if(direction==1)keyboard_status.left=1;
1055 	if(direction==2)keyboard_status.right=1;
1056 
1057 	if (odds(40+const1))keyboard_status.jump=1;
1058 	if (odds(100+const4))keyboard_status.down_ladder=1;
1059 	if (odds(3)+const3)keyboard_status.fire=1;
1060 
1061 }
1062 
1063 
action(void)1064 void action(void)
1065 {
1066 	if ((hero->status)&1024)send_reenter_game();  /* respawn */
1067 	where2go();
1068 }
1069 
1070 /*----------------------------------------------------------------------------*/
main(int argc,char ** argv)1071 int main(int argc,char **argv)
1072 {
1073 	int color;
1074 	unsigned long_long last_time;
1075 	unsigned char *m;
1076 
1077 
1078 #ifdef WIN32
1079 	WSADATA wd;
1080 
1081 	WSAStartup(0x101, &wd);
1082 	printf("Started WinSock version %X.%02X\n", wd.wVersion/0x100, wd.wVersion&0xFF);
1083 #endif
1084 
1085 
1086 	ERROR("Initialization...\n");
1087 
1088 	last_obj=&objects;
1089 #ifndef WIN32
1090 	srandom(get_time());
1091 #else
1092 	srand(get_time());
1093 #endif
1094 
1095 	const1=random()%50;
1096 	const2=random()%20;
1097 	const3=random()%5;
1098 	const4=random()%20;
1099 
1100 	host=NULL;
1101 	parse_command_line(argc,argv);
1102 	if (!host){ERROR("No server address specified.\n");EXIT(1);}
1103 	hash_table_init();
1104 	init_sprites();
1105 	init_area();
1106 	ERROR("Loading graphics...\n");
1107 	load_sprites(DATA_PATH GAME_SPRITES_FILE);
1108 	level_sprites_start=n_sprites;
1109 
1110 	signal(SIGINT,signal_handler);
1111 	signal(SIGTERM,signal_handler);
1112 	signal(SIGILL,signal_handler);
1113 	signal(SIGABRT,signal_handler);
1114 	signal(SIGFPE,signal_handler);
1115 	signal(SIGSEGV,signal_handler);
1116 #ifndef WIN32
1117 	signal(SIGQUIT,signal_handler);
1118 	signal(SIGBUS,signal_handler);
1119 #endif
1120 
1121 	ERROR("Resolving server address ...\n");
1122 	if ((m=find_server(host,port))){ERROR(m);EXIT(1);}
1123 	ERROR("Initializing socket ...\n");
1124 	if ((m=init_socket())){ERROR(m);EXIT(1);}
1125 	ERROR("Contacting server ...\n");
1126 	color=(random()%15)+1;
1127 	if ((m=contact_server(color,select_name()))){ERROR(m);EXIT(1);}
1128 
1129 	connected=1;
1130 	ERROR("OK, connected.\nPlaying...\n");
1131 
1132 	last_time=get_time();
1133 again:
1134 	last_time+=CLIENT_PERIOD_USEC;
1135 	if (get_time()-last_time>PERIOD_USEC*100)last_time=get_time();
1136 	read_data();
1137 	reset_keyboard();
1138 	priority=0;
1139 	update_game();
1140 	action();
1141 	send_keyboard();
1142 	sleep_until(last_time+CLIENT_PERIOD_USEC);
1143 	goto again;
1144 }
1145