X-Git-Url: http://royale.zerezo.com/git/?p=zeRace;a=blobdiff_plain;f=server.c;h=6c410cce6366849cf16fddc2fe86b69704698ebd;hp=c6da73074285dfe04e2ccaafcd39ec502029d662;hb=master;hpb=dde2df6289f6daf23ee1632560c4c89061ef2f4a diff --git a/server.c b/server.c index c6da730..6c410cc 100644 --- a/server.c +++ b/server.c @@ -13,6 +13,7 @@ struct _clients int lasttime; struct _car car; IPaddress address; + int dx,dy; } clients [MAX_CLIENTS]; /* UDP stuff */ @@ -21,6 +22,7 @@ UDPpacket *packet; struct _tracklist *tracklist; SDL_Surface *fun; +SDL_Surface *cars[256]; /* return the id of a connected address */ @@ -54,14 +56,14 @@ void announce(char *name,int clients) printf("announcing server... "); fflush(stdout); - if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) + if (SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) { fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError()); return; } tcpsock=SDLNet_TCP_Open(&ip); - if(!tcpsock) + if (!tcpsock) { fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError()); return; @@ -72,31 +74,66 @@ void announce(char *name,int clients) len=strlen(temp); result=SDLNet_TCP_Send(tcpsock,temp,len); - if(resultw;x++) for (y=0;yh;y++) + { + int x2,y2; + x2=(x-cars[j]->w/2.0)*tcos+(y-cars[j]->h/2.0)*tsin+car->w/2.0; + y2=(x-cars[j]->w/2.0)*tsin-(y-cars[j]->h/2.0)*tcos+car->h/2.0; + if (x2>0 && x2w && y2>0 && y2h) + putpixel(cars[j],x,y,getpixel(car,x2,y2)); + } + } + SDL_FreeSurface(car); +} + + /* main program */ int main(int argc,char *argv[]) { int id,i,j,time=0,nb; char *tmp; unsigned char ip[4]; - int nb_laps,network_speed,pub; + int nb_laps,network_speed,pub,col; - if (argc!=5) + if (argc!=6) { fprintf(stderr, - "usage: %s 'server_name' nb_laps network_speed (public|private)\n" + "Usage: %s 'server_name' nb_laps network_speed (public|private) (col|nocol)\n" " server_name : the name of the server\n" " nb_laps : the number of laps to complete for each race\n" " network_speed : frequency of network messages (1 for fast network, 10 for slow network...)\n" " private : this server will not be listed in the 'internet games'\n" + " col : the server will compute collisions between cars\n" ,argv[0] ); exit(1); @@ -105,6 +142,7 @@ int main(int argc,char *argv[]) printf("nb_laps : %d\n",nb_laps=atoi(argv[2])); printf("network_speed : %d\n",network_speed=atoi(argv[3])); printf("public : %d\n",pub=strcmp("private",argv[4])); + printf("col : %d\n",col=strcmp("nocol",argv[5])); if (!zeRace_get_tracks(&tracklist)) exit(1); @@ -132,7 +170,9 @@ int main(int argc,char *argv[]) fprintf(stderr,"SDLNet_AllocPacket: %s\n",SDLNet_GetError()); exit(2); } - + + zeRace_generate_cars(); + for (;;) { /* announce the server on internet if wanted */ @@ -165,10 +205,10 @@ int main(int argc,char *argv[]) *tmp++=1; /* startup countdown */ strcpy(tmp,tracklist->name); tmp+=strlen(tmp)+1; - memcpy(tmp,&time,sizeof(int)); - tmp+=sizeof(int); - memcpy(tmp,&network_speed,sizeof(int)); - tmp+=sizeof(int); + SDLNet_Write32(time,tmp); + tmp+=4; + SDLNet_Write32(network_speed,tmp); + tmp+=4; packet->len=(void *)tmp-(void *)packet->data; for (i=0;idata; - /*printf("%s\n",tmp);*/ /* new connection ? */ if (strcmp(tmp,"connect")==0) @@ -216,7 +256,7 @@ int main(int argc,char *argv[]) tmp+=strlen(tmp)+1; strcpy(clients[i].pseudo,tmp); tmp+=strlen(tmp)+1; - memcpy(&clients[i].car.color,tmp,sizeof(int)); + clients[i].car.color=SDLNet_Read16(tmp); clients[i].car.x=tracklist->x; clients[i].car.y=tracklist->y; clients[i].car.w=30; @@ -233,10 +273,10 @@ int main(int argc,char *argv[]) *tmp++=0; /* no startup countdown */ strcpy(tmp,tracklist->name); tmp+=strlen(tmp)+1; - memcpy(tmp,&time,sizeof(int)); - tmp+=sizeof(int); - memcpy(tmp,&network_speed,sizeof(int)); - tmp+=sizeof(int); + SDLNet_Write32(time,tmp); + tmp+=4; + SDLNet_Write32(network_speed,tmp); + tmp+=4; packet->len=(void *)tmp-(void *)packet->data; SDLNet_UDP_Send(udpsock,-1,packet); break; @@ -262,21 +302,58 @@ int main(int argc,char *argv[]) } else { - int temp; + int temp,x,y,x2,y2; tmp+=strlen(tmp)+1; - memcpy(&temp,tmp,sizeof(int)); - tmp+=sizeof(int); - if (clients[id].lasttime==temp) + temp=SDLNet_Read32(tmp); + tmp+=4; + x=SDLNet_Read32(tmp); + tmp+=4; + y=SDLNet_Read32(tmp); + tmp+=4; + if (clients[id].lasttime<=temp) { - /* printf("servertime = %d lasttime = %d temp = %d strlen(tmp) = %d\n",time,clients[id].lasttime,temp,strlen(tmp)); */ - /*printf("keys = %s\n",tmp);*/ + tmp+=temp-clients[id].lasttime; while (*tmp) { move_car(&clients[id].car,*tmp-'A',fun); - /*printf("%d = %f\n",id,clients[id].car.angle);*/ clients[id].lasttime++; tmp++; } + /* check that the server and the client are still synchronized */ + x2=clients[id].car.x; + y2=clients[id].car.y; + if (x!=x2 || y!=y2) + { + int round; + /* this should not happen with a perfect network protocol :) */ + printf("client %d unsync at %d\n",id,time); + /* instead of dropping the client, we send him a "dumb" collision to resync him */ + tmp=packet->data; + strcpy(tmp,"collision"); + tmp+=strlen(tmp)+1; + SDLNet_Write32(time,tmp); + tmp+=4; + round=(clients[id].car.x+100)*65536; + clients[id].car.x=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[id].car.y+100)*65536; + clients[id].car.y=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[id].car.speed+100)*65536; + clients[id].car.speed=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[id].car.angle+100)*65536; + clients[id].car.angle=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + packet->len=(void *)tmp-(void *)packet->data; + packet->address=clients[id].address; + SDLNet_UDP_Send(udpsock,-1,packet); + clients[id].lasttime=time; + } } } } @@ -292,31 +369,121 @@ int main(int argc,char *argv[]) clients[i].connected=0; } + /* should we check for collisions ? */ + if (col) + { + /* check for collisions */ + for (i=0;i0 && x2<30 && y2>0 && y2<30) + { + if (getpixel(cars[(unsigned char)(256*clients[j].car.angle/2.0/M_PI)%256],x2,y2)!=0) + { + if (x1<30/2) { clients[i].dx++; clients[j].dx--; } else { clients[i].dx--; clients[j].dx++; } + if (y1<30/2) { clients[i].dy++; clients[j].dy--; } else { clients[i].dy--; clients[j].dy++; } + } + } + } + } + + /* now compute the collisions */ + for (i=0;i5) dx/=2; + while (abs(dy)>5) dy/=2; + /* get the pixel color under the center of car in the function map */ + c=getpixel(fun,clients[i].car.x+dx,clients[i].car.y+dy); + /* green layer (road quality) */ + SDL_GetRGB(c,fun->format,&t,&g,&t); + /* if the destination is not a wall and not outside of the track */ + if (g!=0 && clients[i].car.x>cars[0]->w && clients[i].car.xw-cars[0]->w && clients[i].car.y>cars[0]->h && clients[i].car.yh-cars[0]->h) + { + int round; + clients[i].car.x+=dx; + clients[i].car.y+=dy; + tmp=packet->data; + strcpy(tmp,"collision"); + tmp+=strlen(tmp)+1; + SDLNet_Write32(time,tmp); + tmp+=4; + round=(clients[i].car.x+100)*65536; + clients[i].car.x=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[i].car.y+100)*65536; + clients[i].car.y=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[i].car.speed+100)*65536; + clients[i].car.speed=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[i].car.angle+100)*65536; + clients[i].car.angle=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + packet->len=(void *)tmp-(void *)packet->data; + packet->address=clients[i].address; + SDLNet_UDP_Send(udpsock,-1,packet); + clients[i].lasttime=time; + } + } + } + /* send update to clients */ if (time%network_speed==0) for (i=0;idata; strcpy(tmp,"positions"); tmp+=strlen(tmp)+1; - memcpy(tmp,&time,sizeof(int)); - tmp+=sizeof(int); /* for server time */ - tmp+=sizeof(int); /* for client time */ - tmp+=sizeof(int); /* for number of cars */ + SDLNet_Write32(time,tmp); + tmp+=4; /* for server time */ + tmp+=4; /* for client time */ + tmp+=2; /* for number of cars */ nb=0; for (j=0;jdata+strlen("positions")+1+sizeof(int)+sizeof(int),&nb,sizeof(int)); + SDLNet_Write16(nb,packet->data+strlen("positions")+1+4+4); + SDLNet_Write32(clients[i].lasttime,packet->data+strlen("positions")+1+4); packet->len=(void *)tmp-(void *)packet->data; - memcpy(packet->data+strlen("positions")+1+sizeof(int),&clients[i].lasttime,sizeof(int)); packet->address=clients[i].address; SDLNet_UDP_Send(udpsock,-1,packet); } /* did someone finish the track ? */ + for (i=0;idata; strcpy(tmp,"finish"); tmp+=strlen(tmp)+1; - tmp+=sizeof(int); /* space for number */ + tmp+=2; /* space for number */ nb=0; for (i=0;i<10;i++) { @@ -343,14 +510,14 @@ int main(int argc,char *argv[]) { sprintf(tmp,"%s : %d",clients[best_id].pseudo,best_sc); tmp+=strlen(tmp)+1; - memcpy(tmp,&clients[best_id].car.color,sizeof(int)); - tmp+=sizeof(int); + SDLNet_Write16(clients[best_id].car.color,tmp); + tmp+=2; clients[best_id].car.lap=-1; nb++; printf("top %d : %s - %d\n",nb,clients[best_id].pseudo,best_sc); } } - memcpy(packet->data+strlen("finish")+1,&nb,sizeof(int)); + SDLNet_Write16(nb,packet->data+strlen("finish")+1); packet->len=(void *)tmp-(void *)packet->data; for (i=0;inext; }