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(&paramc,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,&param,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