     WarBirds

      :

struct map_define{
	int present;	/*       ,
				    
				     
				.fuel, .score, .mov
			*/
	char arena[16];	/*    (.tex)    
			 WarBirds      
			  
			*/
	char sbuf[S_BUF_LNG];	/*      
				    WritePack().
				    
				      
				  */
	char rbuf[R_BUF_LNG];	/*         */
	char rest_buf[R_BUF_LNG]; /*       ,
				      .
				    read()  
				   ,      
				 ,      
				(  )    .
				    2    rbuf */
	char com_buf[R_BUF_LNG]; /*     
				      
				   ,   
				.     4 
				    */
	int com_len;		/*     com_buf ( ) */
	int s_cur;		/*       
				 sbuf.       
				   -     
				   */
	int r_cur;		/*       */
	int r_rest;		/*      
				rest_buf */
	char arena_id;		/*    */
	int set_sync;		/*     
				 ,   
				 1.      0. */
	int sync_seq;		/*   1207,   */
	int sync_seq_interval; /*     
				1    400   
				 1207   */
	int country;	/*       */
	int field;	/*    */
	int plane_type;	/*    */
	int altitude;	/*    */
	int ordn;	/*    */
	int fuel;	/*      */
	int conv;	/*   */
	int plane_id;	/*   ,    
			 socket     
			 HOST->FE */
	char nickname[8]; /* ASCII     (antvrp) */
	char login[10]; /*   */
	int pl_status1; /*     (flaps, engine, chasses, wing e.t.c) */
	int pl_status2; /*      (,
			, . .   ..*/

	int x_coord;	/* x coordinats */	
	int y_coord;	/* y coordinats */
	int z_coord;	/* z coordinats */
};



			 .

      select.   = 0.
     ,   select    .
   ,       
        
  .
      .   
  -.
       , 
 ,    ,  ..,  
  "",       
,       .
        ( 
   ),     SIGPIPE ( "").
  ""  ,       
 .
        .
  -    select()   
   .
    .
          
   ,    -   
    .
      .     
    ,        .
   :
   ,    ,  
 ,     .
      ,   .
      ,     .
    ,   :

.....
fd_set read_ready; /*     */
fd_set write_ready; /*     */
.....

	while(1){
		clilen=sizeof(cli_addr);

/*    (     0 */
		FD_ZERO(&read_ready);
/*     (   ) */
		FD_SET(sock, &read_ready);

/*       */
		fd_copy_user();

/*     = 0 */
		to.tv_usec = 0; /*  */
		to.tv_sec = TIMEOUT; /*  */


/******** SELECT CALL **********/

/*    select() */
		if (select(getdtablesize(), &read_ready, 0, 0, &to) < 0) {
			sprintf(mbuf, "%s: select error\n", function);
			log_f(1, mbuf);
			continue;
		}

/******** CHECK INCOMMING CALL *********/

		if (FD_ISSET(sock, &read_ready)) {
/*        ( ) */
/*     */

		printf("Main Server: socket [%d] handle.\n", sock);


/*         */

		/*
		     
		cur -       .
		       
		 .    5 -10 . 
		*/
		
        		p_client[cur].plane_id = accept(sock, (struct sockaddr *) &cli_addr, &clilen);
/*   accept     p_client  plane_id
     FE->SERVER */

			if ( p_client[cur].plane_id < 0){
				sprintf(mbuf, "%s: accept error\n", function);
				log_f(1, mbuf);
				p_client[cur].plane_id = 0;
				exit (1);
			}
			printf("Server: incomming socket address [%s]\n",
			inet_ntoa( *(struct in_addr *)&cli_addr.sin_addr.s_addr));

			/*     
			   (  ) */

		/*         select() */

			FD_SET(p_client[cur].plane_id, &read_ready);


		/*         
			   */

			FD_CLR(sock, &read_ready);

		/*         
			     */
			rval = read_socket(cur, buf);

		/*        
			    -  
			  read_socket (  )*/

			if (rval == -1){
				sprintf(mbuf, "%s: error read socket\n", function);
				log_f(1, mbuf);

			}
			else
			{
			if( rval == 0) continue; /*   */

		/*          */

			sprintf(mbuf, "New Client incomming!\n");
			log_f(1, mbuf);
		/*     */
			if(debug_level >=4)
			{
				sprintf(mbuf, "Received [%d] bytes -> ", rval);
				log_f(4, mbuf);
				write(fd, buf, rval);
				sprintf(mbuf, "\n");
				log_f(4, mbuf);
			}

		/*      */
			HandlePack(buf, rval, cur);

		/*       */
			WritePack(cur);

			} /* end if ... else rval == -1 */


		} /* end if ( FD_ISSET....) */
		/*      */
		/*       
			     */

		for(i=0; i<CL_NUM; i++){
		/*       -  
			,        */
			if ( FD_ISSET(p_client[i].plane_id, &read_ready)) { /* test every incomming socket */
				sprintf(mbuf, "Connected server: socket [%d] handle\n", p_client[i].plane_id);
				log_f(4, mbuf);

				rval=read_socket(i, buf);

				if( rval == -1){
					sprintf(mbuf, "%s: error read socket\n", function);
					log_f(1, mbuf);
				        for(i=0; i<CL_NUM; i++){
						sprintf(mbuf,"p_client[%d].plane_id = [%d]\n", i, p_client[i].plane_id);
						log_f(4, mbuf);
					}


				}
				else
				{
				
				if(rval == 0) continue; /* if rval == 0 then connection closed */

				if(debug_level >=4)
				{
                                 	sprintf(mbuf, "Received [%d] bytes -> ", rval);
					log_f(4, mbuf);

					write(fd, buf, rval);

					sprintf(mbuf, "\n");
					log_f(4, mbuf);
				}

			/* handle incomming client packet */
				HandlePack(buf, rval, i);
				WritePack(i);
			/*     ,
				       */

				FD_CLR(p_client[id].plane_id, &read_ready);
				} /* end if ... else rval == -1 */
			} /* end FD_ISSET */
		} /* end for */
	} /* end while */





  read_socket()

