1 /*****************************************************************************
2 ** This is part of the SpaceZero program
3 ** Copyright(C) 2006-2013 MRevenga
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License (version 3), or
7 ** (at your option) any later version, as published by the Free Software
8 ** Foundation.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** 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 /************* SpaceZero M.R.H. 2006-2013 ******************
21 Author: MRevenga
22 E-mail: mrevenga at users.sourceforge.net
23 version 0.86 December 2013
24 **************************************************************/
25
26 /* Comm Perfomance :
27 bin/space -s -p 8 -l 20000
28 fondo: 5.8 kB/s
29
30 2 minutes: 53 objects 15 ships, 18 shots 196 KB/s 141007
31 2 min 8(4,4) 65 45 0 : MAX: 256.8 kB/s TOT: 25.1 MB => 214 kB/s
32 90 min 56 36 0 : MAX: 792 kB/s TOT: 1021 MB => 194 kB/s
33 don't send projectiles:
34 5 min 45 25 0 : MAX: 213 kB/s TOT: 49 MB => 167 kB/s, 311 obj/s
35 SENDOBJMOD
36 9:10 m 32 12 0 : MAX: 52.6 kB/s TOT: 18.8 MB => 35 kB/s, 194 obj/s
37 SENDOBJMOD0
38 2:40 m 28 8 0 : MAX: 49.8 kB/s TOT: 4.1 MB => 26.2 kB/s, 163 obj/s
39 5:20 m 49 29 0 : MAX: 58.9 kB/s TOT: 10.7MB => 34.2 kB/s, 250 obj/s
40 5:41 m 38 18 0 : MAX: 66.4 kB/s TOT: 11.3MB => 33.9 kB/s, 254 obj/s
41 SENDOBJAALL
42 5:26 m 43 23 0 : MAX: 52.7 kB/s TOT: 12.6MB => 39.6 kB/s, 279 obj/s
43 SENDOBJUNMOD
44 6:13 m 48 21 7 : MAX: 61.3 kB/s TOT: 10.1MB => 27.7 kB/s, 119 obj/s
45 SENDOBJUNMOD0
46 7:33 m 44 24 0 : MAX: 38.4 kB/s TOT: 9.8MB => 22.15 kB/s, 109 obj/s
47
48 */
49
50 #include <time.h>
51 #include <sys/stat.h>
52 #include <fcntl.h>
53 #include "spacecomm.h"
54 #include "ai.h"
55 #include "data.h"
56 #include "functions.h"
57 #include "clock.h"
58 #include "locales.h"
59 #include "players.h"
60 #include "menu.h"
61 #include "save.h"
62
63 #define SENDORDERS 1
64
65 extern struct HeadObjList listheadobjs;
66 extern struct TextMessageList listheadtext;
67 extern struct CharListHead gameloglist; /* list of all game messages */
68 extern struct Window windowgamelog;
69 extern struct Habitat habitat;
70 extern char *savefile;
71 extern sem_t sem_barrier;
72 extern sem_t sem_barrier1;
73
74 extern int order2thread;
75
76 extern int actual_player,actual_player0;
77 extern Object *ship_c;
78 extern int g_objid;
79 extern int g_projid;
80 extern int g_nobjsend;
81 extern int g_nshotsend;
82 extern int g_nobjtype[6];
83 extern struct Parametres param;
84
85 extern int fobj[4];
86
87 extern struct Player *players;
88 /* extern struct Keys keys; */
89 extern Object *cv; /* coordenates center */
90
91 extern char clientname[MAXTEXTLEN];
92
93 struct TextMessage textmen0; /* send message here */
94 struct TextMessage textmen1; /* recv message here */
95 struct Buffer buffer1,buffer2; /* buffers used in comm. */
96 extern struct Global gclient;
97
98
OpenComm(int mode,struct Parametres par,struct Sockfd * sockfd)99 int OpenComm(int mode,struct Parametres par,struct Sockfd *sockfd){
100 /*
101 version 02 26May2011
102 Initiates comm sockets
103 create thread to communication
104
105 */
106
107 struct hostent* he;
108
109 int sfd,nsfd;
110 struct sockaddr_in ser_addr,cli_addr;
111 int cli_addr_len;
112
113 int sfd2,nsfd2;
114 struct sockaddr_in ser_addr2,cli_addr2;
115 int cli_addr_len2;
116
117 int i;
118
119 sfd=nsfd=sfd2=nsfd2=0;
120
121 textmen0.n=0;
122 textmen0.time=0;
123 strcpy(textmen0.text,"");
124
125 textmen1.n=0;
126 textmen1.time=0;
127 strcpy(textmen1.text,"");
128
129
130
131 buffer1.data=malloc(BUFFERSIZE*sizeof(char));
132 if(buffer1.data==NULL){
133 fprintf(stderr,"ERROR in malloc (buffer1)\n");
134 exit(-1);
135 }
136 buffer1.n=0;
137 buffer1.size=BUFFERSIZE;
138
139
140
141 buffer2.data=malloc(BUFFERSIZE*sizeof(char));
142 if(buffer2.data==NULL){
143 fprintf(stderr,"ERROR in malloc (buffer2)\n");
144 exit(-1);
145 }
146 buffer2.n=0;
147 buffer2.size=BUFFERSIZE;
148
149 for(i=0;i<buffer1.size;i++)buffer1.data[i]=0;
150 for(i=0;i<buffer2.size;i++)buffer2.data[i]=0;
151
152 switch(mode){
153 case 0:/* server */
154 /***** Resolving Hostname **********************/
155 if ((he = gethostbyname(par.IP)) == NULL){
156 perror("gethostbyname");
157 exit(-1);
158 }
159 /**************************************************/
160 fprintf(stdout,"Waiting for player ...\n");
161 /* Apertura de un conector del tipo STREAM de la familia AF_INET */
162 if ((sfd=socket(PF_INET,SOCK_STREAM,0)) == -1){
163 perror("abrir socket");
164 exit(-1);
165 }
166
167 /* Publicidad de la direccion del servidor */
168
169 ser_addr.sin_family = AF_INET;
170 ser_addr.sin_addr= *((struct in_addr *)he->h_addr);
171 ser_addr.sin_port = htons ( par.port);
172
173 fprintf(stdout,"waiting conexion %s:%d\n",par.IP,par.port);
174
175 if(bind(sfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr)) == -1){
176 perror("bind");
177 fprintf(stderr,"port %d already in use\n",par.port);
178 exit(-1);
179 }
180
181 /* Declaracion de una cola con un elemento para
182 peticiones de conexion */
183 listen(sfd,1);
184
185 /*Segundo puerto */
186
187 /* Apertura de un conector del tipo STREAM de la familia AF_INET */
188 if ((sfd2=socket(PF_INET,SOCK_STREAM,0)) == -1){
189 perror("open socket");
190 exit(-1);
191 }
192
193 /* Publicidad de la direccion del servidor */
194
195 ser_addr2.sin_family = AF_INET;
196 ser_addr2.sin_addr= *((struct in_addr *)he->h_addr);
197 ser_addr2.sin_port = htons ( par.port2);
198
199 if(bind(sfd2,(struct sockaddr *)&ser_addr2,sizeof(ser_addr)) == -1){
200 perror("bind");
201 fprintf(stderr,"port %d already in use\n",par.port);
202 exit(-1);
203 }
204
205 /* Declaracion de una cola con un elemento para
206 peticiones de conexion */
207 listen(sfd2,1);
208
209
210 /* Atender Conexion 1 */
211 cli_addr_len = sizeof(cli_addr);
212 if((nsfd = accept (sfd,(struct sockaddr *)&cli_addr,(socklen_t *)&cli_addr_len)) == -1){
213 perror("accept");
214 exit(-1);
215 }
216
217 /* Atender Conexion 2 */
218 cli_addr_len2 = sizeof(cli_addr2);
219 if((nsfd2 = accept (sfd2,(struct sockaddr *)&cli_addr2,(socklen_t *)&cli_addr_len2)) == -1){
220 perror("accept");
221 exit(-1);
222 }
223
224 break;
225 case 1: /* client */
226 /* **** Resolving Hostname **********************/
227 if ((he = gethostbyname(par.IP)) == NULL){
228 perror("gethostbyname");
229 exit(-1);
230 }
231 /* ************************************************/
232 fprintf(stdout,"Connecting with server: %s:%d\n",par.IP,par.port);
233
234 /* Apertura de un conector del tipo STREAM de la familia AF_INET */
235 if ((sfd=socket(PF_INET,SOCK_STREAM,0)) == -1){
236 perror("open socket");
237 exit(-1);
238 }
239
240 /* Peticion de conexion con el servidor */
241 ser_addr.sin_family = AF_INET;
242 ser_addr.sin_addr= *((struct in_addr *)he->h_addr);
243 ser_addr.sin_port = htons ( par.port);
244 if(connect(sfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr)) == -1){
245 perror("conexion:");
246 fprintf(stderr,"port: %d\n",par.port);
247 exit(-1);
248 }
249
250 /* HERE duplicado */
251 fprintf(stdout,"Connecting with server: %s:%d\n",par.IP,par.port2);
252 /* Apertura de un conector del tipo STREAM de la familia AF_INET */
253 if ((sfd2=socket(PF_INET,SOCK_STREAM,0)) == -1){
254 perror("open socket");
255 exit(-1);
256 }
257
258 /* Peticion de conexion con el servidor */
259 ser_addr2.sin_family = AF_INET;
260 ser_addr2.sin_addr= *((struct in_addr *)he->h_addr);
261 ser_addr2.sin_port = htons ( par.port2);
262 if(connect(sfd2,(struct sockaddr *)&ser_addr2,sizeof(ser_addr2)) == -1){
263 perror("conexion");
264 fprintf(stderr,"port: %d",par.port2);
265 exit(-1);
266 }
267
268 break;
269 default:
270 break;
271 }
272 sockfd->sfd=sfd;
273 sockfd->sfd2=sfd2;
274 sockfd->nsfd=nsfd;
275 sockfd->nsfd2=nsfd2;
276
277 return(0);
278 }
279
StartComm(int mode,struct Sockfd * sockfd)280 int StartComm(int mode,struct Sockfd *sockfd){
281 /* Initial comunication between server and client */
282 char *buf1,*buf2;
283
284 int sfd,nsfd;
285 int sfd2,nsfd2;
286 pthread_attr_t attr;
287 pthread_t thread;
288
289 struct Thread_arg targs; /* arguments sended to the server and client */
290
291 int gnplayers;
292 struct Parametres paramc;
293 int npcc,npcs;
294
295 pthread_attr_init(&attr);
296 pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
297
298 sfd= sockfd->sfd;
299 sfd2= sockfd->sfd2;
300 nsfd= sockfd->nsfd;
301 nsfd2= sockfd->nsfd2;
302
303
304 switch(mode){
305 case 0:/* server */
306
307
308 buf1=buffer1.data;
309 buf2=buffer2.data;
310
311
312 /* receive game options from client */
313 recv_buf(nsfd,buf2);
314 memcpy(¶mc,buf2,sizeof(struct Parametres));
315
316 fprintf(stdout,"Client parametres:\n\tnplayers:%d\n\tname: %s\n",
317 paramc.nplayers,paramc.playername);
318
319 /* interpret the message */
320 if(strlen(paramc.playername)>0){
321 snprintf(clientname,MAXTEXTLEN,"%s",paramc.playername);
322 }
323 npcc=paramc.nplayers;
324 if(npcc>GameParametres(GET,GNPLAYERS,0)){
325 npcc=GameParametres(GET,GNPLAYERS,0);
326 }
327
328 paramc.nplayers=npcc;
329
330 fprintf(stdout,"Server parametres:\n\tnplayers:%d\n\tnpcs:%d\n",GameParametres(GET,GNPLAYERS,0),GameParametres(GET,GNPLAYERS,0)-npcc);
331
332 /* send the final options */
333 gnplayers=GameParametres(GET,GNPLAYERS,0);
334 memcpy(buf1,&gnplayers,sizeof(int));
335 memcpy(buf1+sizeof(int),&npcc,sizeof(int));
336 send_buf(nsfd,buf1,2*sizeof(int));
337
338
339 /* create server thread */
340
341 targs.sfd=nsfd;
342 targs.sfd2=nsfd2;
343 targs.id=0;
344 targs.n=0;
345
346 pthread_create(&(thread),&attr,CommServer,(void *)(&targs));
347
348 break;
349 case 1: /* client */
350
351 buf1=buffer1.data;
352 buf2=buffer2.data;
353
354 /* sending game options to server */
355
356 fprintf(stdout,"HELLO CLIENT\n");
357
358 fprintf(stdout,"sending client parametres:\n\tnplayers:%d\n\tname: %s\n",
359 param.nplayers,param.playername);
360
361 memcpy(buf1,¶m,sizeof(struct Parametres));
362 send_buf(sfd,buf1,sizeof(struct Parametres));
363
364 /* receiving the final options */
365
366 recv_buf(sfd,buf2);
367
368 gnplayers=GameParametres(GET,GNPLAYERS,0);
369 memcpy(&gnplayers,buf2,sizeof(int));
370 memcpy(&npcc,buf2+sizeof(int),sizeof(int));
371 npcs=GameParametres(GET,GNPLAYERS,0)-npcc;
372
373 fprintf(stdout,"Game:\n\tnplayers:%d \n\t npcc:%d\n\t npcs:%d\n",
374 GameParametres(GET,GNPLAYERS,0),
375 npcc,npcs);
376
377 /*create client thread*/
378 targs.sfd=sfd;
379 targs.sfd2=sfd2;
380 targs.id=0;
381 targs.n=0;
382
383 pthread_create(&(thread),&attr,CommClient,(void *)(&targs));
384
385 break;
386 default:
387 break;
388 }
389 sleep(1);
390 return(0);
391 }
392
393
CommServer(void * a)394 void *CommServer(void /* struct Thread_arg */ *a){
395 /*
396 version 01 25Nov2010
397 Server Thread
398 */
399 struct Thread_arg *args=(struct Thread_arg *)a;
400 int sfd,sfd2;
401 int fd;
402 /* struct IntList *kp,*ks; */
403 int status;
404
405
406 sfd=args->sfd;
407 sfd2=args->sfd2;
408
409 sem_post(&sem_barrier);
410 sem_wait(&sem_barrier1);
411
412
413 /* sending file with universe */
414
415 if((fd=open(SAVETMPFILE,O_RDONLY))==-1){
416 fprintf(stdout,"Commserver():Can't open the file: %s\n","/tmp/spacesavetmp");
417 exit(-1);
418 }
419
420 fprintf(stdout,"Sending file: %s\n",SAVETMPFILE);
421 SendFile(fd,sfd);
422 close(fd);
423
424
425 /* synchronization with main program */
426
427 sem_post(&sem_barrier);
428
429 /* set clocks to zero */
430
431 /* loop of communication */
432 for(;;){ /* server */
433
434 /* synchronization with main program */
435 sem_wait(&sem_barrier1);
436
437 SendBuffer(sfd,&buffer1);
438 fdatasync(sfd);
439
440 switch(order2thread){
441 case OTSENDLOAD:
442 /* checking the file */
443 if((fd=open(savefile,O_RDONLY))==-1){
444 fprintf(stdout,"CommServer()[OTSENDLOAD]: Can't open the file: %s\n",savefile);
445 exit(-1);
446 }
447 else{
448 /* sending file with universe */
449 SendFile(fd,sfd); /* copy file to buffer, send buffer */
450 }
451 close(fd);
452
453
454 break;
455 case OTSENDKILL:
456 fprintf(stdout,"exiting...\n");
457 RecvBuffer(sfd2,&buffer2);
458 GameParametres(SET,GNET,FALSE);
459 /* game.quit=2; */
460 close(sfd);
461 close(sfd2);
462 sem_post(&sem_barrier);
463 return((void *)1);
464
465 break;
466 default:
467 break;
468 }
469
470 RecvBuffer(sfd2,&buffer2);
471
472 status=ServerProcessBuffer(&buffer2);
473 switch(status){
474 case OTSENDKILL:
475 fprintf(stdout,"client has gone\n");
476 GameParametres(SET,GNET,FALSE);
477 /* game.quit=2; */
478 close(sfd);
479 close(sfd2);
480 sem_post(&sem_barrier);
481 return((void *)1);
482
483 break;
484 default:
485 break;
486 }
487
488 sem_post(&sem_barrier);
489 }
490 return((void *)0);
491 }
492
493
CommClient(void * a)494 void *CommClient(void /*struct Thread_arg*/ *a){
495 /*
496 version 01 25Nov2010
497 Client Thread
498 */
499 struct Thread_arg * args=(struct Thread_arg *) a;
500 char *buf;
501 int sfd;
502 int sfd2;
503 int fd;
504 int nbytes;
505 int status;
506
507 struct MessageHeader messh;
508 int order;
509
510
511 buf=buffer2.data;
512 sfd=args->sfd;
513 sfd2=args->sfd2;
514
515 sem_post(&sem_barrier);
516 sem_wait(&sem_barrier1);
517
518
519 /* receiving file with universe */
520
521 if((fd=open(savefile,O_WRONLY|O_CREAT,S_IREAD|S_IWRITE|S_IRGRP|S_IROTH))==-1){
522 fprintf(stdout,"CommClient(): Can't open the file: %s\n",savefile);
523 exit(-1);
524 }
525
526 fprintf(stdout,"Receiving file...%s\n",savefile);
527
528 RecvFile(fd,sfd);
529 close(fd);
530
531 fprintf(stdout,"...done\n");
532
533 /* synchronization with main program */
534
535 sem_post(&sem_barrier);
536
537 /* loop of communication */
538
539 /* set clocks to zero */
540
541 for(;;){ /* client */
542
543 /* synchronization with main program */
544 sem_wait(&sem_barrier1);
545
546 RecvBuffer(sfd,&buffer2);
547
548 nbytes=sizeof(struct MessageHeader);
549
550 buf=buffer2.data;
551 memcpy(&messh,buf,nbytes);
552 order=messh.id;
553
554
555 if(order2thread==OTSENDKILL){ /* client has gone */
556 /* sending message */
557 fprintf(stdout,"exiting...\n");
558 order=OTSENDKILL;
559 LoadBuffer(order,&buffer1,CLIENT);
560
561 SendBuffer(sfd2,&buffer1);
562 GameParametres(SET,GNET,FALSE);
563
564 close(sfd);
565 close(sfd2);
566 sem_post(&sem_barrier);
567 return((void *)1);
568 }
569
570 switch(order){
571 case OTSENDOBJS:
572 LoadBuffer(order,&buffer1,CLIENT);
573 break;
574 case OTSENDSAVE:
575 SetModifiedAll(&listheadobjs,ALLOBJS,SENDOBJALL,FALSE);
576 SetModifiedAll(&listheadobjs,PLANET,SENDOBJPLANET,TRUE);
577 Setttl(&listheadobjs,0);
578 LoadBuffer(order,&buffer1,CLIENT);
579 break;
580 case OTSENDLOAD:
581
582 fprintf(stdout,"received: load data\n");
583
584 /* receiving file with universe */
585
586 if((fd=open(savefile,O_WRONLY|O_CREAT,S_IREAD|S_IWRITE|S_IRGRP|S_IROTH))==-1){
587 fprintf(stdout,"CommClient()[OTSENDLOAD]: Can't open the file: %s\n",savefile);
588 exit(-1);
589 }
590
591 fprintf(stdout,"receiving file ...");
592 RecvFile(fd,sfd);
593 close(fd);
594
595 fprintf(stdout,"...done\n");
596 {
597 struct Keys *key;
598 key=GetKeys();
599 key->load=TRUE;
600 }
601 LoadBuffer(order,&buffer1,CLIENT);
602
603 break;
604 default:
605
606 break;
607 }
608
609 if(order!=OTSENDLOAD){
610 status=ClientProcessBuffer(&buffer2);
611
612 switch(status){
613 case OTSENDKILL:
614 fprintf(stdout,"SERVER has gone\n");
615 GameParametres(SET,GNET,FALSE);
616 SendBuffer(sfd2,&buffer1);
617 close(sfd);
618 close(sfd2);
619 sem_post(&sem_barrier);
620
621 return((void *)1);
622 break;
623 default:
624 break;
625 }
626 }
627
628 SendBuffer(sfd2,&buffer1);
629
630 fdatasync(sfd2);
631
632 sem_post(&sem_barrier);
633 }
634
635 return((void *)0);
636 }
637
638
PrintTextMessage(struct Message * mess)639 void PrintTextMessage(struct Message *mess){
640
641 fprintf(stdout,"\tid: %d\n\tnobjs: %d\n\tnbytes: %d\n",
642 mess->header.id,mess->header.nobjs,mess->header.nbytes);
643 }
644
645
646
CopyObjs2Buffer(struct Buffer * buffer,struct HeadObjList hl)647 int CopyObjs2Buffer(struct Buffer *buffer,struct HeadObjList hl){
648 /*
649 version 02 251110
650 Copy all objects with ttl <=0 belonging to proc to buffer
651 return:
652 the bytes copied to buffer.
653 */
654
655 struct ObjList *ls;
656 Object *obj;
657 int nbytes=0;
658 int proc;
659 int i;
660 struct MessageHeader messh;
661 struct NetMess mess;
662
663
664 proc=GetProc();
665 ls=hl.list;
666 while(ls!=NULL ){
667 if(proc!=players[ls->obj->player].proc){
668 ls=ls->next;continue;
669 }
670
671 if(ls->obj->ttl>0){
672 ls=ls->next;continue;
673 }
674
675 if(ls->obj->modified==SENDOBJDEAD ||
676 ls->obj->modified==SENDOBJNOTSEND ||
677 ls->obj->modified==SENDOBJUNMOD){
678 ls=ls->next;continue;
679 }
680
681 /* exceptions errors*/
682 if(ls->obj->type==PROJECTILE){
683 if(ls->obj->modified!=SENDOBJNEW){
684 fprintf(stderr,"WARNING: Trying to send a projectile\n");
685 fprintf(stderr,"\t id:%d type: %d mod:%d\n",ls->obj->id,ls->obj->type,ls->obj->modified);
686 }
687 }
688
689 /* --exceptions errors*/
690 obj=ls->obj;
691
692 if(obj->type==PLANET){ /* HERE , this must be mod */
693 obj->modified=SENDOBJPLANET;
694 }
695
696 nbytes+=CopyObj2Buffer(buffer,obj,obj->modified);
697 g_nobjsend++;
698 if(obj->type==PROJECTILE){
699 g_nshotsend++;
700 }
701
702 SetModified(obj,SENDOBJSEND);
703
704 ls=ls->next;
705 }
706 /**** Sending pending messages *****/
707 if(textmen0.time==-1){
708 nbytes+=CopyObj2Buffer(buffer,&textmen0,SENDOBJSTR);
709 textmen0.time=0;
710 }
711
712
713 /***** Send players *****/
714 {
715
716 /* HERE continue here */
717 for(i=1;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
718 if(proc==players[i].proc && players[i].modified==SENDPLAYERMOD){
719 messh.id=SENDPLAYERMOD;
720 messh.nobjs=1;
721 messh.nbytes=0;
722 CopyMessHeader2Buffer(buffer,&messh);
723 CopyPlayerMod2Buffer(buffer,&players[i]);
724
725 players[i].ttl=2000+i;
726 players[i].modified=SENDOBJUNMOD;
727 }
728 }
729 }
730
731
732 /***** Send Messages *****/
733
734 mess.id=mess.a=mess.b=0;
735 while(NetMess(&mess,NMREAD)!=0){
736 messh.id=SENDMESS;
737 messh.nobjs=1;
738 messh.nbytes=0;
739 nbytes+=CopyMessHeader2Buffer(buffer,&messh);
740 nbytes+=CopyNetMess2Buffer(buffer,&mess);
741 }
742
743 nbytes+=CopyObj2Buffer(buffer,NULL,SENDEND); /* end of transmision */
744 return(nbytes);
745 }
746
747
CopyObj2Buffer(struct Buffer * buffer,void * object,int modtype)748 int CopyObj2Buffer(struct Buffer *buffer,void *object,int modtype){
749 /*
750 version 01 (011210)
751 add object data to buffer to send
752 reallocate if necessary.
753 actualize buffer write position (buffer.n)
754 return the bytes writed to the buffer
755 */
756
757 int n0;
758 int nbytes=0;
759 char *buf;
760 struct MessageHeader *header;
761 struct MessageHeader messh;
762 Object *obj=NULL;
763 struct Objectpos opos;
764 struct Objectdynamic odyn;
765 struct ObjectAll oall;
766 struct ObjectAAll oaall;
767 struct ObjectNew onew;
768 struct TextMessage *text;
769 int kid;
770
771
772 /* if(modtype==SENDOBJKILL)return(0); */
773 if(buffer->n+sizeof(struct MessageHeader)+2*sizeof(Object) > buffer->size){
774 int newsize;
775 newsize=(int)((buffer->size+sizeof(struct MessageHeader)+2*sizeof(Object))*1.1);
776
777 buffer->data=realloc(buffer->data,newsize*sizeof(char));
778 if(buffer->data==NULL){
779 fprintf(stderr,"ERROR in malloc Copyfile2Buf()\n");
780 exit(-1);
781 }
782 buffer->size=newsize;
783 }
784
785 n0=buffer->n;
786 buf=(buffer->data+buffer->n);
787
788 /* copy the header */
789
790 header=(struct MessageHeader *)buf;
791
792
793 messh.id=modtype;
794 obj=(Object *)object;
795
796
797 switch (modtype){
798 case SENDOBJUNMOD:
799 fprintf(stderr,"WARNING CopyObj2Buffer() sending ans unmod obj (%d)%d",obj->player,obj->pid);
800 case SENDOBJMOD0: /* Object modified send only position */
801 messh.nobjs=1;
802 messh.nbytes=sizeof(struct Objectpos);
803 g_nobjtype[0]++;
804 break;
805 case SENDOBJMOD: /* Object modified */
806 messh.nobjs=1;
807 messh.nbytes=sizeof(struct Objectdynamic);
808 g_nobjtype[1]++;
809 break;
810 case SENDOBJAALL:
811 messh.nobjs=1;
812 messh.nbytes=sizeof(struct ObjectAAll);
813 g_nobjtype[2]++;
814 break;
815 case SENDOBJALL:
816 messh.nobjs=1;
817 messh.nbytes=sizeof(struct ObjectAll);
818 g_nobjtype[3]++;
819 break;
820 case SENDOBJNEW: /* new object. */
821 messh.nobjs=1;
822 messh.nbytes=sizeof(struct ObjectNew);
823 g_nobjtype[4]++;
824 break;
825 case SENDOBJKILL: /* qwerty */
826 messh.nobjs=1;
827 messh.nbytes=2*sizeof(int);
828 break;
829 case SENDOBJPLANET:
830 messh.nobjs=1;
831 messh.nbytes=2*sizeof(int)+sizeof(float);
832 g_nobjtype[5]++;
833 break;
834 case SENDOBJSTR:
835 messh.nobjs=1;
836 messh.nbytes=((struct TextMessage *)object)->n;
837 break;
838 case SENDEND: /* end of message */
839 messh.nobjs=0;
840 messh.nbytes=0;
841 break;
842 default:
843 fprintf(stderr,"ERROR CopyObj2Buffer(): id: %d modtype: %d\n",((Object *)object)->id,modtype);
844 exit(-1);
845 break;
846 }
847
848 CopyMessHeader2Buffer(buffer,&messh);
849
850 buf=buffer->data+buffer->n;
851
852 /* copy the object */
853
854 switch (modtype){
855 case SENDOBJUNMOD:
856 case SENDOBJMOD0: /* Object modified copy only position */
857 opos.id=obj->id;
858 opos.x=obj->x;
859 opos.y=obj->y;
860 /* aqui here */
861 nbytes=sizeof(struct Objectpos);
862
863 memcpy(buf,&opos,nbytes);
864 buffer->n+=nbytes;
865 break;
866 case SENDOBJMOD: /* Object modified, copy dynamic properties */
867 nbytes=sizeof(struct Objectdynamic);
868
869 odyn.id=obj->id;
870 odyn.level=obj->level;
871 odyn.habitat=obj->habitat;
872
873 odyn.inid=0;
874 if(obj->in!=NULL){
875 odyn.inid=obj->in->id;
876 }
877 odyn.mode=obj->mode;
878 odyn.x=obj->x;
879 odyn.y=obj->y;
880 odyn.x0=obj->x0;
881 odyn.y0=obj->y0;
882 odyn.vx=obj->vx;
883 odyn.vy=obj->vy;
884 odyn.a=obj->a;
885 odyn.ang_v=obj->ang_v;
886 odyn.ang_a=obj->ang_a;
887 odyn.accel=obj->accel;
888 /* odyn.gas=obj->gas; */
889 odyn.state=obj->state;
890
891
892 /* aqui memcpy((struct Objectdynamic *)buf,&odyn,nbytes); */
893 memcpy(buf,&odyn,nbytes);
894 buffer->n+=nbytes;
895 break;
896
897 case SENDOBJAALL: /* Object modified, copy dynamic properties */
898 nbytes=sizeof(struct ObjectAAll);
899
900 oaall.id=obj->id;
901 /* oaall.visible=obj->visible; */
902 oaall.level=obj->level;
903 /* oaall.kills=obj->kills; */
904 oaall.habitat=obj->habitat;
905 oaall.mode=obj->mode;
906 oaall.x=obj->x;
907 oaall.y=obj->y;
908 oaall.x0=obj->x0;
909 oaall.y0=obj->y0;
910 oaall.vx=obj->vx;
911 oaall.vy=obj->vy;
912
913 oaall.a=obj->a;
914 oaall.ang_v=obj->ang_v;
915 oaall.ang_a=obj->ang_a;
916 oaall.accel=obj->accel;
917 oaall.gas=obj->gas;
918 oaall.life=obj->life;
919 /* oaall.shield=obj->shield; */
920 oaall.state=obj->state;
921
922 oaall.inid=0;
923 if(obj->in!=NULL){
924 oaall.inid=obj->in->id;
925 }
926
927
928 /* aqui memcpy((struct ObjectAAll *)buf,&oaall,nbytes); */
929 memcpy(buf,&oaall,nbytes);
930 buffer->n+=nbytes;
931 break;
932
933 case SENDOBJNEW:
934 nbytes=sizeof(struct ObjectNew);
935
936 onew.id=obj->id;
937 onew.player=obj->player;
938 onew.type=obj->type;
939 onew.subtype=obj->subtype;
940 onew.durable=obj->durable;
941 onew.radio=obj->radio;
942 onew.damage=obj->damage;
943
944 onew.ai=obj->ai;
945 onew.modified=obj->modified;
946 onew.habitat=obj->habitat;
947 onew.mode=obj->mode;
948 onew.x=obj->x;
949 onew.y=obj->y;
950 onew.vx=obj->vx;
951 onew.vy=obj->vy;
952
953 onew.a=obj->a;
954 onew.gas=obj->gas;
955 onew.life=obj->life;
956
957 onew.parent=0;
958 onew.inid=0;
959 onew.planet=0;
960
961 onew.engtype=obj->engine.type;
962
963 if(obj->parent!=NULL){
964 onew.parent=obj->parent->id;
965 }
966 if(obj->in!=NULL){
967 onew.inid=obj->in->id;
968 }
969
970 /* aqui memcpy((struct ObjectNew *)buf,&onew,nbytes); */
971 memcpy(buf,&onew,nbytes);
972 buffer->n+=nbytes;
973
974 #if SENDORDERS
975 nbytes=AddObjOrders2Buffer(buffer,obj);
976 #endif
977
978 break;
979 case SENDOBJALL:
980
981 nbytes=sizeof(struct ObjectAll);
982
983 oall.id=obj->id;
984 oall.pid=obj->pid;
985 oall.oriid=obj->oriid;
986 oall.destid=obj->destid;
987 strncpy(oall.name,obj->name,OBJNAMESMAXLEN);
988 oall.player=obj->player;
989 oall.type=obj->type;
990 oall.subtype=obj->subtype;
991
992 oall.level=obj->level;
993 oall.experience=obj->experience;
994 oall.kills=obj->kills;
995 oall.ntravels=obj->ntravels;
996
997 oall.durable=obj->durable;
998 oall.visible=obj->visible;
999 oall.selected=obj->selected;
1000 oall.radar=obj->radar;
1001 oall.mass=obj->mass;
1002
1003 oall.cargo.capacity=obj->cargo.capacity;
1004 oall.cargo.mass=obj->cargo.mass;
1005 oall.cargo.n=obj->cargo.n;
1006 oall.cargo.hlist=NULL;
1007 oall.items=obj->items;
1008 oall.radio=obj->radio;
1009 oall.cost=obj->cost;
1010 oall.damage=obj->damage;
1011
1012 oall.ai=obj->ai;
1013 oall.modified=obj->modified;
1014 oall.ttl=obj->ttl;
1015 oall.habitat=obj->habitat;
1016 oall.mode=obj->mode;
1017
1018 oall.x=obj->x;
1019 oall.y=obj->y;
1020 oall.x0=obj->x0;
1021 oall.y0=obj->y0;
1022 oall.vx=obj->vx;
1023 oall.vy=obj->vy;
1024 oall.fx=obj->fx;
1025 oall.fy=obj->fy;
1026 oall.fx0=obj->fx0;
1027 oall.fy0=obj->fy0;
1028
1029 oall.a=obj->a;
1030 oall.ang_v=obj->ang_v;
1031 oall.ang_a=obj->ang_a;
1032 oall.accel=obj->accel;
1033 oall.gas=obj->gas;
1034 oall.gas_max=obj->gas_max;
1035 oall.life=obj->life;
1036 oall.shield=obj->shield;
1037 oall.state=obj->state;
1038
1039 oall.dest_r2=obj->dest_r2;
1040 oall.sw=obj->sw;
1041 oall.trace=obj->trace;
1042
1043 oall.norder=obj->norder;
1044 memcpy(&oall.actorder,&obj->actorder,sizeof(struct Order));
1045
1046 if(obj->parent!=NULL){oall.parent=obj->parent->id;}else{oall.parent=0;}
1047 if(obj->dest!=NULL){oall.dest=obj->dest->id;}else{oall.dest=0;}
1048 if(obj->in!=NULL){oall.inid=obj->in->id;}else{oall.inid=0;}
1049
1050 oall.weapon=0; /* HERE choose correct weapon */
1051 memcpy(&oall.weapon0,&obj->weapon0,sizeof(Weapon));
1052 memcpy(&oall.weapon1,&obj->weapon1,sizeof(Weapon));
1053 memcpy(&oall.weapon2,&obj->weapon2,sizeof(Weapon));
1054 memcpy(&oall.engine,&obj->engine,sizeof(Engine));
1055
1056 /* aqui memcpy((struct ObjectAAll *)buf,&oall,nbytes); */
1057 memcpy(buf,&oall,nbytes);
1058 buffer->n+=nbytes;
1059
1060 #if SENDORDERS
1061 nbytes=AddObjOrders2Buffer(buffer,obj);
1062 #endif
1063
1064 break;
1065 case SENDOBJKILL:
1066 nbytes=sizeof(int);
1067 kid=obj->id;
1068 memcpy(buf,&kid,nbytes);
1069
1070 kid=obj->sw; /* id of the killer */
1071 memcpy(buf+sizeof(int),&kid,nbytes);
1072 buffer->n+=2*nbytes;
1073
1074 break;
1075 case SENDOBJPLANET:
1076 nbytes=2*sizeof(int)+sizeof(float);
1077 memcpy(buf,&(obj->id),sizeof(int));
1078 memcpy(buf+sizeof(int),&(obj->player),sizeof(int));
1079 memcpy(buf+2*sizeof(int),&(obj->planet->gold),sizeof(float));
1080 buffer->n+=nbytes;
1081 break;
1082 case SENDOBJSTR:
1083 text=(struct TextMessage *)object;
1084 nbytes=header->nbytes;
1085 memcpy(buf,&text->text,nbytes);
1086
1087 buffer->n+=nbytes;
1088 break;
1089 case SENDEND: /* end of message */
1090 break;
1091 default:
1092 fprintf(stderr,"ERROR 2:CopyObj2Buffer() id:%d",modtype);
1093 exit(-1);
1094 break;
1095 }
1096
1097 return(buffer->n-n0);
1098 }
1099
1100
ReadObjsfromBuffer(char * buf)1101 int ReadObjsfromBuffer(char *buf){
1102 /*
1103 read the modified objs from the buffer and copy them to memory
1104 recive data
1105 returns:
1106 the number of bytes readed.
1107 */
1108
1109 struct MessageHeader header;
1110 Object *nobj,*objt,*parent;
1111 struct Objectpos objpos;
1112 struct Objectdynamic objdyn;
1113 struct ObjectAll objall;
1114 struct ObjectAAll objaall;
1115
1116 struct ObjectNew objnew;
1117 int gnplayers;
1118 int id,projid,idkiller;
1119 int inid;
1120 int nbytes,tbytes;
1121 int proc;
1122 Data *data;
1123
1124
1125 header.id=-1;
1126 tbytes=0;
1127
1128 proc=GetProc();
1129 gnplayers=GameParametres(GET,GNPLAYERS,0);
1130
1131 while(header.id!=SENDEND){
1132
1133
1134 /******
1135 read the header
1136 ******/
1137
1138 memcpy(&header,buf,sizeof(struct MessageHeader));
1139 buf+=sizeof(struct MessageHeader);
1140 tbytes+=sizeof(struct MessageHeader);
1141
1142 nobj=NULL;
1143
1144 switch(header.id){
1145 case SENDOBJUNMOD:
1146 case SENDOBJMOD0: /* only position */
1147
1148 nbytes=sizeof(struct Objectpos);
1149 nobj=SelectObj(&listheadobjs,((struct Objectpos *)buf)->id);
1150 if(nobj!=NULL){
1151
1152 /* aqui memcpy(&objpos,(struct Objectpos *)buf,nbytes); */
1153 memcpy(&objpos,buf,nbytes);
1154 nobj->x=objpos.x;
1155 nobj->y=objpos.y;
1156
1157 nobj->x0=objpos.x; /* x no x0 */
1158 nobj->y0=objpos.y;
1159 nobj->ttl=0;
1160 /* nobj->a=objpos.a; */
1161
1162 }
1163 else{ /* New object or object has been killed in client side*/
1164 fprintf(stderr,"ERROR ReadObjsfromBuffer(SENDOBJMOD0) id: %d type:%d mod: %d doesn't exists\n",
1165 ((Object *)buf)->id,((Object *)buf)->type,((Object *)buf)->modified);
1166 exit(-1);/*HERE TODO try to do something with this. LINE must not be reached */
1167 }
1168
1169 buf+=nbytes;
1170 tbytes+=nbytes;
1171 break;
1172 case SENDOBJMOD:
1173 nbytes=sizeof(struct Objectdynamic);
1174 nobj=SelectObj(&listheadobjs,((struct Objectdynamic *)buf)->id);
1175 if(nobj!=NULL){
1176 /* aqui memcpy(&objdyn,(struct Objectdynamic *)buf,nbytes); */
1177 memcpy(&objdyn,buf,nbytes);
1178
1179 nobj->level=objdyn.level;
1180 inid=0;
1181 if(nobj->in!=NULL){
1182 inid=nobj->in->id;
1183 }
1184 if(inid!=objdyn.inid){
1185 if(objdyn.inid==0){
1186 nobj->in=NULL;
1187 }
1188 else{
1189 nobj->in=SelectObj(&listheadobjs,objdyn.inid);
1190 }
1191 }
1192
1193 nobj->habitat=objdyn.habitat;
1194 nobj->mode=objdyn.mode;
1195 nobj->x=objdyn.x;
1196 nobj->y=objdyn.y;
1197 nobj->x0=objdyn.x0;
1198 nobj->y0=objdyn.y0;
1199 nobj->vx=objdyn.vx;
1200 nobj->vy=objdyn.vy;
1201 nobj->a=objdyn.a;
1202 nobj->ang_v=objdyn.ang_v;
1203 nobj->ang_a=objdyn.ang_a;
1204 nobj->accel=objdyn.accel;
1205 /* nobj->gas=objdyn.gas; */
1206 nobj->state=objdyn.state;
1207 nobj->ttl=0;
1208
1209 }
1210 else{ /* New object or object has been killed in client side*/
1211 fprintf(stderr,"ERROR ReadObjsfromBuffer(SENDOBJMOD) id: %d doesn't exists\n",
1212 ((struct Objectdynamic *)buf)->id);
1213 exit(-1);/*HERE TODO try to do something with this. LINE must not be reached */
1214 }
1215 buf+=nbytes;
1216 tbytes+=nbytes;
1217 break;
1218
1219 case SENDOBJAALL:
1220 nbytes=sizeof(struct ObjectAAll);
1221 nobj=SelectObj(&listheadobjs,((struct ObjectAAll *)buf)->id);
1222 if(nobj!=NULL){
1223
1224 memcpy(&objaall,buf,nbytes);
1225
1226 nobj->id=objaall.id;
1227 nobj->level=objaall.level;
1228 nobj->habitat=objaall.habitat;
1229 nobj->mode=objaall.mode;
1230 nobj->x=objaall.x;
1231 nobj->y=objaall.y;
1232 nobj->x0=objaall.x0;
1233 nobj->y0=objaall.y0;
1234 nobj->vx=objaall.vx;
1235 nobj->vy=objaall.vy;
1236
1237 nobj->fx=0;/* objaall.fx; */
1238 nobj->fy=0;
1239 nobj->fx0=0;
1240 nobj->fy0=0;
1241
1242 nobj->a=objaall.a;
1243 nobj->ang_v=objaall.ang_v;
1244 nobj->ang_a=objaall.ang_a;
1245 nobj->accel=objaall.accel;
1246 nobj->gas=objaall.gas;
1247 nobj->life=objaall.life;
1248 /* nobj->shield=objaall.shield; */
1249 nobj->state=objaall.state;
1250 nobj->in=NULL;
1251
1252 nobj->ttl=0;
1253 if(objaall.inid!=0){
1254 nobj->in=SelectObj(&listheadobjs,objaall.inid);
1255
1256 if(nobj->in!=NULL){
1257 nobj->planet=NULL;
1258 if(nobj->in->type==PLANET){
1259 nobj->planet=nobj->in->planet;
1260 }
1261 }
1262 else{
1263 fprintf(stderr,"ERROR in ReadObjsfromBuffer(OBJAALL)in =NULL\n");
1264 exit(-1);
1265 }
1266 }
1267
1268 }
1269 else{ /* New object or object has been killed in client side*/
1270 fprintf(stderr,"%d ERROR ReadObjsfromBuffer(SENDOBJAALL) id: %d doesn't exists\n",GetTime(),
1271 ((struct ObjectAAll *)buf)->id);
1272 exit(-1);/*HERE TODO try to do something with this. LINE must not be reached */
1273 }
1274 buf+=nbytes;
1275 tbytes+=nbytes;
1276 break;
1277
1278 case SENDOBJALL:
1279 nbytes=sizeof(struct ObjectAll);
1280 nobj=SelectObj(&listheadobjs,((struct ObjectAll *)buf)->id);
1281
1282 if(nobj==NULL){ /* the object doesn't exist */
1283 /* HERE BUG: pilots */
1284 fprintf(stderr,"\nERROR in ReadObjsfromBuffer(SENDOBJALL): Object %d (%d,%d) doesn't exists\n",((Object *)buf)->id,((Object *)buf)->type,((Object *)buf)->subtype);
1285 buf+=nbytes;
1286 tbytes+=nbytes;
1287 exit(-1);
1288 break;
1289 }
1290
1291 memcpy(&objall,buf,nbytes);
1292
1293 /* memcpy(&obj0,&nobj,nbytes); */
1294 data=nobj->cdata;
1295 parent=nobj->parent;
1296
1297 /***********************/
1298 /* CopyObject(nobj,obj); */
1299 nobj->id=objall.id;
1300 nobj->pid=objall.pid;
1301 nobj->pid=objall.pid;
1302 nobj->oriid=objall.oriid;
1303 strncpy(nobj->name,objall.name,OBJNAMESMAXLEN);
1304 nobj->player=objall.player;
1305 nobj->type=objall.type;
1306 nobj->subtype=objall.subtype;
1307
1308 nobj->level=objall.level;
1309 nobj->experience=objall.experience;
1310 nobj->pexperience=0;
1311 nobj->kills=objall.kills;
1312 nobj->ntravels=objall.ntravels;
1313
1314 nobj->durable=objall.durable;
1315 nobj->visible=objall.visible;
1316 nobj->selected=objall.selected;
1317 nobj->radar=objall.radar;
1318 nobj->mass=objall.mass;
1319 nobj->cargo.capacity=objall.cargo.capacity;
1320 nobj->cargo.n=objall.cargo.n;
1321 nobj->cargo.mass=objall.cargo.mass;
1322 nobj->cargo.hlist=NULL;
1323
1324 nobj->items=objall.items;
1325 nobj->radio=objall.radio;
1326 nobj->cost=objall.cost;
1327 nobj->damage=objall.damage;
1328
1329 nobj->ai=objall.ai;
1330 nobj->modified=objall.modified;
1331 nobj->ttl=objall.ttl;
1332 nobj->habitat=objall.habitat;
1333 nobj->mode=objall.mode;
1334
1335 nobj->x=objall.x;
1336 nobj->y=objall.y;
1337 nobj->x0=objall.x0;
1338 nobj->y0=objall.y0;
1339 nobj->vx=objall.vx;
1340 nobj->vy=objall.vy;
1341 nobj->fx=objall.fx;
1342 nobj->fy=objall.fy;
1343 nobj->fx0=objall.fx0;
1344 nobj->fy0=objall.fy0;
1345
1346 nobj->a=objall.a;
1347 nobj->ang_v=objall.ang_v;
1348 nobj->ang_a=objall.ang_a;
1349 nobj->accel=objall.accel;
1350 nobj->gas=objall.gas;
1351 nobj->gas_max=objall.gas_max;
1352 nobj->life=objall.life;
1353 nobj->shield=objall.shield;
1354 nobj->state=objall.state;
1355
1356 nobj->dest_r2=objall.dest_r2;
1357 nobj->sw=objall.sw;
1358 nobj->trace=objall.trace;
1359
1360 nobj->norder=objall.norder;
1361 memcpy(&nobj->actorder,&objall.actorder,sizeof(struct Order));
1362
1363
1364 memcpy(&nobj->weapon0,&objall.weapon0,sizeof(Weapon));
1365 memcpy(&nobj->weapon1,&objall.weapon1,sizeof(Weapon));
1366 memcpy(&nobj->weapon2,&objall.weapon2,sizeof(Weapon));
1367 memcpy(&nobj->engine,&objall.engine,sizeof(Engine));
1368
1369 /***********************************/
1370
1371 nobj->cdata=data;
1372 nobj->parent=parent;
1373
1374 /* nobj->modified=0; */
1375 /* nobj->norder=0; */
1376
1377 /* HERE save as data */
1378 /* nobj->parent=NULL; */
1379 nobj->dest=NULL;
1380 nobj->in=NULL;
1381 nobj->planet=NULL;
1382 nobj->lorder=NULL;
1383 nobj->weapon=NULL;
1384
1385 objt=NULL;
1386
1387 nobj->dest=SelectObj(&listheadobjs,(objall.dest)); /* HERE one function for all the pointers */
1388 /* nobj->parent=SelectObj(&listheadobjs,(int)(obj->parent)); */
1389 nobj->in=SelectObj(&listheadobjs,objall.inid);
1390
1391
1392 if(nobj->in!=NULL){
1393
1394 nobj->planet=NULL;
1395
1396 if(nobj->in->type==PLANET){
1397 nobj->planet=nobj->in->planet;
1398 }
1399 /* if(nobj->in->type==SHIP){ */
1400 /* nobj->in->items=nobj->in->items| ITPILOT; */
1401 /* } */
1402 }
1403 else{
1404 if(objall.inid!=0){
1405 fprintf(stderr,"ERROR in ReadObjsfromBuffer(id: %d)in =NULL\n",nobj->id);
1406 exit(-1);
1407 }
1408 }
1409 nobj->weapon=&nobj->weapon0;
1410 nobj->ttl=0;
1411 buf+=nbytes;
1412 tbytes+=nbytes;
1413
1414 #if SENDORDERS
1415 nbytes=CopyObjOrdersfromBuffer(nobj,buf);
1416 buf+=nbytes;
1417 tbytes+=nbytes;
1418 #endif
1419
1420 break;
1421 case SENDOBJPLANET:
1422 nbytes=2*sizeof(int)+ sizeof(float);
1423 memcpy(&id,buf,sizeof(int));
1424 nobj=SelectObj(&listheadobjs,id);
1425 if(nobj==NULL){
1426 fprintf(stderr,"ERROR ReadObjsfromBuffer(SENDOBJPLANET) id: %d doesn't exists\n",id);
1427 exit(-1);
1428 }
1429 /* memcpy(&player,buf+sizeof(int),sizeof(int)); */
1430
1431 if(nobj->modified==SENDOBJSEND && nobj->sw){
1432 nobj->sw=0;
1433 }
1434 else{
1435 memcpy(&(nobj->player),buf+sizeof(int),sizeof(int));
1436 memcpy(&(nobj->planet->gold),buf+2*sizeof(int),sizeof(float));
1437 }
1438
1439 /**** check if I a have that information
1440 received ally conquered planets ****/
1441
1442 if(players[nobj->player].team==players[actual_player].team){
1443 if(IsInIntList((players[actual_player].kplanets),nobj->id)==0){
1444 players[actual_player].kplanets=Add2IntList((players[actual_player].kplanets),nobj->id);
1445 }
1446 }
1447
1448
1449 buf+=nbytes;
1450 tbytes+=nbytes;
1451 break;
1452 case SENDOBJKILL:
1453 nbytes=sizeof(int);
1454 memcpy(&id,buf,nbytes);
1455 buf+=nbytes;
1456 tbytes+=nbytes;
1457 memcpy(&idkiller,buf,nbytes);
1458 buf+=nbytes;
1459 tbytes+=nbytes;
1460 nobj=SelectObj(&listheadobjs,id);
1461
1462 if(nobj==NULL){
1463 fprintf(stderr,"ERROR ReadObjsfromBuffer(SENDOBJKILL) id: %d doesn't exists\n",id);
1464 /*exit(-1);*/ /*HERE TODO try to do something with this. LINE must not be reached */
1465 }
1466 else{
1467 nobj->state=0;
1468 nobj->modified=SENDOBJDEAD;/* RemoveObj(nobj); */
1469 nobj->sw=idkiller;
1470 }
1471
1472 break;
1473 case SENDOBJNEW:
1474 id=g_objid;
1475 projid=g_projid;
1476 nbytes=sizeof(struct ObjectNew);
1477
1478 /* aqui memcpy(&objnew,(struct ObjectNew *)buf,nbytes); */
1479 memcpy(&objnew,buf,nbytes);
1480
1481 nobj=SelectObj(&listheadobjs,objnew.id);
1482 if(nobj!=NULL){ /* the object exist */
1483 fprintf(stderr,"\nERROR in ReadObjsfromBuffer(SENDOBJNEW): Object %d exists type:%d stype:%d proc:%d\n",nobj->id,nobj->type,nobj->subtype,players[nobj->player].proc);
1484 buf+=sizeof(struct ObjectNew);
1485 tbytes+=nbytes;
1486 exit(-1); /*HERE TODO try to do something with this. LINE must not be reached */
1487 }
1488
1489
1490 /* obj=(struct ObjectNew *)buf; */
1491
1492 parent=SelectObj(&listheadobjs,objnew.parent);
1493
1494 nobj=NewObj(objnew.type,objnew.subtype,
1495 objnew.x,objnew.y,
1496 objnew.vx,objnew.vy,
1497 CANNON0,objnew.engtype,objnew.player,parent,NULL);
1498
1499 if(nobj==NULL){
1500 fprintf(stderr,"\nERROR in ReadObjsfromBuffer(): NewObj() returns NULL\n");
1501 fprintf(stderr,"\t object not created. Exiting ...\n");
1502 exit(-1);
1503 }
1504
1505 if(parent==NULL &&nobj->type!=SHIP && nobj->type!=ASTEROID){ /* */
1506 fprintf(stderr,"\nWARNING in ReadObjsfromBuffer(SENDOBJNEW): id:%d type:%d(parent) obj %d doesn't exists\n",nobj->id,nobj->type,((struct ObjectNew *)buf)->parent);
1507 /* buf+=sizeof(Object); */
1508 /* exit(-1); */
1509 }
1510
1511
1512 g_objid=id;
1513 g_projid=projid;
1514
1515 nobj->id=objnew.id;
1516 /* nobj->player=objnew.player; */
1517
1518 if(nobj->player!=objnew.player){
1519 fprintf(stderr,"ERROR readobjsfrombuffer\n");
1520 exit(-1);
1521 }
1522 nobj->type=objnew.type;
1523 nobj->subtype=objnew.subtype;
1524 nobj->durable=objnew.durable;
1525
1526 nobj->radio=objnew.radio;
1527 nobj->damage=objnew.damage;
1528 nobj->ai=objnew.ai;
1529 nobj->modified=objnew.modified;
1530 nobj->habitat=objnew.habitat;
1531 nobj->mode=objnew.mode;
1532 nobj->x=objnew.x;
1533 nobj->y=objnew.y;
1534 nobj->vx=objnew.vx;
1535 nobj->vy=objnew.vy;
1536
1537 nobj->a=objnew.a;
1538 nobj->gas=objnew.gas;
1539 nobj->life=objnew.life;
1540
1541 nobj->norder=0;
1542 nobj->parent=parent;
1543 nobj->dest=NULL;
1544 nobj->in=NULL;
1545 nobj->planet=NULL;
1546 nobj->lorder=NULL;
1547 nobj->weapon=&nobj->weapon0;
1548 nobj->ttl=0;
1549 objt=NULL;
1550
1551 if(objnew.inid!=0){
1552 nobj->in=SelectObj(&listheadobjs,objnew.inid);
1553
1554 if(nobj->habitat==H_SPACE){
1555 fprintf(stderr,"ERROR in ReadObjsfromBuffer(OBJNEW)in !=NULL\n");
1556 exit(-1);
1557 }
1558 }
1559
1560 objt=SelectObj(&listheadobjs,objnew.planet);
1561 if(objt!=NULL){
1562 nobj->planet=objt->planet;
1563 }
1564
1565 Add2ObjList(&listheadobjs,nobj);
1566 buf+=nbytes;
1567 tbytes+=nbytes;
1568
1569 #if SENDORDERS
1570 nbytes=CopyObjOrdersfromBuffer(nobj,buf);
1571 buf+=nbytes;
1572 tbytes+=nbytes;
1573 #endif
1574
1575 break;
1576
1577 case SENDOBJSTR:
1578 if(header.nbytes>MAXTEXTLEN || header.nbytes<0){
1579 fprintf(stderr,"ERROR in SENDOBJSTR : %d\n",header.nbytes);
1580 exit(-1);
1581 }
1582 textmen1.n=header.nbytes;
1583 textmen1.time=100;
1584 strncpy(textmen1.text,buf,header.nbytes);
1585 strncpy(textmen1.text+header.nbytes,"\0",1);
1586 fprintf(stdout,"RECV MESS: %s\n",textmen1.text);
1587
1588 if(strncmp(textmen1.text,"Game PAUSED",12)==0){
1589 textmen1.time=4;
1590 }
1591
1592 buf+=header.nbytes;
1593 tbytes+=header.nbytes;
1594 break;
1595
1596
1597 case SENDPLAYER:
1598 {
1599 struct HeadIntIList ks;
1600 struct IntList *kp;
1601 struct PlayerAll playerall;
1602 struct Player *player;
1603
1604
1605 nbytes=sizeof(struct PlayerAll);
1606 memcpy(&playerall,buf,nbytes);
1607
1608 /* DelIntIList(&(players[playerall.id].ksectors)); */
1609 kp=players[playerall.id].kplanets;
1610
1611 memcpy(&ks,&players[playerall.id].ksectors,sizeof(struct HeadIntIList));
1612 /****/
1613 player=&players[playerall.id];
1614
1615 strncpy(player->playername,playerall.playername,MAXTEXTLEN);
1616
1617 player->id=playerall.id;
1618 player->pid=playerall.pid;
1619 player->proc=playerall.proc;
1620 player->control=playerall.control;
1621 player->team=playerall.team;
1622 player->profile=playerall.profile;
1623 player->strategy=playerall.strategy;
1624 player->gmaxlevel=playerall.gmaxlevel;
1625 player->maxlevel=playerall.maxlevel;
1626 player->color=playerall.color;
1627 player->cv=playerall.cv;
1628 player->nplanets=playerall.nplanets;
1629 player->nships=playerall.nships;
1630 player->nbuildships=playerall.nbuildships;
1631 player->gold=playerall.gold;
1632 player->balance=playerall.balance;
1633 player->lastaction=playerall.lastaction;
1634 player->ndeaths=playerall.ndeaths;
1635 player->nkills=playerall.nkills;
1636 player->points=playerall.points;
1637 player->modified=playerall.modified;
1638 player->ttl=playerall.ttl;
1639
1640
1641 /****/
1642
1643
1644 players[playerall.id].kplanets=kp;
1645 memcpy(&players[playerall.id].ksectors,&ks,sizeof(struct HeadIntIList));
1646
1647 players[playerall.id].ttl=2000;
1648 players[playerall.id].modified=SENDOBJUNMOD;
1649
1650
1651 buf+=nbytes;
1652 tbytes+=nbytes;
1653 }
1654 break;
1655
1656 case SENDPLAYERMOD:
1657 {
1658 struct PlayerMod pmod;
1659 int pid;
1660
1661 nbytes=sizeof(struct PlayerMod);
1662 memcpy(&pmod,buf,nbytes);
1663 pid=pmod.id;
1664
1665 players[pid].gmaxlevel=pmod.gmaxlevel;
1666 players[pid].maxlevel=pmod.maxlevel;
1667 players[pid].nplanets=pmod.nplanets;
1668 players[pid].nships=pmod.nships;
1669 players[pid].nbuildships=pmod.nbuildships;
1670 players[pid].gold=pmod.gold;
1671 players[pid].ndeaths=pmod.ndeaths;
1672 players[pid].nkills=pmod.nkills;
1673 players[pid].points=pmod.points;
1674 players[pid].ttl=2000;
1675 players[pid].modified=SENDOBJUNMOD;
1676
1677 buf+=nbytes;
1678 tbytes+=nbytes;
1679 }
1680 break;
1681
1682 case SENDMESS:
1683 {
1684 struct NetMess mess;
1685
1686 nbytes=sizeof(struct NetMess);
1687 memcpy(&mess,buf,nbytes);
1688 buf+=nbytes;
1689 tbytes+=nbytes;
1690
1691 switch(mess.id){
1692 case NMPLANETDISCOVERED:
1693 {
1694 Object *obj,*pnt;
1695 int i;
1696 char text[MAXTEXTLEN];
1697 obj=SelectObj(&listheadobjs,mess.a);
1698 pnt=SelectObj(&listheadobjs,mess.b);
1699
1700 if(obj!=NULL && pnt!=NULL){
1701 for(i=0;i<=gnplayers+1;i++){
1702 if( (i!=obj->player) && ((players[obj->player].team==players[i].team) || GameParametres(GET,GENEMYKNOWN,0)) ){
1703 if(GetProc()==players[i].proc){
1704 if(IsInIntList((players[i].kplanets),pnt->id)==0){
1705 players[i].kplanets=Add2IntList((players[i].kplanets),pnt->id);
1706 snprintf(text,MAXTEXTLEN,"(%s) %s %d %s",
1707 players[obj->player].playername,
1708 GetLocale(L_PLANET),
1709 pnt->id,
1710 GetLocale(L_DISCOVERED));
1711 if(!Add2TextMessageList(&listheadtext,text,obj->id,i,0,100,0)){
1712 Add2CharListWindow(&gameloglist,text,0,&windowgamelog);
1713 }
1714 }
1715 }
1716 }
1717 }
1718 }
1719 else{
1720 fprintf(stderr,"ERROR ReadObjsFromBuffer(): obj or planet NULL %p %p\n",
1721 (void *)obj,(void *)pnt);
1722 fprintf(stderr,"\tmessage discarded\n");
1723 }
1724 }
1725 break;
1726 case NMPLANETLOST:
1727 {
1728 char text[MAXTEXTLEN];
1729 if(GetProc()==players[mess.a].proc){
1730 snprintf(text,MAXTEXTLEN,"%s %d %s",
1731 GetLocale(L_PLANET),
1732 mess.b,
1733 GetLocale(L_LOST));
1734 if(!Add2TextMessageList(&listheadtext,text,mess.b,mess.a,0,100,2)){
1735 Add2CharListWindow(&gameloglist,text,0,&windowgamelog);
1736 }
1737 }
1738 }
1739 break;
1740 default:
1741 fprintf(stderr,"ERROR. ReadObjsFromBuffer() SENDMESS. Not implemented %d\n",mess.id);
1742 exit(-1);
1743 break;
1744 }
1745 }
1746 break;
1747
1748 case SENDEND:
1749 break;
1750 default:
1751 fprintf(stderr,"ERROR ReadObjsfromBuffer() header id %d unknown\n",header.id);
1752 exit(-1);
1753 break;
1754 }
1755
1756 if(nobj!=NULL){
1757 nobj->trace=FALSE;
1758 if(nobj->mode==LANDED){ /*accel must be zero */
1759 nobj->accel=0;
1760 }
1761
1762 if(proc!=players[nobj->player].proc){
1763 nobj->ttl=0;
1764 }
1765
1766 if(cv==nobj){
1767 habitat.type=cv->habitat;
1768 habitat.obj=cv->in;
1769 }
1770 /* check for pilots */ /* HERE must not be necesary eject pilots */
1771 /* if((nobj->items & ITPILOT)){ */
1772
1773 /* /\* when landed *\/ */
1774 /* if(nobj->mode==LANDED){ */
1775 /* EjectPilotsObj(&listheadobjs,nobj); */
1776 /* nobj->items=(nobj->items)&(~ITPILOT); */
1777 /* } */
1778
1779 /* /\* when destroyed *\/ */
1780 /* if(nobj->modified==SENDOBJDEAD){ */
1781 /* EjectPilotsObj(&listheadobjs,nobj); */
1782 /* } */
1783 /* } */
1784
1785 /* --check for pilots */
1786
1787 }
1788 }
1789 return(tbytes);
1790 }/* int ReadObjsfromBuffer(char *buf){ */
1791
1792
SendTextMessage(char * mess)1793 void SendTextMessage(char *mess){
1794 int l;
1795 l=strlen(mess);
1796 if(l>MAXTEXTLEN)l=MAXTEXTLEN;
1797
1798 memcpy(textmen0.text,mess,l);
1799 textmen0.n=l;
1800 textmen0.time=-1;
1801 }
1802
PendingTextMessage(void)1803 int PendingTextMessage(void){
1804 if(textmen1.time>0)return(1);
1805 return(0);
1806 }
1807
GetTextMessage(char * mess)1808 void GetTextMessage(char *mess){
1809 int l;
1810 l=strlen(textmen1.text);
1811 if(l>MAXTEXTLEN)l=MAXTEXTLEN;
1812 memcpy(mess,textmen1.text,l);
1813 memcpy(mess+l,"\0",1);
1814 textmen1.time--;
1815 }
1816
TextMessage(int action)1817 void TextMessage(int action){
1818
1819 switch(action){
1820 case 0:
1821 break;
1822 case 1:
1823 break;
1824 case 2:
1825 break;
1826 default:
1827 break;
1828 }
1829 }
1830
CopyObjOrdersfromBuffer(Object * obj0,char * buf0)1831 int CopyObjOrdersfromBuffer(Object *obj0,char *buf0){
1832
1833 /*
1834 Copy the orders of the object obj from the buffer
1835 returns:
1836 the number of bytes writed.
1837 */
1838 struct Order order;
1839 char *buf;
1840 int nbytes,tbytes;
1841 int i;
1842 int norders;
1843 int nordread=0;
1844
1845 tbytes=0;
1846 buf=buf0;
1847
1848 /* reading norders*/
1849
1850 nbytes=sizeof(int); /* norders */
1851 memcpy(&norders,buf,nbytes);
1852 buf+=nbytes;
1853 tbytes+=nbytes;
1854
1855 DelAllOrder(obj0);
1856
1857 /* rest of orders */
1858
1859 obj0->lorder=NULL;
1860 obj0->norder=0;
1861 nbytes=sizeof(struct Order);
1862
1863 for(i=0;i<norders;i++){
1864 memcpy(&order,buf,nbytes);
1865 AddOrder(obj0,&order);
1866 buf+=nbytes;
1867 tbytes+=nbytes;
1868 nordread++;
1869
1870 }
1871 return(tbytes);
1872 }
1873
1874
1875
SetModified(Object * obj,int mode)1876 int SetModified(Object *obj,int mode){
1877 /*
1878 version 01
1879 returns:
1880 0 if the obj is modified to mode
1881 1 if its modified to other mode
1882 2 not modified, error
1883 */
1884 int sw=0;
1885 int swmod=0;
1886
1887 /* object modify types, used in transmission buffer */
1888
1889 /* #define SENDOBJUNMOD 32 /\* obj unmodified, don't send *\/ */
1890 /* #define SENDOBJMOD0 33 /\* obj modified, send only position *\/ */
1891 /* #define SENDOBJMOD 34 /\* obj modified, send more information *\/ */
1892 /* #define SENDOBJAALL 35 /\* obj modified, send almost all info *\/ */
1893 /* #define SENDOBJALL 36 /\* obj modified, send all info *\/ */
1894 /* #define SENDOBJKILL 37 /\* delete the object *\/ */
1895 /* #define SENDOBJNEW 38 /\* new obj *\/ */
1896 /* #define SENDOBJDEAD 39 /\* don't send and remove *\/ */
1897 /* #define SENDOBJPLANET 40 /\* send all info planet *\/ */
1898 /* #define SENDOBJSTR 41 /\* send a text message *\/ */
1899 /* #define SENDOBJSEND 42 /\* object just sended *\/ */
1900 /* #define SENDOBJNOTSEND 43 /\*don't send *\/ */
1901
1902 if(obj==NULL)return(2);
1903
1904 if(mode==obj->modified)return(0);
1905
1906 if(GetProc()!=players[obj->player].proc){
1907 /* mode allowed for different processes */
1908 switch(mode){
1909 default:
1910 break;
1911 }
1912 }
1913
1914 if(GameParametres(GET,GMODE,0)==LOCAL){
1915 return(0);
1916 }
1917
1918
1919 /* forbidden changes */
1920
1921 if(mode==SENDOBJNEW){ /* SENDOBJNEW only in NewObj() */
1922 return(2);
1923 }
1924
1925
1926 /* --forbidden changes */
1927
1928
1929 /******** PLANETS AND PROJECTILES ******/
1930 switch(obj->type){
1931 case PLANET:
1932 switch(obj->modified){
1933 case SENDOBJUNMOD:
1934 switch(mode){
1935 case SENDOBJUNMOD:
1936 break;
1937 case SENDOBJMOD0:
1938 case SENDOBJMOD:
1939 case SENDOBJAALL:
1940 case SENDOBJALL:
1941 case SENDOBJPLANET:
1942 obj->modified=SENDOBJPLANET;
1943 break;
1944 default:
1945 break;
1946 }
1947 break;
1948 case SENDOBJPLANET:
1949 switch(mode){
1950
1951 case SENDOBJMOD0:
1952 case SENDOBJMOD:
1953 case SENDOBJAALL:
1954 case SENDOBJALL:
1955 case SENDOBJPLANET:
1956 break;
1957 case SENDOBJSEND:
1958 obj->modified=mode;
1959 break;
1960 default:
1961 break;
1962 }
1963 break;
1964 case SENDOBJSEND:
1965 switch(mode){
1966 case SENDOBJUNMOD:
1967 obj->modified=mode;
1968 break;
1969 default:
1970 break;
1971 }
1972
1973 break;
1974 default:
1975 break;
1976 }
1977
1978 break;
1979 case PROJECTILE:
1980 switch(obj->modified){
1981
1982 case SENDOBJUNMOD:
1983 obj->modified=SENDOBJNOTSEND;
1984 break;
1985
1986 case SENDOBJNEW:
1987 switch(mode){
1988 case SENDOBJMOD0:
1989 case SENDOBJMOD:
1990 case SENDOBJAALL:
1991 case SENDOBJALL:
1992 break;
1993 case SENDOBJKILL:
1994 obj->modified=SENDOBJDEAD;
1995 break;
1996 case SENDOBJSEND:
1997 case SENDOBJDEAD:
1998 case SENDOBJNOTSEND:
1999 obj->modified=mode;
2000 break;
2001 default:
2002 return(2);
2003 break;
2004 }
2005 break;
2006
2007 case SENDOBJSEND:
2008 switch(mode){
2009 case SENDOBJDEAD:
2010 case SENDOBJSEND:
2011 case SENDOBJNOTSEND:
2012 obj->modified=mode;
2013 break;
2014 case SENDOBJUNMOD:
2015 case SENDOBJMOD0:
2016 if(obj->type==PROJECTILE){
2017 if(obj->subtype==MISSILE){
2018 obj->modified=mode;
2019 }
2020 else{
2021 return(2);
2022 }
2023 }
2024 else{
2025 obj->modified=mode;
2026 }
2027 break;
2028
2029 default:
2030 return(2);
2031 break;
2032 }
2033
2034 break;
2035
2036 case SENDOBJNOTSEND:
2037 switch(mode){
2038 case SENDOBJMOD0:
2039 case SENDOBJMOD:
2040 case SENDOBJAALL:
2041 case SENDOBJALL:
2042 break;
2043 case SENDOBJKILL:
2044 case SENDOBJDEAD:
2045 obj->state=0;
2046 obj->modified=SENDOBJDEAD;
2047 break;
2048 default:
2049 return(2);
2050 break;
2051 }
2052 break;
2053
2054 case SENDOBJDEAD:
2055 break;
2056
2057 default:
2058 break;
2059 }
2060 break;
2061
2062 /****** SHIPS AND ASTEROIDS *******************/
2063 case SHIP:
2064 case ASTEROID:
2065
2066 switch(obj->modified){
2067
2068 case SENDOBJUNMOD:
2069
2070 switch(mode){
2071 case SENDOBJUNMOD: /* HERE check what use this */
2072 obj->modified=mode;
2073 break;
2074 case SENDOBJMOD0:
2075 case SENDOBJMOD:
2076 case SENDOBJAALL:
2077 case SENDOBJALL:
2078 case SENDOBJKILL:
2079 case SENDOBJPLANET:
2080 obj->modified=mode;
2081 break;
2082 case SENDOBJSEND: /* HERE why send unmod objs */
2083 obj->modified=mode;
2084 break;
2085 default:
2086 return(2);
2087 break;
2088 }
2089
2090
2091 break;
2092 case SENDOBJMOD0:
2093 case SENDOBJMOD:
2094 case SENDOBJAALL:
2095 case SENDOBJALL:
2096 switch(mode){
2097
2098 case SENDOBJMOD0:
2099 case SENDOBJMOD:
2100 case SENDOBJAALL:
2101 case SENDOBJALL:
2102 if(obj->modified<mode){ /* HERE dangerous */
2103 obj->modified=mode;
2104 }
2105
2106 break;
2107 case SENDOBJKILL:
2108 case SENDOBJSEND:
2109 obj->modified=mode;
2110 break;
2111
2112 default:
2113 return(2);
2114 break;
2115 }
2116 break;
2117
2118 case SENDOBJKILL:
2119 switch(mode){
2120 case SENDOBJMOD0:
2121 case SENDOBJMOD:
2122 case SENDOBJAALL:
2123 case SENDOBJALL:
2124 break;
2125 case SENDOBJSEND:
2126 obj->modified=mode;
2127 break;
2128 case SENDOBJKILL:
2129 break;
2130 default:
2131 return(2);
2132 break;
2133 }
2134 break;
2135
2136 case SENDOBJNEW:
2137 switch(mode){
2138 case SENDOBJMOD0:
2139 case SENDOBJMOD:
2140 case SENDOBJAALL:
2141 case SENDOBJALL:
2142 break;
2143
2144 case SENDOBJKILL:
2145 case SENDOBJDEAD:
2146 obj->modified=SENDOBJDEAD;
2147 break;
2148 case SENDOBJSEND:
2149 obj->modified=SENDOBJSEND;
2150 break;
2151 default:
2152 return(2);
2153 break;
2154 }
2155 break;
2156
2157 case SENDOBJDEAD:
2158 switch(mode){
2159 case SENDOBJMOD0:
2160 case SENDOBJMOD:
2161 case SENDOBJAALL:
2162 case SENDOBJALL:
2163 case SENDOBJKILL:
2164 case SENDOBJNOTSEND:
2165 break;
2166 default:
2167 return(2);
2168 break;
2169 }
2170 break;
2171
2172 case SENDOBJPLANET:
2173 switch(mode){
2174 case SENDOBJSEND:
2175 obj->modified=mode;
2176 break;
2177 default:
2178 return(2);
2179 break;
2180 }
2181 break;
2182
2183 case SENDOBJSTR: /* HERE this line is reached ?? */
2184 switch(mode){
2185 case SENDOBJSEND:
2186 obj->modified=mode;
2187 break;
2188 default:
2189 return(2);
2190 break;
2191 }
2192 break;
2193
2194 case SENDOBJSEND:
2195 switch(mode){
2196 case SENDOBJUNMOD:
2197 case SENDOBJDEAD:
2198 case SENDOBJSEND:
2199 case SENDOBJNOTSEND:
2200 obj->modified=mode;
2201 break;
2202 default:
2203 return(2);
2204 break;
2205 }
2206 break;
2207 case SENDOBJNOTSEND:
2208 switch(mode){
2209 case SENDOBJMOD0:
2210 case SENDOBJMOD:
2211 case SENDOBJAALL:
2212 case SENDOBJALL:
2213 break;
2214 case SENDOBJKILL:
2215 case SENDOBJDEAD:
2216 obj->modified=SENDOBJDEAD;
2217 break;
2218 case SENDOBJNOTSEND:
2219 break;
2220 default:
2221 return(2);
2222 break;
2223 }
2224 break;
2225 default:
2226 fprintf(stderr,"SetModified(): ERROR: obj mode %d not known\n",
2227 obj->modified);
2228 exit(-1);
2229 break;
2230 }
2231 break;
2232 default:
2233 break;
2234 }
2235
2236 if(swmod){
2237 fprintf(stdout,"\t SetModified(): obj %d modified: to %d mode: %d time: %d\n",
2238 obj->id,
2239 obj->modified,mode,GetTime());
2240 }
2241
2242 return(sw);
2243 }
2244
SetModifiedAll(struct HeadObjList * lh,int type,int mode,int force)2245 int SetModifiedAll(struct HeadObjList *lh,int type,int mode,int force){
2246 /*
2247 Reset the modified variable on all objects of type type to mode mode
2248 return the number of objects modified
2249 */
2250
2251 struct ObjList *ls;
2252 int n=0;
2253 int proc=0;
2254
2255
2256 proc=GetProc();
2257 ls=lh->list;
2258 while(ls!=NULL){
2259 if(proc!=players[ls->obj->player].proc){ls=ls->next;continue;}
2260
2261 if(ls->obj->type==type || type==ALLOBJS){
2262 if(force==TRUE){
2263 ls->obj->modified=mode;
2264 }
2265 else{
2266 SetModified(ls->obj,mode);
2267 }
2268 n++;
2269
2270 }
2271 ls=ls->next;
2272 }
2273 return(n);
2274 }
2275
2276
CheckModifiedPre(struct HeadObjList * lh,int proc)2277 int CheckModifiedPre(struct HeadObjList *lh,int proc){
2278 /*
2279 Check the modified parameter of all the objects.
2280 return number of objects modified.
2281 */
2282
2283 struct ObjList *ls;
2284 Object *obj;
2285 int n=0;
2286
2287
2288 ls=lh->list;
2289 while(ls!=NULL){
2290 obj=ls->obj;
2291
2292 if(proc!=players[obj->player].proc){
2293 ls=ls->next;continue;
2294 }
2295
2296 switch(obj->type){
2297
2298 case PROJECTILE:
2299 case ASTEROID:
2300 case SHIP:
2301
2302 if(obj->type==PROJECTILE){
2303
2304 if(obj->subtype!=MISSILE){
2305 if(obj->modified!=SENDOBJNEW &&
2306 obj->modified!=SENDOBJNOTSEND &&
2307 obj->modified!=SENDOBJDEAD){
2308 SetModified(obj,SENDOBJNOTSEND);
2309 }
2310 }
2311 }
2312
2313 switch(obj->modified){
2314 case SENDOBJUNMOD:
2315 if(obj->x!=obj->x0 || obj->y!=obj->y0 || obj->ang_v!=0){
2316 SetModified(obj,SENDOBJMOD);
2317 n++;
2318 }
2319 if(obj->state<=0){
2320 SetModified(obj,SENDOBJKILL);
2321 n++;
2322 }
2323 break;
2324 case SENDOBJMOD0:
2325 case SENDOBJMOD:
2326 case SENDOBJALL:
2327 case SENDOBJAALL:
2328 if(obj->state<=0){
2329 SetModified(obj,SENDOBJKILL);
2330 n++;
2331 }
2332 break;
2333 case SENDOBJNEW:
2334 if(obj->state<=0){
2335 SetModified(obj,SENDOBJDEAD);/* don't send */
2336 n++;
2337 }
2338 break;
2339 case SENDOBJKILL:
2340 obj->state=0;
2341 break;
2342 case SENDOBJDEAD:
2343 obj->state=0;
2344 break;
2345 case SENDOBJNOTSEND:
2346 if(obj->state<=0){
2347 SetModified(obj,SENDOBJDEAD);/* don't send */
2348 n++;
2349 }
2350 break;
2351 default:
2352 fprintf(stderr,"CheckModifiedPre() mode %d not implemented. Exiting...\n",obj->modified);
2353 exit(-1);
2354 break;
2355 }
2356 break;
2357 case PLANET:
2358 if(obj->ttl<=0)SetModified(obj,SENDOBJPLANET);
2359 break;
2360 case TRACE:
2361 break;
2362 default:
2363 fprintf(stdout,"Warning:CheckModifiedPre() must no reach this line\n");
2364 break;
2365 }
2366 ls=ls->next;
2367 }
2368 return n;
2369 }
2370
2371
CheckModifiedPost(struct HeadObjList * lh,int proc)2372 int CheckModifiedPost(struct HeadObjList *lh,int proc){
2373 /*
2374 version 01 27Dic2010
2375 Checking after send objects.
2376 Set modified parameter from SEND to UNMOD, DEAD, NOTSEND
2377 return number of objects modified.
2378 */
2379
2380 struct ObjList *ls;
2381 Object *obj;
2382 int n=0;
2383
2384
2385 ls=lh->list;
2386 while(ls!=NULL){
2387 obj=ls->obj;
2388
2389 if(obj->life<=0)obj->state=0;
2390 if(obj->modified==SENDOBJDEAD)obj->state=0;
2391
2392 if(obj->state<=0){
2393 if(obj->modified==SENDOBJSEND || obj->modified==SENDOBJNOTSEND){
2394 obj->modified=SENDOBJDEAD;
2395 }
2396 }
2397
2398 if(proc!=players[obj->player].proc){
2399 if(obj->type==PROJECTILE){ /* HERE not neccesary */
2400 if(obj->state<=0){
2401 SetModified(obj,SENDOBJDEAD);
2402 }
2403 }
2404 ls=ls->next;continue;
2405 }
2406
2407 switch(obj->type){
2408 case SHIP:
2409 case ASTEROID:
2410 case PROJECTILE:
2411 switch(obj->modified){
2412 case SENDOBJUNMOD:
2413 case SENDOBJMOD0:
2414 case SENDOBJMOD:
2415 case SENDOBJALL:
2416 case SENDOBJAALL:
2417 case SENDOBJNEW:
2418 case SENDOBJKILL:
2419 case SENDOBJDEAD:
2420 break;
2421 case SENDOBJSEND:
2422 if(obj->state>0){
2423 if(obj->type==PROJECTILE){
2424 if(obj->subtype!=MISSILE){
2425 SetModified(obj,SENDOBJNOTSEND); /* projectiles are send only once */
2426 n++;
2427 }
2428 else{
2429 SetModified(obj,SENDOBJUNMOD);
2430 n++;
2431 }
2432 }
2433 else{
2434 SetModified(obj,SENDOBJUNMOD);
2435 n++;
2436 }
2437 }
2438 else{
2439 SetModified(obj,SENDOBJDEAD);
2440 n++;
2441 }
2442 break;
2443 case SENDOBJNOTSEND:
2444 if(obj->state<=0 || obj->life<=0){
2445 SetModified(obj,SENDOBJDEAD);/* remove it */
2446 n++;
2447 }
2448 break;
2449 default:
2450 fprintf(stderr,"CheckModifiedPost() mode %d not implemented\n",obj->modified);
2451 exit(-1);
2452 break;
2453 }
2454 break;
2455 case PLANET:
2456 if(obj->modified==SENDOBJSEND){
2457 SetModified(obj,SENDOBJUNMOD);
2458 obj->sw=0;
2459 n++;
2460 }
2461 break;
2462 case TRACE:
2463 break;
2464 default:
2465 fprintf(stdout,"Warning:CheckModifiedPost() must no reach this line\n");
2466 break;
2467 }
2468
2469 ls=ls->next;
2470 }
2471 return n;
2472 }
2473
2474
Setttl0(struct HeadObjList * lh)2475 void Setttl0(struct HeadObjList *lh){
2476 /*
2477 version 01 (031210)
2478 All ships with ttl <=0 will be send.
2479 If the object must be send, set ttl to 0
2480 if it must not be never send, set ttl to 1024
2481
2482 SERVER:
2483 Send near enemies. Reasign its ttl.
2484 send allies if ttl<=0.
2485
2486 CLIENT:
2487 send ships with ttl<=0.
2488
2489 return:
2490 void
2491 */
2492
2493 struct ObjList *ls;
2494 Object *obj=NULL;
2495 int proc,gmode,gcooperative,otherproc, genemyknown;
2496 int sw;
2497
2498 proc=GetProc();
2499 gmode=GameParametres(GET,GMODE,0);
2500 gcooperative=GameParametres(GET,GCOOPERATIVE,0);
2501 genemyknown=GameParametres(GET,GENEMYKNOWN,0);
2502
2503 ls=lh->list;
2504 while(ls!=NULL){
2505 if(proc!=players[ls->obj->player].proc){
2506 ls=ls->next;continue;
2507 }
2508 obj=ls->obj;
2509
2510 if(obj->type==PROJECTILE && obj->subtype==EXPLOSION){
2511 obj->ttl=1024; /* explosion never are send */
2512
2513 if(obj->modified!=SENDOBJNOTSEND){
2514 SetModified(obj,SENDOBJNOTSEND);
2515 }
2516 ls=ls->next;continue;
2517 }
2518
2519 /* ttl code */
2520 switch(gmode){
2521 case SERVER:
2522 /* server */
2523 /* send data if an ship of another proccesor is near */
2524 sw=0;
2525 switch (obj->type){
2526 case PROJECTILE:
2527 case ASTEROID:
2528 case SHIP:
2529
2530 if(obj->ttl<=0){ /* objects ready to send */
2531 sw=1;
2532
2533 if(gcooperative==TRUE && players[obj->player].control==HUMAN){
2534 /* send human controled ships periodically */
2535 if(obj->habitat==H_SPACE){
2536 SetModified(obj,SENDOBJMOD0);
2537 obj->ttl=0;
2538 sw=0;
2539 }
2540 if(obj->ttl<=MINTTL){/* send now */
2541 obj->ttl=0;
2542 sw=0;
2543 }
2544 }
2545 if(genemyknown){
2546 /* if enemy is known send ships in outer space periodically */
2547 if(obj->habitat==H_SPACE){
2548 SetModified(obj,SENDOBJMOD0);
2549 obj->ttl=0;
2550 sw=0;
2551 }
2552 if(obj->ttl<=MINTTL){/* send now */
2553 obj->ttl=0;
2554 sw=0;
2555 }
2556 }
2557
2558 if(sw){ /* reassign ttl */
2559 otherproc=OtherProc(lh,proc,obj); /* double buffer */
2560 switch(otherproc){ /* */
2561 case 0: /* (4r,inf) r: radar range*/
2562 obj->ttl=150+obj->id%20; /* (90) don't send */
2563 break;
2564 case 1: /* (3r,4r) */
2565 obj->ttl=58+obj->id%12; /* don't send */
2566 break;
2567 case 2: /* (1.5r,3r) */
2568 obj->ttl=16; /* don't send */
2569 break;
2570 case 3: /* (900p,1.5r) */
2571 if(obj->ttl<0){
2572 obj->ttl=-8; /* send */
2573 SetModified(obj,SENDOBJMOD0);
2574 }
2575 break;
2576 case 4: /* (0,900p) */
2577 if(obj->type==SHIP && obj->subtype==PILOT && obj->mode==LANDED){
2578 /* less than zero tll means: send now and set ttl to -ttl (in Settl())*/
2579 obj->ttl=-(90+obj->id%20);
2580 SetModified(obj,SENDOBJMOD0);
2581 }
2582 else{
2583 obj->ttl=0;
2584 SetModified(obj,SENDOBJMOD);
2585 }
2586 break;
2587 case 5:
2588 obj->ttl=-(90+obj->id%20);
2589 SetModified(obj,SENDOBJMOD0);
2590 break;
2591 default:
2592 obj->ttl=0;
2593 SetModified(obj,SENDOBJMOD);
2594 break;
2595 }
2596 }
2597 }
2598 break;
2599
2600 case PLANET:
2601 break;
2602
2603 default:
2604 break;
2605 }
2606
2607 break;
2608 case CLIENT:
2609 /* if(obj->type==SHIP && obj->subtype==PILOT && obj->mode==LANDED){ */
2610 /* obj->ttl=-(90+obj->id%20); */
2611 /* } */
2612 break;
2613 default:
2614 /* PRODUCTION */
2615 fprintf(stderr,"ERROR 1 :setttl0() gmode %d unknown, mode: %d, obj type: %d player: %d id: %d pid: %d\n",
2616 gmode,obj->modified,obj->type,obj->player,obj->id,obj->pid);
2617 /* exit(-1); */
2618 break;
2619 }
2620
2621 /* --ttl code */
2622
2623 if(obj->ttl<=0){
2624 SetModified(obj,SENDOBJMOD0);
2625 }
2626
2627 switch (obj->modified){
2628 case SENDOBJUNMOD:
2629 case SENDOBJMOD0: /* Object modified send only position */
2630 case SENDOBJMOD: /* Object modified */
2631 case SENDOBJAALL:
2632
2633 break;
2634 case SENDOBJSEND: /* just sended HERE must not happen BUG[96] ignoring*/
2635 fprintf(stderr,"ERROR 2 :setttl0() mode %d unknown, obj type: %d player: %d id: %d pid: %d proc: %d\n",
2636 obj->modified,obj->type,obj->player,obj->id,obj->pid,players[obj->player].proc);
2637 break;
2638 /* Send this now */
2639 case SENDOBJALL:
2640 case SENDOBJKILL: /* send these objects */
2641 case SENDOBJNEW: /* new object. */
2642 case SENDOBJPLANET:
2643 case SENDOBJSTR:
2644 obj->ttl=0;
2645 break;
2646 case SENDOBJNOTSEND: /* don't send these objects*/
2647 case SENDOBJDEAD:
2648 obj->ttl=1024; /* don't send dead objects */
2649 break;
2650 default:
2651 /* PRODUCTION Quitar el exit ignorar?? */
2652 fprintf(stderr,"ERROR 3 :setttl0() mode %d unknown, obj type: %d player: %d id: %d pid: %d proc: %d\n",
2653 obj->modified,obj->type,obj->player,obj->id,obj->pid,players[obj->player].proc);
2654 /* exit(-1); */
2655 break;
2656 }
2657 ls=ls->next;
2658 }
2659 return;
2660 }
2661
2662
Setttl(struct HeadObjList * lh,int n)2663 void Setttl(struct HeadObjList *lh,int n){
2664 /*
2665 version 0.1
2666 Adjust ttl parameter used to decide what object send:
2667 if ttl == 0 object is just sended (modified must be SENDOBJSEND).
2668 input param n:
2669 if n>=0 all objects ttl is set to n
2670
2671 SERVER:
2672 ally ships: Reasign its ttl.
2673 send planets periodically.
2674
2675 CLIENT:
2676 ships: Reasign its ttl.
2677 send planets periodically.
2678
2679
2680 return:
2681 void
2682 */
2683
2684 struct ObjList *ls;
2685 Object *obj=NULL;
2686 int proc;
2687 int otherproc;
2688 int gcooperative;
2689 int genemyknown;
2690
2691 proc=GetProc();
2692 gcooperative=GameParametres(GET,GCOOPERATIVE,0);
2693 genemyknown=GameParametres(GET,GENEMYKNOWN,0);
2694
2695 if(n>=0){ /* all objects are set to ttl=n */
2696 ls=lh->list;
2697 while(ls!=NULL){
2698 if(proc!=players[ls->obj->player].proc){
2699 ls=ls->next;continue;
2700 }
2701 ls->obj->ttl=n;
2702 ls=ls->next;
2703 }
2704 return;
2705 } /*--n<0 */
2706
2707
2708 ls=lh->list;
2709 while(ls!=NULL){
2710
2711 if(proc!=players[ls->obj->player].proc){
2712 ls=ls->next;continue;
2713 }
2714 obj=ls->obj;
2715
2716 if(obj->ttl<=0){ /* objects just sended */
2717 if(obj->ttl<=-4){
2718 obj->ttl=-obj->ttl;
2719 ls=ls->next;continue;
2720 }
2721
2722
2723 switch (obj->type){
2724 case PROJECTILE:
2725 case ASTEROID:
2726 case SHIP:
2727
2728 /* only calc ttl for computer controled ships */
2729 if((gcooperative==TRUE && players[obj->player].control==HUMAN)|| genemyknown){
2730
2731 otherproc=OtherProc(lh,proc,obj);
2732 switch(otherproc){ /* */
2733
2734 case 0: /* (4r,inf) */
2735 obj->ttl=150+obj->id%20; /* (old value: 90)*/
2736 if(obj->mode==LANDED && obj->type==SHIP && obj->subtype==TOWER)obj->ttl*=2;
2737 break;
2738 case 1: /* (3r,4r) */
2739 obj->ttl=56+obj->id%20;
2740 if(obj->mode==LANDED && obj->type==SHIP && obj->subtype==TOWER)obj->ttl*=2;
2741 break;
2742 case 2: /* (1.5r,3r) */
2743 obj->ttl=32;
2744 if(obj->mode==LANDED && obj->type==SHIP && obj->subtype==TOWER)obj->ttl*=2;
2745 break;
2746 case 3: /* (900p,1.5r) */
2747 obj->ttl=16; /* 8 */
2748 if(obj->mode==LANDED && obj->type==SHIP && obj->subtype==TOWER)obj->ttl*=2;
2749 break;
2750 case 4: /* (0,900p) */
2751 if(obj->type==SHIP && obj->subtype==PILOT && obj->mode==LANDED){
2752 obj->ttl=(90+obj->id%20);
2753 }
2754 else{
2755 obj->ttl=2;/* 0 */
2756 if(obj->mode==LANDED)obj->ttl=8;
2757 /* SetModified(obj,SENDOBJMOD); */
2758 }
2759 break;
2760 case 5:
2761 obj->ttl=(150+obj->id%20); /* old value: 90*/
2762 if(obj->mode==LANDED && obj->type==SHIP && obj->subtype==TOWER)obj->ttl*=2;
2763 break;
2764 default:
2765 break;
2766 }
2767 }
2768 break;
2769 case PLANET:
2770 obj->ttl=400+(obj->id%100);
2771 break;
2772 default:
2773 break;
2774 }
2775 }
2776 ls=ls->next;
2777 }
2778 return;
2779 }
2780
2781
LoadBuffer(int order,struct Buffer * buffer,int mode)2782 void LoadBuffer(int order,struct Buffer *buffer,int mode){
2783 /*
2784 version 01
2785 */
2786
2787 struct MessageHeader messh;
2788 int i;
2789 int nkp;
2790 int proc;
2791 struct IntList *list;
2792 int fd;
2793
2794 if(buffer==NULL)return;
2795
2796 buffer->n=0; /* reset buffer */
2797
2798 proc=GetProc();
2799
2800 /* main header */
2801
2802 messh.id=order;
2803 messh.nobjs=0;
2804 messh.nbytes=0;
2805 CopyMessHeader2Buffer(buffer,&messh);
2806
2807 /* rest of data */
2808
2809 switch(mode){
2810
2811
2812 /******* SERVER *******************/
2813 case SERVER:
2814
2815 switch(order){
2816 case OTSENDPING: /* not used */
2817 break;
2818 case OTSENDOBJS: /* send modified objects */
2819 CopyObjs2Buffer(buffer,listheadobjs);
2820 break;
2821 case OTSENDSAVE: /* sendallobjects */
2822
2823 break;
2824 case OTSENDLOAD: /* load a game */
2825
2826 fprintf(stdout,"LOAD\n");
2827
2828 /* checking the file */
2829 if((fd=open(savefile,O_RDONLY))==-1){
2830 fprintf(stdout,"CommServer()[OTSENDLOAD]: Can't open the file: %s\n",savefile);
2831 exit(-1);
2832 }
2833 close(fd);
2834
2835 break;
2836 case OTSENDKILL: /* kill client */
2837
2838 /* OK */
2839 break;
2840 case OTSENDEND: /* no more messages */
2841 break;
2842 default:
2843 break;
2844 }
2845 break;
2846
2847
2848 /******* CLIENT *******************/
2849 case CLIENT:
2850 switch(order){
2851 case OTSENDPING: /* not used */
2852 break;
2853 case OTSENDOBJS: /* send modified objects */
2854 CopyObjs2Buffer(buffer,listheadobjs);
2855 break;
2856 case OTSENDSAVE: /* sendallobjects */
2857 /* objects */
2858 CopyObjs2Buffer(buffer,listheadobjs);
2859
2860 /* global variables */
2861 messh.id=SENDGLOBAL;
2862 messh.nobjs=0;
2863 messh.nbytes=0;
2864 CopyMessHeader2Buffer(buffer,&messh);
2865
2866 CopyGlobal2Buffer(buffer);
2867
2868 /* Loading buffer with known sectors and planets */
2869 for(i=0;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
2870 if(proc!=players[i].proc)continue;
2871
2872
2873 /* player */
2874
2875 messh.id=SENDPLAYER;
2876 messh.nobjs=0;
2877 messh.nbytes=0;
2878
2879 CopyMessHeader2Buffer(buffer,&messh);
2880
2881 CopyPlayer2Buffer(buffer,&players[i]);
2882
2883 /* list of planets */
2884
2885 /* header */
2886 nkp=CountIntList(players[i].kplanets);
2887 messh.id=SENDPLANETLIST;
2888 messh.nobjs=nkp;
2889 messh.nbytes=0;
2890 CopyMessHeader2Buffer(buffer,&messh);
2891
2892 CopyInt2Buffer(buffer,&i);
2893
2894 if(nkp>0){
2895 list=players[i].kplanets;
2896
2897 /* planets id */
2898 while(list!=NULL){
2899 CopyInt2Buffer(buffer,&(list->id));
2900 list=list->next;
2901 }
2902 }
2903
2904 /* list of sectors */
2905 /* header */
2906 messh.id=SENDSECTORLIST;
2907 messh.nobjs=players[i].ksectors.n;
2908 messh.nbytes=0;
2909
2910 CopyMessHeader2Buffer(buffer,&messh);
2911
2912 CopyInt2Buffer(buffer,&i);
2913
2914 if(players[i].ksectors.n>0){
2915 list=players[i].ksectors.list;
2916 while(list!=NULL){
2917 CopyInt2Buffer(buffer,&(list->id));
2918 list=list->next;
2919 }
2920 }
2921 }
2922 /* --Loading buffer with known sectors and planets */
2923
2924 /* ending message */
2925
2926 messh.id=SENDEND;
2927 messh.nobjs=0;
2928 messh.nbytes=0;
2929 CopyMessHeader2Buffer(buffer,&messh);
2930 break;
2931 case OTSENDLOAD: /* load a game */
2932 /* ok */
2933 break;
2934 case OTSENDKILL: /* kill client */
2935
2936 /* OK */
2937 break;
2938 case OTSENDEND: /* no more messages */
2939 break;
2940 default:
2941 break;
2942 }
2943 break;
2944 }
2945 }
2946
2947
ServerProcessBuffer(struct Buffer * buffer)2948 int ServerProcessBuffer(struct Buffer *buffer){
2949 struct MessageHeader mess;
2950 char *buf;
2951 int nbytes;
2952 int order;
2953 int i;
2954
2955 int id;
2956 struct Player *player;
2957 struct PlayerAll playerall;
2958
2959 int playerid;
2960 int nkp,nks;
2961 int gkplanets;
2962 struct IntList *kp;
2963 struct HeadIntIList ks;
2964
2965 gkplanets=GameParametres(GET,GKPLANETS,0);
2966
2967 nbytes=sizeof(struct MessageHeader);
2968
2969 buf=buffer->data;
2970 memcpy(&mess,buf,nbytes);
2971 order=mess.id;
2972 buf+=nbytes;
2973
2974 switch(order){
2975 case OTSENDPING:
2976 break;
2977 case OTSENDOBJS: /* send modified objects */
2978 ReadObjsfromBuffer(buf);
2979 break;
2980 case OTSENDSAVE: /* sendallobjects */
2981 nbytes=ReadObjsfromBuffer(buf);
2982 buf+=nbytes;
2983
2984 do{
2985 nbytes=sizeof(struct MessageHeader);
2986 memcpy(&mess,buf,nbytes);
2987 order=mess.id;
2988 buf+=nbytes;
2989
2990 switch(order){
2991 case SENDGLOBAL:
2992
2993 nbytes=sizeof(struct Global);
2994 memcpy(&gclient,buf,nbytes);
2995
2996 buf+=nbytes;
2997 break;
2998
2999 case SENDPLAYER:
3000 nbytes=sizeof(struct PlayerAll);
3001 memcpy(&playerall,buf,nbytes);
3002 buf+=nbytes;
3003 player=&players[playerall.id];
3004
3005 /* DelIntIList(&(players[playerall.id].ksectors)); */
3006 kp=player->kplanets;
3007 memcpy(&ks,&player->ksectors,sizeof(struct HeadIntIList));
3008
3009
3010 strncpy(player->playername,playerall.playername,MAXTEXTLEN);
3011 player->id=playerall.id;
3012 player->pid=playerall.pid;
3013 player->proc=playerall.proc;
3014 player->control=playerall.control;
3015 player->team=playerall.team;
3016 player->profile=playerall.profile;
3017 player->strategy=playerall.strategy;
3018 player->gmaxlevel=playerall.gmaxlevel;
3019 player->maxlevel=playerall.maxlevel;
3020 player->color=playerall.color;
3021 player->cv=playerall.cv;
3022 player->nplanets=playerall.nplanets;
3023 player->nships=playerall.nships;
3024 player->nbuildships=playerall.nbuildships;
3025 player->gold=playerall.gold;
3026 player->balance=playerall.balance;
3027 player->lastaction=playerall.lastaction;
3028 player->ndeaths=playerall.ndeaths;
3029 player->nkills=playerall.nkills;
3030 player->points=playerall.points;
3031 player->modified=playerall.modified;
3032 player->ttl=playerall.ttl;
3033
3034
3035 players[playerall.id].kplanets=kp;
3036 memcpy(&players[playerall.id].ksectors,&ks,sizeof(struct HeadIntIList));
3037
3038 break;
3039
3040 case SENDPLANETLIST:
3041 nkp=mess.nobjs;
3042
3043 memcpy(&playerid,buf,sizeof(int));
3044 buf+=sizeof(int);
3045
3046 fprintf(stdout,"\trecv PLAYER: %d\n",playerid);
3047
3048 DelIntList((players[playerid].kplanets));
3049 players[playerid].kplanets=NULL;/*kp; */
3050
3051 for(i=0;i<nkp;i++){
3052 memcpy(&id,buf,sizeof(int));
3053 buf+=sizeof(int);
3054 players[playerid].kplanets=Add2IntList((players[playerid].kplanets),id);
3055 }
3056 break;
3057
3058 case SENDSECTORLIST:
3059 nks=mess.nobjs;
3060 /* copying sectors ids to buffer*/
3061
3062 memcpy(&playerid,buf,sizeof(int));
3063 buf+=sizeof(int);
3064
3065 players[playerid].ksectors.n=0;
3066 players[playerid].ksectors.n0=0;
3067 players[playerid].ksectors.list=NULL;
3068 for(i=0;i<NINDEXILIST;i++){
3069 players[playerid].ksectors.index[i]=NULL;
3070 }
3071
3072 for(i=0;i<nks;i++){
3073 memcpy(&id,buf,sizeof(int));
3074 buf+=sizeof(int);
3075 if(gkplanets==FALSE){
3076 Add2IntIList(&(players[playerid].ksectors),id);
3077 }
3078 }
3079 break;
3080 case SENDEND:
3081 break;
3082 default:
3083 fprintf(stderr,"ERROR in ServerProcessBuffer() order %d unknown\n",order);
3084 exit(-1);
3085
3086 break;
3087 }
3088
3089 }while(order!=SENDEND);
3090 break;
3091
3092 case OTSENDLOAD: /* load game */
3093 break;
3094 case OTSENDKILL: /* kill client */
3095 return(order);
3096 break;
3097 case OTSENDEND: /* no more messages */
3098 break;
3099 default:
3100 fprintf(stderr,"ERROR unknown message header id:%d\n",order);
3101 exit(-1);
3102 break;
3103 }
3104 return(0);
3105 }
3106
3107
ClientProcessBuffer(struct Buffer * buffer)3108 int ClientProcessBuffer(struct Buffer *buffer){
3109 struct MessageHeader mess;
3110 char *buf;
3111 int nbytes;
3112 int order;
3113
3114
3115 nbytes=sizeof(struct MessageHeader);
3116
3117 buf=buffer->data;
3118 memcpy(&mess,buf,nbytes);
3119 order=mess.id;
3120 buf+=nbytes;
3121
3122 switch(order){
3123 case OTSENDPING:
3124 break;
3125 case OTSENDOBJS: /* send modified objects */
3126 ReadObjsfromBuffer(buf);
3127 break;
3128 case OTSENDSAVE: /* sendallobjects */
3129 break;
3130 case OTSENDLOAD: /* load game */
3131 return(0);
3132 break;
3133 case OTSENDKILL: /* kill client */
3134 return(order);
3135 break;
3136 case OTSENDEND: /* no more messages */
3137 break;
3138 default:
3139 fprintf(stderr,"ERROR ClientProcessBuffer():unknown message header id:%d\n",order);
3140 exit(-1);
3141 break;
3142 }
3143 return(0);
3144 }
3145
CopyMessHeader2Buffer(struct Buffer * buffer,struct MessageHeader * messh)3146 int CopyMessHeader2Buffer(struct Buffer *buffer, struct MessageHeader *messh){
3147 int nbytes;
3148
3149 nbytes=sizeof(struct MessageHeader);
3150 if(buffer->n+nbytes>buffer->size){
3151 int newsize;
3152 newsize=buffer->size+1024;
3153 buffer->data=realloc(buffer->data,newsize*sizeof(char));
3154 if(buffer->data==NULL){
3155 fprintf(stderr,"ERROR in malloc Copyfile2Buf()\n");
3156 exit(-1);
3157 }
3158 buffer->size=newsize;
3159 }
3160
3161 memcpy(buffer->data+buffer->n,messh,nbytes);
3162 buffer->n+=nbytes;
3163 return(nbytes);
3164 }
3165
CopyGlobal2Buffer(struct Buffer * buffer)3166 int CopyGlobal2Buffer(struct Buffer *buffer){
3167 /*
3168 copy the global game variables to buffer buf
3169 */
3170 struct Global global;
3171 int nbytes;
3172 int i;
3173
3174 global.actual_player=actual_player0;
3175 global.g_objid=g_objid;
3176 global.g_projid=g_projid;
3177 global.ship_c=0;
3178 if(ship_c!=NULL)
3179 global.ship_c=ship_c->id;
3180 global.cv=0;
3181 if(cv!=NULL){
3182 global.cv=cv->id;
3183 }
3184 global.habitat_type=habitat.type;
3185 global.habitat_id=0;
3186 /* global.habitat_pid=0; */
3187 if(habitat.obj!=NULL){
3188 global.habitat_id=habitat.obj->id;
3189 /* global.habitat_pid=habitat.obj->id; */
3190 }
3191 for(i=0;i<4;i++){
3192 global.fobj[i]=fobj[i];
3193 }
3194
3195 nbytes=sizeof(struct Global);
3196
3197
3198 if(buffer->n+nbytes>buffer->size){
3199 int newsize;
3200 newsize=buffer->size+1024;
3201 buffer->data=realloc(buffer->data,newsize*sizeof(char));
3202 if(buffer->data==NULL){
3203 fprintf(stderr,"ERROR in malloc Copyfile2Buf()\n");
3204 exit(-1);
3205 }
3206 buffer->size=newsize;
3207 }
3208
3209 memcpy(buffer->data+buffer->n,&global,nbytes);
3210 buffer->n+=nbytes;
3211 return (nbytes);
3212 }
3213
CopyPlayer2Buffer(struct Buffer * buffer,struct Player * player)3214 int CopyPlayer2Buffer(struct Buffer *buffer, struct Player *player){
3215 int nbytes;
3216 struct PlayerAll *playerall;
3217
3218 nbytes=sizeof(struct PlayerAll);
3219 if(buffer->n+nbytes>buffer->size){
3220 int newsize;
3221 newsize=buffer->size+1024;
3222 buffer->data=realloc(buffer->data,newsize*sizeof(char));
3223 if(buffer->data==NULL){
3224 fprintf(stderr,"ERROR in malloc Copyfile2Buf()\n");
3225 exit(-1);
3226 }
3227 buffer->size=newsize;
3228 }
3229
3230
3231 playerall=(struct PlayerAll *)(buffer->data+buffer->n);
3232
3233 strncpy(playerall->playername,player->playername,MAXTEXTLEN);
3234
3235 playerall->id=player->id;
3236 playerall->pid=player->pid;
3237 playerall->proc=player->proc;
3238 playerall->control=player->control;
3239 playerall->team=player->team;
3240 playerall->profile=player->profile;
3241 playerall->strategy=player->strategy;
3242 playerall->gmaxlevel=player->gmaxlevel;
3243 playerall->maxlevel=player->maxlevel;
3244 playerall->color=player->color;
3245 playerall->cv=player->cv;
3246 playerall->nplanets=player->nplanets;
3247 playerall->nships=player->nships;
3248 playerall->nbuildships=player->nbuildships;
3249 playerall->gold=player->gold;
3250 playerall->balance=player->balance;
3251 playerall->lastaction=player->lastaction;
3252 playerall->ndeaths=player->ndeaths;
3253 playerall->nkills=player->nkills;
3254 playerall->points=player->points;
3255 playerall->modified=player->modified;
3256 playerall->ttl=player->ttl;
3257
3258 buffer->n+=nbytes;
3259 return(nbytes);
3260 }
3261
3262
CopyPlayerMod2Buffer(struct Buffer * buffer,struct Player * player)3263 int CopyPlayerMod2Buffer(struct Buffer *buffer, struct Player *player){
3264 int nbytes;
3265
3266 struct PlayerMod pmod;
3267
3268 nbytes=sizeof(struct PlayerMod);
3269
3270 if(buffer->n+nbytes>buffer->size){
3271 int newsize;
3272 newsize=buffer->size+1024;
3273 buffer->data=realloc(buffer->data,newsize*sizeof(char));
3274 if(buffer->data==NULL){
3275 fprintf(stderr,"ERROR in malloc Copyfile2Buf()\n");
3276 exit(-1);
3277 }
3278 buffer->size=newsize;
3279 }
3280
3281 pmod.id=player->id;
3282 pmod.gmaxlevel=player->gmaxlevel;
3283 pmod.maxlevel=player->maxlevel;
3284 pmod.nplanets=player->nplanets;
3285 pmod.nships=player->nships;
3286 pmod.nbuildships=player->nbuildships;
3287 pmod.gold=player->gold;
3288 pmod.ndeaths=player->ndeaths;
3289 pmod.nkills=player->nkills;
3290 pmod.points=player->points;
3291
3292 memcpy(buffer->data+buffer->n,&pmod,nbytes);
3293 buffer->n+=nbytes;
3294 return(nbytes);
3295 }
3296
3297
CopyOrder2Buffer(struct Buffer * buffer,struct Order * order)3298 int CopyOrder2Buffer(struct Buffer *buffer, struct Order *order){
3299 int nbytes;
3300
3301 nbytes=sizeof(struct Order);
3302 if(buffer->n+nbytes>buffer->size){
3303 int newsize;
3304 newsize=buffer->size+1024;
3305 buffer->data=realloc(buffer->data,newsize*sizeof(char));
3306 if(buffer->data==NULL){
3307 fprintf(stderr,"ERROR in malloc Copyfile2Buf()\n");
3308 exit(-1);
3309 }
3310 buffer->size=newsize;
3311 }
3312
3313 memcpy(buffer->data+buffer->n,order,nbytes);
3314 buffer->n+=nbytes;
3315 return(nbytes);
3316 }
3317
3318
3319
CopyInt2Buffer(struct Buffer * buffer,int * i)3320 int CopyInt2Buffer(struct Buffer *buffer,int *i){
3321 int nbytes;
3322
3323 nbytes=sizeof(int);
3324 if(buffer->n+nbytes>buffer->size){
3325 int newsize;
3326 newsize=buffer->size+1024;
3327 buffer->data=realloc(buffer->data,newsize*sizeof(char));
3328 if(buffer->data==NULL){
3329 fprintf(stderr,"ERROR in malloc Copyfile2Buf()\n");
3330 exit(-1);
3331 }
3332 buffer->size=newsize;
3333 }
3334
3335 memcpy(buffer->data+buffer->n,i,nbytes);
3336 buffer->n+=nbytes;
3337 return(nbytes);
3338
3339 }
3340
AddObjOrders2Buffer(struct Buffer * buffer,Object * obj)3341 int AddObjOrders2Buffer(struct Buffer *buffer,Object *obj){
3342 /*
3343 version01 (021210)
3344 Add the orders of the object *obj to buffer
3345 returns:
3346 the number of bytes writed.
3347 */
3348 struct OrderList *lo;
3349 int norders=0;
3350 int nbytes,tbytes;
3351 int i,n,no;
3352
3353
3354 tbytes=0;
3355
3356 n=0; /* counting n. of orders. */
3357 lo=obj->lorder;
3358 while(lo!=NULL){
3359 n++;
3360 lo=lo->next;
3361 }
3362
3363 no=obj->norder;
3364 if(no!=n){
3365 fprintf(stderr,"ERROR SendPlayerOrders(): number of orders don't match norder\n" );
3366 fprintf(stderr,"\tnor: %d norder: %d \n",n,obj->norder);
3367 exit(-1);
3368 }
3369
3370 nbytes=sizeof(int); /* number of orders */
3371 CopyInt2Buffer(buffer,&n);
3372 tbytes+=nbytes;
3373
3374 /* list of orders */
3375 lo=obj->lorder;
3376 i=0;
3377 while(lo!=NULL){
3378 nbytes=sizeof(struct Order);
3379 CopyOrder2Buffer(buffer,&lo->order);
3380 tbytes+=nbytes;
3381 norders++;
3382 i++;
3383
3384 lo=lo->next;
3385 }
3386 if(i!=n){
3387 fprintf(stderr,"ERROR SendPlayerOrders(): number of orders don't match norder\n" );
3388 fprintf(stderr,"\tnor: %d norder: %d \n",i,n);
3389 exit(-1);
3390 }
3391
3392 return(tbytes);
3393 }
3394
3395
3396
NetMess(struct NetMess * mess,int action)3397 int NetMess(struct NetMess *mess,int action){
3398 /*
3399 A list of messages to be sended between client and server.
3400 returns:
3401 1 if the operation success
3402 0 if no data is readed or writed.
3403 */
3404
3405 static int cont=0;
3406 static struct ListNetMess head;
3407 static int sw=0;
3408 struct ListNetMess *l,*lnewm;
3409 int ret,n;
3410
3411 if(sw==0){
3412 head.next=NULL;
3413 sw++;
3414 }
3415
3416 ret=0;
3417
3418 switch(action){
3419 case NMADD:
3420 if(mess==NULL)return(0);
3421
3422 lnewm=malloc(sizeof(struct ListNetMess));
3423 if(lnewm==NULL){
3424 fprintf(stderr,"ERROR in malloc (NetMess)\n");
3425 exit(-1);
3426 }
3427
3428 lnewm->next=head.next;
3429 lnewm->mess.id=mess->id;
3430 lnewm->mess.a=mess->a;
3431 lnewm->mess.b=mess->b;
3432 head.next=lnewm;
3433
3434 cont++;
3435 ret=1;
3436 break;
3437 case NMREAD:
3438 if(head.next==NULL){
3439 if(cont!=0){
3440 fprintf(stderr,"ERROR in NetMess(): no data and cont=%d\n",cont);
3441 }
3442 ret=0;
3443 }
3444 else{
3445 mess->id=head.next->mess.id;
3446 mess->a=head.next->mess.a;
3447 mess->b=head.next->mess.b;
3448 lnewm=head.next;
3449 head.next=head.next->next;
3450 free(lnewm);
3451 cont--;
3452 ret=1;
3453 }
3454 break;
3455 case NMCLEAN:
3456 fprintf(stderr,"ERROR NetMess(): action %d not implemented\n",action);
3457 ret=0;
3458 break;
3459 case NMCOUNT:
3460 ret=cont;
3461 break;
3462 case NMPRINT:
3463 n=0;
3464 l=head.next;
3465 while(l!=NULL){
3466 printf("%d %d %d\n",l->mess.id,l->mess.a,l->mess.b);
3467 n++;
3468 l=l->next;
3469 }
3470 ret=n;
3471 break;
3472 default:
3473 fprintf(stderr,"ERROR NetMess(): action %d not implemented\n",action);
3474 exit(-1);
3475 break;
3476 }
3477
3478 return(ret);
3479 }
3480
CopyNetMess2Buffer(struct Buffer * buffer,struct NetMess * mess0)3481 int CopyNetMess2Buffer(struct Buffer *buffer, struct NetMess *mess0){
3482 /*
3483 Copy the list of messages to buffer, ready to be sended between client and server.
3484 returns:
3485 the number of bytes writed.
3486 */
3487
3488 int nbytes;
3489 struct NetMess mess;
3490
3491 nbytes=sizeof(struct NetMess);
3492
3493 if(buffer->n+nbytes>buffer->size){
3494 int newsize;
3495 newsize=buffer->size+1024;
3496 buffer->data=realloc(buffer->data,newsize*sizeof(char));
3497 if(buffer->data==NULL){
3498 fprintf(stderr,"ERROR in malloc Copyfile2Buf()\n");
3499 exit(-1);
3500 }
3501 buffer->size=newsize;
3502 }
3503
3504 mess.id=mess0->id;
3505 mess.a=mess0->a;
3506 mess.b=mess0->b;
3507
3508 memcpy(buffer->data+buffer->n,&mess,nbytes);
3509 buffer->n+=nbytes;
3510 return(nbytes);
3511 }
3512
3513
3514
3515 /******* Cargo *********/
3516
AddObjCargo2Buffer(struct Buffer * buffer,Object * obj)3517 int AddObjCargo2Buffer(struct Buffer *buffer,Object *obj){
3518 /*
3519
3520 returns:
3521 the number of bytes added
3522 */
3523
3524
3525 int n;
3526 int nbytes,tbytes;
3527 struct ObjList *ls;
3528
3529 tbytes=0;
3530
3531 /*count number of objects */
3532 n=0;
3533
3534 if(obj->cargo.hlist==NULL){
3535 /* nothing to add */
3536 nbytes=sizeof(int);
3537 CopyInt2Buffer(buffer,&n);
3538 return(tbytes);
3539 }
3540
3541 ls=obj->cargo.hlist->list;
3542 while(ls!=NULL){
3543 n++;
3544 }
3545 /* Checking */
3546
3547 if(n!=obj->cargo.hlist->n){
3548 fprintf(stderr,"ERROR AddObjCargo2Buffer(): number of items don't match\n" );
3549 fprintf(stderr,"\tn: %d nlist: %d \n",n,obj->cargo.hlist->n);
3550 exit(-1);
3551 }
3552
3553 nbytes=sizeof(int); /* number of items */
3554 CopyInt2Buffer(buffer,&n);
3555 tbytes+=nbytes;
3556
3557 /* list of item */
3558 ls=obj->cargo.hlist->list;
3559 while(ls!=NULL){
3560 nbytes=sizeof(int);
3561 CopyInt2Buffer(buffer,&ls->obj->id);
3562 tbytes+=nbytes;
3563 ls=ls->next;
3564 }
3565 return(tbytes);
3566 }
3567
CopyObjCargofromBuffer(Object * obj0,char * buf0)3568 int CopyObjCargofromBuffer(Object *obj0,char *buf0){
3569
3570 return(0);
3571 }
3572
3573