#include "bomber.h" #include "announce.h" #include "game.h" #include "menu.h" #include "network.h" #include "utils.h" #define MAXMSG 4096 int udpsocket; const unsigned char gameversion[4]={0xda,0x01,0x00,0x04}; struct netnode netnodes[64]; static int informsize; static unsigned char regpacket[64]; static struct sockaddr_in myname={0},mastername={0}; static socklen_t senderlength; static struct sockaddr_in sender={0}; static unsigned char mesg[MAXMSG]=""; uchar needwhole=0; int mydatacount; int myslot; network_type network = NETWORK_NONE; static unsigned char hist[ACTIONHIST][MAXNETNODES]; int actionput,actioncount; unsigned char actionblock[ACTIONHIST*MAXNETNODES]; int myaction; unsigned char actions[MAXNETNODES]; unsigned char latestactions[MAXNETNODES]; long latestcounts[MAXNETNODES]; /* Network I/O, building/checking packets */ #if defined (TEST_LATENCY) #define NUMQ 512 struct message { int time; struct sockaddr_in *to; int tosize; unsigned char msg[512]; int len; } message[NUMQ]={0}; outmsgs() { int i; for(i=0;i>24L; p[1]=i>>16L; p[2]=i>>8L; p[3]=i; return p+4; } static Uint32 readuint32(unsigned char *p) { return (p[0]<<24L) | (p[1]<<16L) | (p[2]<<8) | p[3]; } static unsigned char* writeunique(unsigned char *p) { memcpy(p, &network_unique, 4); return p + 4; } static unsigned char* writeversion(unsigned char *p) { memcpy(p, &gameversion, 4); return p + 4; } static int isvalidmsg() { int i; void *host; void *port; if (!isvalidunique(mesg+1)) return -1; host=&sender.sin_addr.s_addr; port=&sender.sin_port; for(i=1;i0) { j=actionput-i-1; if(j<0) j+=ACTIONHIST; memmove(p,hist[j],MAXNETNODES); } else { memset(p,0,MAXNETNODES); } p+=MAXNETNODES; ++i; } } static void sendactions(int which) { unsigned char msg[512]; msg[0] = PKT_STEP; writeunique(msg+1); writeuint32(msg+5, actioncount); memcpy(msg+9,actionblock,MAXNETNODES*ACTIONHIST); putmsg(&netnodes[which].netname,msg,MAXNETNODES*ACTIONHIST+9); } static void sendmine(int frame) { unsigned char msg[64]; msg[0] = PKT_MYDATA; writeunique(msg+1); writeuint32(msg+5, frame); msg[9]=myaction; putmsg(&mastername,msg,10); } int networktraffic(void) { int i; int length; int whosent; unsigned char newactions[MAXNETNODES]; long now; long count; switch (network) { case NETWORK_NONE: return -1; case NETWORK_MASTER: memcpy(newactions,latestactions,MAXNETNODES); newactions[0]=myaction; now=gtime(); for(;;) { if(gtime()-now>15) break; length=getmsg(5); if(length>0 && *mesg!=PKT_MYDATA) fprintf(stderr, "Strange packet %d\n", (int) *mesg); // check for unexpected old packets... // for example JOIN on frame 0, respond with BEGIN if player already in game // respond with uninvite INVITE on JOIN from others if(length<10) continue; whosent=isvalidmsg(); if(whosent<=0) continue; count=readuint32(mesg+5); if(count>latestcounts[whosent]) { latestcounts[whosent]=count; newactions[whosent]=mesg[9]; } } if(myaction==ACT_QUIT) { for(i=1;i=1) { lastsent=gtime(); sendmine(mydatacount); } */ if(latest>=0 && gtime()-now>3) break; length=getmsg(3); if(length==MAXNETNODES*ACTIONHIST+9 && sender.sin_addr.s_addr==mastername.sin_addr.s_addr && sender.sin_port==mastername.sin_port) { i=readuint32(mesg+5); if(i=17) { if((i=*take)