int read_socket(id, buf)
int id;
char *buf;
{
int i,k,n;
int rval;

	rval = read(p_client[id].plane_id, buf, R_BUF_LNG);

        for(;;){ /* for read */
        	if(rval < 0){
		sprintf(mbuf,"Server: error in reading [%d] socket\n", p_client[id].plane_id);
		log_f(1, mbuf);

	/* remove socket from listening sockets array */

		FD_CLR(p_client[id].plane_id, &ready);

		shutdown(p_client[id].plane_id, 2);
		close(p_client[id].plane_id); /* close socket connection */

	/* remove socket from plane_id database */

		plane_zero(id);
		rval = -1;
		break;
		} /* end if rval = -1 */

		if(rval == 0){
		sprintf(mbuf,"Server: ending connection [%d] socket.\n", p_client[id].plane_id);
		log_f(1, mbuf);
	/* remove socket from listening sockets array */

		FD_CLR(p_client[id].plane_id,&ready);

		shutdown(p_client[id].plane_id, 2);
		close(p_client[id].plane_id); /* close socket connection */

	/* remove socket from plane_id database */

		plane_zero(id);
		break;
		} /* end if rval == 0 */
	break;
	} /* end for read loop */

return (rval);
}



  WritePack()
       HandlePack  (FE).
    read_socket    ,
 HandlrPack  ,      .
        write   
,   ()     p_client.sbuf,
    handlePack    .
  WritePack     p_client.s_cur 
 0,   HandlrPack    .
    HandlePack   
p_client.s_cur         .
  .
      ,     ,
      .   ,   .
       ,   
      .

int WritePack(id)
int id;
{
int rval;
char *function = "WritePack";

	if(debug_level >= 12)
	{
		sprintf(mbuf, "%s: start %8.8x\n", function, (unsigned int) times(&tms));
		log_f(12, mbuf);
	}

	if(p_client[id].s_cur == 0) return TRUE; /* no data to write */

	rval = WriteSocket(id, p_client[id].sbuf, p_client[id].s_cur);

	if(rval == FALSE)
	{
		sprintf(mbuf, "%s: error write socket\n", function);
		log_f(1, mbuf);
		return FALSE;
	}
p_client[id].s_cur = 0;
return TRUE;
}



  WriteSocket()
        
    .    
  .
         
    .

int WriteSocket(id, sbuf, len)
int id;
char *sbuf;
int len;
{
int rval;
char *function = "WriteSocket";

	if(debug_level >=12)
	{
		sprintf(mbuf, "%s: start %8.8x\n", function, (unsigned int) times(&tms));
		log_f(12, mbuf);
	}

	if(p_client[id].plane_id == 0) return TRUE; /* that's socket has been closed */

	/* write raw data to log file */

	if(debug_level >=12)
	{
		write(fd, sbuf, len);
		sprintf(mbuf, "\n\n");
		log_f(9, mbuf);
	}

#ifdef SEND
	rval = send(p_client[id].plane_id, sbuf, len, 0);
#else
	rval = write(p_client[id].plane_id, sbuf, len);
#endif
	if ( rval < 0)
	{
		sprintf(mbuf, "%s: error writing [%d] socket\n", function, p_client[id].plane_id);
		log_f(1, mbuf);

		sprintf(mbuf, "%s: client [%s] removed from server DB\n", function, p_client[id].nickname);
		log_f(1, mbuf);


	/* remove player from server DB */

		FD_CLR(p_client[id].plane_id, &ready);
		RemoveFromAllDB(id); /* remove this plane from ALL DB */
		shutdown(p_client[id].plane_id, 2);
		close(p_client[id].plane_id); /* close socket connection */
		plane_zero(id);
		return FALSE;
	}
	if(debug_level >=6)
	{
		sprintf(mbuf, "%s: write socket [%d] OK\n", function, p_client[id].plane_id);
		log_f(6, mbuf);
	}

return TRUE;
}



  Send0f00Pack, Send0f01Pack.
         .
   ()     
 .
      FE.
     32 .
   - 10 000  (30 000 ).
     .
   .
          
FE.
   30000 ,     ,
    .
1.      .
2.     30000       .
          (   ).
3.    30000       .   
    .     .
4.      ,   4  0x00.
5.    ,     .
6.    FE    .   
7.         !
8.        ( )   
   !!!      30   
 .

     FE.    
   .

        .
  .
         .
 .

int Send0f00Packet(id)
int id;
{
char *function = "Send0f00Packet";
int k=0;	/*     */
int i, j;
int data_len;
int ox, oy, oz; /*    */
int mx, my, mz; /*    */
int distance;	/*    */
int wbmain;	/*     WB nickname  FE */
int wbfound;	/*     WB nickname  FE */
int rval;	/*    */
int glob_idx;
int tmp;
int status;	/*    FE DB   
			.     . */

unsigned char sum;
unsigned char wbchar[5];	/*     WB nickname */
unsigned char sbuf_db[S_BUF_LNG]; /*       */

	name64(p_client[id].nickname, wbchar);
	wbmain = int_ret(wbchar, 0);
	status = 255;

	for(k=0; k<CL_NUM; k++)
	{

		ox=p_client[k].x_coord;
		oy=p_client[k].y_coord;
		oz=p_client[k].z_coord;

		mx=p_client[id].x_coord;
		my=p_client[id].y_coord;
		mz=p_client[id].z_coord;

	/* convert found nickname to wb-nickname */

		name64(p_client[k].nickname, wbchar);
		wbfound = int_ret(wbchar, 0);

		if(wbfound == 0) continue; /* that this cell is empty */
		if(wbfound == wbmain) continue; /* that is my own FE */

	/* now we calculate distance from my FE to tested plane */
	/* distance = SQRT(x*x + y*y +z*z) */

	distance = sqrt((ox-mx)*(ox-mx) + (oy-my)*(oy-my) + (oz-mz)*(oz-mz));

	/* test for distance */

		if(distance > 100*100*3 || p_client[k].in_tower == 0x0030 ) /* 100 d or in tower */
		{
	/* this plane furter then allow FEdatabase distance */
	/* test for present this plane in my FE database */
	/* if plane present, then remove it, if no then continue to test next plane */
			
			rval = TestFEDBPresent(id, wbfound);
			if( rval == 255) continue; /* then plane not have been
							in FE database */

			wbfound = 0; /* remove plane */
			int_store(p_client[id].fe_dat, wbfound, rval);
			status = rval;	/* status - index of changed palne in FE DB */

/*
			sprintf(mbuf, "%s removed", p_client[k].nickname);
			SendWBMessage(id , HOST_CHL , wb_nick, mbuf);
*/

			break;	/* go away from cycle */
				/* need to send changes to FE */	
		}
		else
		{
	/* test for present this plane in my FE database */
	/* if plane present, then continue, if no then find first free cell
		and store new plane in it */

			rval = TestFEDBPresent(id, wbfound);
			if(rval != 255) continue; /* then plane have been stored
							in FE database */

			/* now find first free cell */
			rval = TestFEDBPresent(id, 0); /* "0" - mean free cell */
			if(rval == 255)
			{
	/****************** IMPORTANT! ******************/
				/* I have no any free cell */
				/* this is known bug and i don't store
					plane in my FE */
				continue;
			}

			/* first free cell has index "rval" */
			/* I store new plane (wbfound) in it */
			/* so I store plane_type and country in database */

			int_store(p_client[id].fe_dat, wbfound, rval);
			status = rval; /* index changed palne in FE DB */
			p_client[id].fe_dat_cntr[rval/4] = p_client[k].country;
			p_client[id].fe_dat_pln[rval/4] = p_client[k].plane_type;

			sprintf(mbuf, "%s added", p_client[k].nickname);
			SendWBMessage(id , HOST_CHL , wb_nick, mbuf);

			break; /* send data to FE */
		}
	} /* end for k */
	
/* in this point all planes in arena tested and registed */
/* now I need to create packet to send */

	if(status == 255) return FALSE; /* no data to send, no changes */

	i=0;
	sbuf_db[i] = 0x02; /* header */
	i=i+3;		   /* skip offset */

	sh_store(sbuf_db, 0x0f00, i);
	i=i+2;

	sbuf_db[i] = status/4;
	i++;

	int_store(sbuf_db, wbfound, i);
	i=i+4;

	int_store(sbuf_db, p_client[id].fe_dat_cntr[status/4], i); /* country */
	i=i+4;

	int_store(sbuf_db, p_client[id].fe_dat_pln[status/4], i); /* plane type */
	i=i+4;

	int_store(sbuf_db, 0, i); /* damages */
	i=i+4;

	/* calculate data segment length */
	data_len = i-3;

/*
 make offset
 */
	sh_store(sbuf_db, data_len, 1);

/*
 Calculate CRC
 */

	sum = 0;
	for(j=3; j<3+data_len; j++)
	{
		sum = sum+sbuf_db[j];
	}
	sbuf_db[j] = sum;

/* current position to write */
	j++;

#ifdef SEND
	rval = send(p_client[id].plane_id, sbuf_db, j, 0);
#else
	rval = write(p_client[id].plane_id, sbuf_db, j);
#endif
	if ( rval < 0)
	{
		sprintf(mbuf, "%s: error write socket\n", function);
		log_f(1, mbuf);
		ShutdownClient(id);
		return FALSE;
	}

	sprintf(mbuf, "%s: write OK\n", function);
	log_f(5, mbuf);

	/* log to file */
	if(debug_level >=9)
	{
		write(fd, sbuf_db, j);
		sprintf(mbuf, "\n\n");
		log_f(9, mbuf);
	}

/**********************SEND STATUS************************/

	glob_idx = GetIdxByWBPack(wbfound);
	if(glob_idx == 255) return TRUE; /* Not found, not send */

	Send0f02Packet(id, glob_idx); /* Send status to "id" about "glob_idx" */


return TRUE;
}






   TestFEDBPresent(int , int ) ?
     WB nickname.
 .       
      (   4  )
      255 (   ).

int TestFEDBPresent(id, wbtest)
int wbtest;
{
int k;
unsigned int test

	k=0;
	while(k<N_OBJECTS*4)
	{
		test = int_ret(p_client[id].fe_dat, k);
		if(test == wbtest) return (k);
		k=k+4;
	}
return (255);
}



     id   
   FE DB.   DRON    .


int Send0f01Packet(id)
int id;
{
char *function = "Send0f01Packet";
int i, j, k, l;
int less_30;	/* store current index for write number of planes d<30 */
int more_30;	/* store current index for write number of planes d>30 */
int data_len;
int rval;
int count1;	/* number of planes d < 30 */
int count2;	/* number of planes d > 30 */
int last;
float sh_dt;
unsigned int wbmain;
unsigned int wbfound;

unsigned int interval_time;
unsigned char sum;

short int two_bytes;

unsigned char wbchar[5];
unsigned char sbuf_fe[S_BUF_LNG];
unsigned char tmp_sbuf_fe[7*N_OBJECTS];

/* temporary for debug SH */
short int ta, ts, dx, dy, dz, vpitch, vbank, vyaw, vx, vy, vz;

	name64(p_client[id].nickname, wbchar);
	wbmain = int_ret(wbchar, 0);

	sh_dt = 0.5; /* minimal quant of time in WB - 500mS */

	/* set current sbuf_fe position to 0 */
	i=0;

	/* header */
	sbuf_fe[i] = 0x02;
	i=i+3; /* skip offset */

	/* store packet type 0x0f01 */
	sh_store(sbuf_fe, 0x0f01, i);
	i=i+2;


	/* get system timesequence (4 bytes) */
	/* we use ONE global time - global_sys */
	/* every client has ONE time val */

	int_store(sbuf_fe, (unsigned int) global_sys, i);
	i=i+4;


/*
 Put absolute coords of the reference point
 Any relative coords in this packet will 
 refer to this point only
 */

	/* store global x */
	int_store(sbuf_fe, p_client[id].x_coord, i);
	i=i+4;

	/* store global y */
	int_store(sbuf_fe, p_client[id].y_coord, i);
	i=i+4;

	/* store global z */
	int_store(sbuf_fe, p_client[id].z_coord, i);
	i=i+4;


	/* skip number of planes, it depends of FE DB */
	less_30 = i;
	i++;

	count1=0;
	count2=0;

	k=0;
	l=0; /* index tmp buf */

	while(k<4*N_OBJECTS)
	{
	/* get current packed wbnickname from FE database */

		wbfound = int_ret(p_client[id].fe_dat, k);
		if(wbfound == 0) /* that is cell is empty */
		{
			k=k+4;
			continue;
		}

		rval = GetDistance(id, wbfound);


/*
		sprintf(tmp_nick, "-host-");
		name64(tmp_nick, wb_nick);
		wb_nick[0] = wb_nick[0] | 0x40;

		sprintf(mbuf, "d = [%d]", (unsigned int) (rval/300));
		SendWBMessage(id , HOST_CHL , wb_nick, mbuf);
*/


		if(rval > 30*100*3) /* more then 30d */
		{
			/* far plane 30d < plane < 100d */
			/* from this place we found plane with distance d30<xx<d100 */

			count2++;

			tmp_sbuf_fe[l] = k/4;
			l++;

			j=GetIdxByWBPack(wbfound);

#define LGT 8.8 /* divide koeff */

			dx = (short int)((p_client[j].x_coord-p_client[id].x_coord)/LGT);
			dy = (short int)((p_client[j].y_coord-p_client[id].y_coord)/LGT);
			dz = (short int)((p_client[j].z_coord-p_client[id].z_coord)/LGT);

			sprintf(mbuf, "%s: %s from me (%s): dx = [%d] dy = [%d] dz = [%d]\n",
				function,
				p_client[j].nickname,
				p_client[id].nickname,
				(short int)dx,
				(short int)dy,
				(short int)dz);
			log_f(9, mbuf);

			sh_store(tmp_sbuf_fe, dx, l);	/* dx - relative position */
			l=l+2;
			sh_store(tmp_sbuf_fe, dy, l);	/* dy - relative position */
			l=l+2;
			sh_store(tmp_sbuf_fe, dz, l);	/* dz - relative position */
			l=l+2;


			k=k+4;
			continue;
		}

		/* from this place we found plane with distance < d30 */
		count1++;

		sprintf(mbuf, "%s: count1 = %d\n", function, count1);
		log_f(8, mbuf);

		/* very interesting 2 bytes! */
		two_bytes = 0xffff;
		sh_store(sbuf_fe, two_bytes, i);
		i=i+2;

		sbuf_fe[i] = k/4;	/* object ID in FE DB, so as each member - 4 bytes */
		i++;

		j=GetIdxByWBPack(wbfound);

/*********************** FROM plane i test SUBSTRUCT MY COORD!!!! ********/
/************************ THAT'S WRIGHT! *********************************/

		dx = (short int)(p_client[j].x_coord-p_client[id].x_coord);
		dy = (short int)(p_client[j].y_coord-p_client[id].y_coord);
		dz = (short int)(p_client[j].z_coord-p_client[id].z_coord);

		sprintf(mbuf, "%s: %s from me (%s): dx = [%d] dy = [%d] dz = [%d]\n",
			function,
			p_client[j].nickname,
			p_client[id].nickname,
			(short int)dx,
			(short int)dy,
			(short int)dz);
		log_f(8, mbuf);

		sh_store(sbuf_fe, dx, i);	/* dx - relative position */
		i=i+2;
		sh_store(sbuf_fe, dy, i);	/* dy - relative position */
		i=i+2;
		sh_store(sbuf_fe, dz, i);	/* dz - relative position */
		i=i+2;

#define VD 4	/* linear speed divider < I think it's accurate > */
#define AD 4 	/* linear acceleration divider < Not sure > */
#define ASD 64	/* angular speed divider < Looks good > */
#define ANGLE_CVT(A,S) (char)(256.0*(double)(A + sh_dt * S)/(10.0*360.0)) 
#define SPEED_CVT(S, A) (S + A * sh_dt)/VD


		/* PITCH ANGLE - tangazh */
		sbuf_fe[i] = ANGLE_CVT(p_client[j].pitch, p_client[j].vpitch);
		i++;

		/* X acceleration */
		sbuf_fe[i] = p_client[j].ax / AD;
		i++;

		/* VPITCH - angular speed */
		/* Some strange format, but it works */
		vpitch = p_client[j].vpitch / ASD ;
		if(vpitch >= 0) {
			sbuf_fe[i] = vpitch << 1;
			sbuf_fe[i] = sbuf_fe[i] | 0x80;
		} else {
			sbuf_fe[i] = vpitch << 1;
			sbuf_fe[i] = sbuf_fe[i] & 0x7f;
		}
		i++;

		/* X SPEED */
		/* First bit (sign) must be in previous byte !!! */
		vx = SPEED_CVT(p_client[j].vx, p_client[j].ax);
		if(vx >= 0) {
			sbuf_fe[i-1] = sbuf_fe[i-1] | 1;
			sbuf_fe[i] = (char)vx;
		} else {
			sbuf_fe[i-1] = sbuf_fe[i-1] & 0xfe;
			sbuf_fe[i] = 0xff + (char)vx;
		}
		i++;

		/* BANK ANGLE - kren */
		sbuf_fe[i] = ANGLE_CVT(p_client[j].bank, p_client[j].vbank);	
		i++;

		/* Y ACCELERATION */
		sbuf_fe[i] = p_client[j].ay / AD;
		i++;

		/* VBANK - angular speed */
		/* Some strange format, but it works */
		vbank = p_client[j].vbank / ASD ;
		if(vbank >= 0) {
			sbuf_fe[i] = vbank << 1;
			sbuf_fe[i] = sbuf_fe[i] | 0x80;
		} else {
			sbuf_fe[i] = vbank << 1;
			sbuf_fe[i] = sbuf_fe[i] & 0x7f;
		}
		i++;

		/* Y SPEED */
		/* First bit (sign) must be in previous byte !!! */
		vy = SPEED_CVT(p_client[j].vy, p_client[j].ay);
		if(vy >= 0) {
			sbuf_fe[i-1] = sbuf_fe[i-1] | 1;
			sbuf_fe[i] = (char)vy;
		} else {
			sbuf_fe[i-1] = sbuf_fe[i-1] & 0xfe;
			sbuf_fe[i] = 0xff + (char)vy;
		}
		i++;

		/* YAW - really heading - kurs */
		sbuf_fe[i] = ANGLE_CVT(p_client[j].yaw, p_client[j].vyaw);
		i++;

		/* Z ACCELERATION */
		sbuf_fe[i] = p_client[j].az / AD;
		i++;

		/* VYAW - angular speed */
		/* Some strange format, but it works */
		vyaw = p_client[j].vyaw / ASD ;
		if(vyaw >= 0) {
			sbuf_fe[i] = vyaw << 1;
			sbuf_fe[i] = sbuf_fe[i] | 0x80;
		} else {
			sbuf_fe[i] = vyaw << 1;
			sbuf_fe[i] = sbuf_fe[i] & 0x7f;
		}
		i++;

		/* Z SPEED */
		/* First bit (sign) must be in previous byte !!! */
		vz = SPEED_CVT(p_client[j].vz, p_client[j].az);
		if(vz >= 0) {
			sbuf_fe[i-1] = sbuf_fe[i-1] | 1;
			sbuf_fe[i] = (char)vz;
		} else {
			sbuf_fe[i-1] = sbuf_fe[i-1] & 0xfe;
			sbuf_fe[i] = 0xff + (char)vz;
		}
		i++;

		k=k+4;

	} /* end k */

	/* store number of planes d<30 */
	sbuf_fe[less_30] = count1;

/*
 We have no planes in range d30-d100 so
 this number should be 0. Normally we put here number of
 planes in range d30-d100
 */

	more_30=i; /* store index where to write number of planes d>30 */

/*************************HERE IS BODY TO STORE PLANES D>30***************/
/*
		BODY
*/
	sbuf_fe[more_30] = count2;
	i++;

	/* copy from tmp buf planes coord > d30 */

	last = l;

	if(count2 != 0)
	{
		for(l=0; l<last; l++)
		{
			sbuf_fe[i] = tmp_sbuf_fe[l];
			i++;
		}
	}

/*
********************* NOW WE TEST count1 and count2
*/

	if(count1 == 0 && count2 == 0) return FALSE; /* none plane is here */



	/* calculate data segment length */
	data_len = i-3;

/*
 make offset
 */
	sh_store(sbuf_fe, data_len, 1);

/*
 Calculate CRC
 */

	sum = 0;
	for(j=3; j<3+data_len; j++)
	{
		sum = sum+sbuf_fe[j];
	}
	sbuf_fe[j] = sum;

/* current position to write */
	j++;

#ifdef SEND
	rval = send(p_client[id].plane_id, sbuf_fe, j, 0);
#else
	rval = write(p_client[id].plane_id, sbuf_fe, j);
#endif
	if ( rval < 0)
	{
		sprintf(mbuf, "%s: error write socket\n", function);
		log_f(1, mbuf);
		ShutdownClient(id);
		return FALSE;
	}

	sprintf(mbuf, "%s: write to %s OK\n", function, p_client[id].nickname);
	log_f(9, mbuf);

	/* log to file */
	if(debug_level >=9)
	{
		write(fd, sbuf_fe, j);
		sprintf(mbuf, "\n\n");
		log_f(9, mbuf);
	}
return TRUE;
}


 int GetDistance(int )      
  .

unsigned int GetDistance(id, wbfound)
int id;
int wbfound;
{
int k;
int x;
int y;
int z;

	k=GetIdxByWBPack(wbfound);
	if(k == 255) return (0xffffffff); /* client not found, max distance */

	x=p_client[k].x_coord - p_client[id].x_coord;
	y=p_client[k].y_coord - p_client[id].y_coord;
	z=p_client[k].z_coord - p_client[id].z_coord;

	return (sqrt(x*x + y*y + z*z));
}

 GetIdxByWBPack(int )      
p_client[n]    .    255
     (  ).

int GetIdxByWBPack(wbtest)
int wbtest;
{
int k;
char wb_nickname[8];
char wbchar[5];

	int_store(wbchar, wbtest, 0);
	name46(wbchar, wb_nickname);
	for(k=0; k<CL_NUM; k++)
	{
		if(!strncmp(p_client[k].nickname, wb_nickname, strlen(wb_nickname)))
		{
			return (k);
		}
	}
return (255);
}

    .
        (0f02 packet).
    1 .
        .
       
        
   .   -   
        
         .
           
       .


   id        .

int SendAll0f02Packet(id)
int id;
{
int i, j, k;
int c_fe;
int data_len;
char wbchar[5];
int wbtest;
int wbown;
int found;
int found1;
int found2;
int rval;
char sbuf_st[16];
unsigned char sum;
char *function = "SendAll0f02Packet";

#if !defined DRON /* make process if DRON not defined */

	/* store my own wbpacked nickname in "wbown" */
	name64(p_client[id].nickname, wbchar);
	wbown = int_ret(wbchar, 0);

	/* preset value */
	found1 = 255;

	/* test ALL palnes in my FE DB */
	k=0;
	while(k<4*N_OBJECTS)
	{
		wbtest = int_ret(p_client[id].fe_dat, k);
		if (wbtest == 0) /* empty cell */
		{
			k=k+4;
			continue;
		}

		/* get plane's global index */
		found = GetIdxByWBPack(wbtest);

		/* test plane's "found" FE DB for myself plane present */
		c_fe = 0;
		found2 = 255;
		while(c_fe < 4*N_OBJECTS)
		{
			wbtest = int_ret(p_client[found].fe_dat, c_fe);
			if(wbtest == wbown)
			{
				found2 = c_fe/4;
				break; /* that is found myself in his FE DB */
			}

			c_fe = c_fe+4;
			continue;
		}

		if(found2 == 255)
		{
			k=k+4;
			continue; /* that's i didn't found */
		}

		i=0;
		sbuf_st[i] = 0x02; /* header */
		i=i+3;
		/* store packet type 0x0f02 */
		sh_store(sbuf_st, 0x0f02, i);
		i=i+2;
		sbuf_st[i] = found2; /* my current index in his FE DB */
		i++;
		int_store(sbuf_st, p_client[id].pl_status1, i); /* my status1 */
		i=i+4;
		int_store(sbuf_st, p_client[id].pl_status2, i); /* my status2 */
		i=i+4;

	/* calculate data segment length */
		data_len = i-3;

/*
 make offset
*/
		sh_store(sbuf_st, data_len, 1);

/*
 Calculate CRC
 */

		sum = 0;
		for(j=3; j<3+data_len; j++)
		{
			sum = sum+sbuf_st[j];
		}
		sbuf_st[j] = sum;

/* current position to write */
		j++;

#ifdef SEND
		rval = send(p_client[found].plane_id, sbuf_st, j, 0);
#else
		rval = write(p_client[found].plane_id, sbuf_st, j);
#endif
		if ( rval < 0)
		{
			sprintf(mbuf, "%s: error write [%d] socket\n", function, p_client[found].plane_id);
			log_f(1, mbuf);
			p_client[found].s_cur = 0;
			k=k+4;
			continue; /* to next plane */
		}

		sprintf(mbuf, "%s: write to %s OK\n", function, p_client[found].nickname);
		log_f(1, mbuf);

	/* log to file */
		if(debug_level >=1)
		{
			write(fd, sbuf_st, j);
			sprintf(mbuf, "\n\n");
			log_f(1, mbuf);
		}

		k=k+4;
		continue; /* next plane */
	}

	if(found1 == 255)
	{
		p_client[id].status_chngd = FALSE; /* set changed status value to FALSE */
                return FALSE; /* none plane has been found */
	}

	p_client[id].status_chngd = FALSE; /* set changed status value to FALSE */

#endif /* not defined DRON */

return TRUE;
}


      idx  id.
       
    .



int Send0f02Packet(id, idx)
int id;
int idx;
{
int i, j, k;
int data_len;
char wbchar[5];
int wbfound;
int wbtest;
int found;
int rval;
char sbuf_st[16];
unsigned char sum;
char *function = "Send0f02Packet";

	name64(p_client[idx].nickname, wbchar);
	wbfound = int_ret(wbchar, 0);

	k=0;
	found = 255;
	while(k<4*N_OBJECTS)
	{
		wbtest = int_ret(p_client[id].fe_dat, k);
		if (wbtest != wbfound)
		{
			k=k+4;
			continue;
		}
		found = k/4;
		break;
	}
	if(found == 255) return FALSE; /* not found */

	i=0;

	sbuf_st[i] = 0x02;
	i=i+3;

	/* store packet type 0x0f02 */
	sh_store(sbuf_st, 0x0f02, i);
	i=i+2;

	sbuf_st[i] = found;
	i++;

	int_store(sbuf_st, p_client[idx].pl_status1, i);
	i=i+4;
	int_store(sbuf_st, p_client[idx].pl_status2, i);
	i=i+4;

	/* calculate data segment length */
	data_len = i-3;

/*
 make offset
 */
	sh_store(sbuf_st, data_len, 1);

/*
 Calculate CRC
 */

	sum = 0;
	for(j=3; j<3+data_len; j++)
	{
		sum = sum+sbuf_st[j];
	}
	sbuf_st[j] = sum;

/* current position to write */
	j++;

#ifdef SEND
	rval = send(p_client[id].plane_id, sbuf_st, j, 0);
#else
	rval = write(p_client[id].plane_id, sbuf_st, j);
#endif
	if ( rval < 0)
	{
		sprintf(mbuf, "%s: error write socket\n", function);
		log_f(1, mbuf);
		p_client[id].s_cur = 0;
		return FALSE;
	}

	sprintf(mbuf, "%s: write to %s OK\n", function, p_client[id].nickname);
	log_f(1, mbuf);

	/* log to file */
	if(debug_level >=1)
	{
		write(fd, sbuf_st, j);
		sprintf(mbuf, "\n\n");
		log_f(1, mbuf);
	}

return TRUE;
}


   0e00.
FE        .
    (    ).
         FE DB 
  .
          FE   
      .
 2       .
       FE   
  FE.
      p_client.
 .
         .
    SYNC .   SYNC  .
        
SYNC(FE)  SYNC(HOST).      
   .     FE   
         
     FE.
          
     .


void HandleFEPosition(id)
int id;
{
char *function = "HandleFEPosition";
int k;
int interval_time;
int wbfound;
int wbmain;
char wbchar[5];

	sprintf(mbuf, "%s:\n", function);
	log_f(5, mbuf);

	p_client[id].prev_0e00 = p_client[id].last_0e00;
	p_client[id].last_0e00 = (unsigned int) times(&tms);

	/* if client in tower, then his in_tower == 0x0030 */
	p_client[id].in_tower = (unsigned int) sh_ret(p_client[id].com_buf, 6);

/*
	sprintf(mbuf, "0e00 in_tower = %4.4x",
			(unsigned int) sh_ret(p_client[id].com_buf, 6));
	SendWBMessage(id , HOST_CHL , wb_nick, mbuf);
*/


	p_client[id].time_from_0e00 = (unsigned int) int_ret(p_client[id].com_buf, 2);

/*
	sprintf(mbuf, "0e00 sync = %8.8x",
			(unsigned int) p_client[id].time_from_0e00);
	SendWBMessage(id , HOST_CHL , wb_nick, mbuf);
*/


	p_client[id].time_koeff = (unsigned int) ((unsigned int) times(&tms) - (unsigned int) p_client[id].time_from_0e00);

	sprintf(mbuf, "0e00 time_koeff = %8.8x",
			(unsigned int) p_client[id].time_koeff);
	SendWBMessage(id , HOST_CHL , wb_nick, mbuf);


	p_client[id].x_coord = int_ret(p_client[id].com_buf, 10);
	p_client[id].y_coord = int_ret(p_client[id].com_buf, 14);
	p_client[id].z_coord = int_ret(p_client[id].com_buf, 18);

	/* SH BEGIN */

	p_client[id].vx=sh_ret(p_client[id].com_buf, 22);
	p_client[id].vy=sh_ret(p_client[id].com_buf, 24);
	p_client[id].vz=sh_ret(p_client[id].com_buf, 26);

/*
	sprintf(mbuf, "V0e00=%d %d %d",
					p_client[id].vx,
					p_client[id].vy,
					p_client[id].vz );
	SendWBMessage(id , HOST_CHL , wb_nick, mbuf);
*/

	p_client[id].ax=sh_ret(p_client[id].com_buf, 28);
	p_client[id].ay=sh_ret(p_client[id].com_buf, 30);
	p_client[id].az=sh_ret(p_client[id].com_buf, 32);



	p_client[id].pitch=sh_ret(p_client[id].com_buf, 34);
	p_client[id].bank=sh_ret(p_client[id].com_buf, 36);
	p_client[id].yaw=sh_ret(p_client[id].com_buf, 38);


	p_client[id].vpitch=sh_ret(p_client[id].com_buf, 40);
	p_client[id].vbank=sh_ret(p_client[id].com_buf, 42);
	p_client[id].vyaw=sh_ret(p_client[id].com_buf, 44);

	/* SH END */

	sprintf(mbuf, "%s: nickname %s x=%8.8x y=%8.8x z=%8.8x\n",
	function,
	p_client[id].nickname,
	p_client[id].x_coord,
	p_client[id].y_coord,
	p_client[id].z_coord);

	log_f(9, mbuf);

	p_client[id].set_cc = 1;

#ifdef DRON /* only if test for dron */

	for(k=0; k<CL_NUM; k++)
	{

		name64(p_client[k].nickname, wbchar);
		wbfound = int_ret(wbchar, 0);

		if(wbfound == 0) continue; /* that this cell is empty */
		if(wbfound == wbmain) continue; /* that is my own FE */

	/* now store all coord, pitch, yaw, angle variables according to my FE */

		p_client[k].x_coord=p_client[id].x_coord+p_client[k].rand_x;
		p_client[k].y_coord=p_client[id].y_coord+p_client[k].rand_y;
		p_client[k].z_coord=p_client[id].z_coord+p_client[k].rand_z;
		p_client[k].vx=p_client[id].vx;
		p_client[k].vy=p_client[id].vy;
		p_client[k].vz=p_client[id].vz;
		p_client[k].ax=p_client[id].ax;
		p_client[k].ay=p_client[id].ay;
		p_client[k].az=p_client[id].az;
		p_client[k].pitch=p_client[id].pitch;
		p_client[k].bank=p_client[id].bank;
		p_client[k].yaw=p_client[id].yaw;
		p_client[k].vpitch=p_client[id].vpitch;
		p_client[k].vbank=p_client[id].vbank;
		p_client[k].vyaw=p_client[id].vyaw;
	}
#endif /* DRON */
return;
}



