📄 bnserver.c
字号:
wprintd(titles[num_jug],"\nPlayer %i, -NOT CONNECTED- ",num_jug+1);}/* * Funcion principal */int play_batnav( int fd ) { int i,j,x,y; char outbuf[MSGMAXLEN]; struct protocolo proto; char pre[4]=""; /* para versiones preX de los clientes*/ /* modify on v0.50 */ if( read(fd,&proto,MAXLEN) != MAXLEN ) return(-1); if( (proto.bnphead[0]!='B') || (proto.bnphead[1]!='N') || (proto.bnphead[2]!='P')) return(0); j=proto.jugador-1; switch (proto.bnptip0) { case BNREA: x=proto.bnptip1-1; /* which player do you want to read */ if( usuario.nro_tot[x]>=BOARD ) { rtable(outbuf,x,proto.bnptip2); bnwrite(fd,outbuf,BNREA,x,0,j); /* i'm sending the board */ wprintd(windows[j],"\nReading board from player %i",x+1); } else wprintd(windows[j],"\nReading board form dead player %i",x+1); break; case BNWRI: for(i=0;i<MAXPLAYER;i++) { if( usuario.nro_tot[i]>=3) break; } if(i!=MAXPLAYER) { /* im sorry but people is playing */ bnwrite(fd,outbuf,BNWAI,0,0,0); wprintd(windows[j],"\nSending board...Wait people are playing"); } else { if( wtable(j,&proto)==TRUE) { usuario.nro_tot[j]=2; /* send board ok */ outbuf[0]=1; broadcast(outbuf,BNCON,1,j,j+1,0,0); wprintd(windows[j],"\nSending board... OK, ready to play"); } else { usuario.nro_tot[j]=1; /* send board not ok */ outbuf[0]=0; } bnwrite(fd,outbuf,BNWRI,0,0,0); } break; case BNJUG: for(i=0;i<MAXPLAYER;i++) { if(usuario.nro_tot[i]==0) break; } if(i==MAXPLAYER) /* im sorry, server is full*/ bnwrite(fd,outbuf,BNALL,i+1,0,i+1); else { strcpy(usuario.names[i],proto.bnpmsg); /* new on v0.36 */ sprintf(tempbuf,"[%i]",i+1); strcat(usuario.names[i],tempbuf); usuario.nro_tot[i]=1; /* connected */ usuario.nro_fd[i]=fd; strcpy(outbuf,usuario.server_name); /* new on v0.41 */ bnwrite(fd,outbuf,BNJUG,i+1,0,i+1); wprintd(windows[i],"\nConnecting to server.BNP version 0x%X",proto.bnpver); if(proto.jugador<0) { strcpy(pre,"pre"); proto.jugador*=-1; } if(proto.bnpver>=0x11) { switch(proto.bnptip1) { case XCLI: wprintd(windows[i],"\nUsing xbtclient ver.%s%i.%i",pre,proto.bnptip2,proto.jugador); break; case NCLI: wprintd(windows[i],"\nUsing nbtclient ver.%s%i.%i",pre,proto.bnptip2,proto.jugador); break; case WCLI: wprintd(windows[i],"\nUsando cliente Win16 ver.%s%i.%i",pre,proto.bnptip2,proto.jugador); break; case GCLI: wprintd(windows[i],"\nUsando cliente GTK ver.%s%i.%i",pre,proto.bnptip2,proto.jugador); break; default: wprintd(windows[i],"\nUsando cliente desconocido ver.%s%i.%i",pre,proto.bnptip2,proto.jugador); break; } } wprintd(titles[i],"\nPlayer %i, name:'%s'",i+1,usuario.names[i]); } break; case BNVER: outbuf[0]=BNVERH; outbuf[1]=BNVERL; bnwrite(fd,outbuf,BNVER,0,0,0); wprintd(windows[j],"\nAsking server version..."); break; case BNMSG: /* new on v0.34 */ sprintf(outbuf,"Player %i:",j+1); /* from who */ strcat(outbuf,proto.bnpmsg); if(proto.bnptip1==0) broadcast(outbuf,BNMSG,1,j,0,0,j+1); else { if(usuario.nro_tot[proto.bnptip1-1]>=1) bnwrite(usuario.nro_fd[proto.bnptip1-1],outbuf,BNMSG,0,0,j+1); } if(proto.bnptip2==1) bnwrite(fd,outbuf,BNMSG,0,0,j+1); wprintd(windows[j],"\nSending message to player %i...",proto.bnptip1); break; case BNTST: bnwrite(fd,outbuf,BNTST,0,0,0); wprintd(windows[j],"\nTesting..."); break; case BNEXT: bnexit(j,0); close(fd); FD_CLR(fd,&test_set); break; case BNHIT: if(usuario.nro_tot[j]==4) { /* is it my turn */ x=outbuf[0]=proto.bnpmsg[0]; y=outbuf[1]=proto.bnpmsg[1]; for(i=0;i<MAXPLAYER;i++) { if(usuario.nro_tot[i]>=3) { /* started ?*/ if(i!=j) { /* dont shoot shooter */ if(usuario.table[i].p[x][y]>=1) { if(eshundido(i,x,y)==FALSE) { /* */ outbuf[2]=TOCADO; usuario.table[i].p[x][y]=TOCADO; /* tocado */ bnwrite(usuario.nro_fd[i],outbuf,BNHIT,0,0,i+1); } } else if(usuario.table[i].p[x][y]<=0) { outbuf[2]=AGUA; usuario.table[i].p[x][y]=AGUA; /* agua */ bnwrite(usuario.nro_fd[i],outbuf,BNHIT,0,0,i+1); } } } } /* apartir del siguiente jugador */ usuario.nro_tot[j]=3; /* it is no more your turn */ for(i=proto.jugador;i<MAXPLAYER;i++) { if(usuario.nro_tot[i]==3) break; } if(i==MAXPLAYER) { /* llego al ultimo */ for(i=0;i<MAXPLAYER;i++) { if(usuario.nro_tot[i]==3) break; } } if( (i==j) || (i==MAXPLAYER)) { /* si el turno es para el mismo jugador gano */ bnwrite(usuario.nro_fd[i],outbuf,BNWIN,0,0,i+1); sprintf(outbuf,"The Game is over: Player %i is the winner.",i+1); /* usuario.nro_tot[i]=1; */ /* usuario.hits[i]=0;*/ /* ctable(i);*/ /* clear board */ /* todo esto comentado en la 0.48 */ /* usuario.names[i][0]=0; */ /* esto estaba comentado antes... */ broadcast(outbuf,BNEXT,1,i,i+1,2,0); wprintd(windows[i],"\nGame Over - I'am the winner"); wprintd(windows[i],"\n- - - - -"); wprintd(titles[i],"\nPlayer %i, name:'%s'",i+1,usuario.names[i]); /* Se acabo el juego, limpiar tableros... */ for(i=0;i<MAXPLAYER;i++) if(usuario.nro_tot[i]>=CONNEC) { /* Si el usuario estaba conectado limpiar todo */ usuario.nro_tot[i]=CONNEC; usuario.hits[i] =0; ctable(i); } } else { usuario.nro_tot[i]=4; /* siguiente turno */ bnwrite(usuario.nro_fd[i],outbuf,BNTRN,0,0,i+1); broadcast(outbuf,BNWHO,3,i,i+1,0,0); /* informa de quien es */ wprintd(windows[i],"\nIt is my turn"); } wprintd(windows[j],"\nFiring at (x,y)=%i,%c...",x,'A'+y); } break; case BNSTR: x=0; /* used as a temp variable */ for(i=0;i<MAXPLAYER;i++) { /* added in ver 0.29 */ if(usuario.nro_tot[i]>=2) x++; } if(x<2) { bnwrite(usuario.nro_fd[j],outbuf,BNSOL,0,0,j); wprintd(windows[j],"\nStarting the game...Can't play alone"); } else { for(i=0;i<MAXPLAYER;i++) { /* new on v0.32 */ outbuf[i]=usuario.nro_tot[i]; /* show status of other players */ strcpy(&outbuf[5+i*MAXNAMELEN],usuario.names[i]); /* new on v0.36 */ } for(i=0;i<MAXPLAYER;i++) { if(usuario.nro_tot[i]>=2) { /* BUG fixed in 0.29 */ bnwrite(usuario.nro_fd[i],outbuf,BNSTR,0,0,i+1); usuario.nro_tot[i]=3; /* started */ } } wprintd(windows[j],"\nStarting the game...OK"); sleep(1); /* can this help. new on v0.33 */ for(i=0;i<MAXPLAYER;i++) { if(usuario.nro_tot[i]==3) { bnwrite(usuario.nro_fd[i],outbuf,BNTRN,0,0,i+1); usuario.nro_tot[i]=4; wprintd(windows[i],"\nIt is my turn"); break; /* started */ } } } break; case BNSTS: /* new on v0.43 */ for(i=0;i<MAXPLAYER;i++) { outbuf[i]=usuario.nro_tot[i]; strcpy(&outbuf[5+i*MAXNAMELEN],usuario.names[i]); } bnwrite(fd,outbuf,BNSTS,0,0,i+1); wprintd(windows[j],"\nAsking status of players"); break; default: wprintd(windows[j],"\n*** WARNING:Sending unknown code:%X",proto.bnptip0); break; } return 0;}void init_screen(void) { int i; initscr(); keypad(stdscr, TRUE); noecho(); scrollok(stdscr, TRUE); title=newwin(8,40,0,0); wattrset(title,A_BOLD); sprintf(tempbuf,"Batalla Naval Server v"BN_SVER); i=strlen(tempbuf); mvwprintw(title,0,20-(i/2),tempbuf); sprintf(tempbuf,"(c) 1995,96,97,98 Ricardo Quesada"); i=strlen(tempbuf); mvwprintw(title,1,20-(i/2),tempbuf); sprintf(tempbuf,"Hecho en Buenos Aires, Argentina"); i=strlen(tempbuf); mvwprintw(title,2,20-(i/2),tempbuf); sprintf(tempbuf,"Running at port %i",usuario.port); i=strlen(tempbuf); mvwprintw(title,4,20-(i/2),tempbuf); sprintf(tempbuf,"in host:%s",usuario.server_name); i=strlen(tempbuf); mvwprintw(title,5,20-(i/2),tempbuf); sprintf(tempbuf,"Send bugs to rquesada@dc.uba.ar"); i=strlen(tempbuf); mvwprintw(title,7,20-(i/2),tempbuf); wrefresh(title); for(i=0;i<MAXPLAYER;i++) { titles[i] =newwin(1,40,((i+1)/2)*8,40*((i+1)%2)); windows[i]=newwin(7,40,(((i+1)/2)*8)+1,40*((i+1)%2)); scrollok(windows[i], TRUE); scrollok(titles[i],TRUE); wattrset(titles[i],A_REVERSE); wattrset(windows[i],A_NORMAL); wprintd(titles[i],"\nPlayer %i, -NOT CONNECTED- ",i+1); wrefresh(titles[i]); }}/***************** * main function * *****************/void help() { printf("\n\nBatalla Naval server v"BN_SVER" (c) 1995,96,97,98 Ricardo Quesada\n"); printf("\nsyntax:"); printf("\nbtserver [-p server_port] [-d]"); printf("\n\t-p server_port The port number that btserver will listen to"); printf("\n\t default is: 1995"); printf("\n\t-d With this option you can monitor the users."); printf("\n\t Recommended! - Dont put me in backgroud!."); printf("\n\t-x Same as -d."); printf("\n\nSend bugs,doubts,fixes to rquesada@dc.uba.ar\n"); exit(-1);}void main(int argc, char *argv[]) { int sock,fd,client_len; int max_fd,i; struct rlimit limit_info; struct sockaddr_in server; struct sockaddr client; char deb[2][4]; strcpy(deb[0],"OFF"); strcpy(deb[1],"ON"); gethostname(usuario.server_name,MSGMAXLEN); /* new on v0.37 & 0.41 */ usuario.port=1995; usuario.debug=FALSE; for(i=1;i<argc;i++) { if(argv[i][0]=='-') { switch(argv[i][1]) { case 'p': case 'P': if(argc>i+1) usuario.port=atoi(argv[i+1]); else help(); break; case 'x': case 'X': case 'd': case 'D': usuario.debug=TRUE; break; case 'h': case 'H': case '?': case '-': default: help(); break; } } else { if(argv[i-1][0]!='-') help(); } } printf("Batalla Naval server v"BN_SVER" (c) 1995,96,97,98\n" "by Ricardo Quesada. <rquesada@dc.uba.ar>\n" "Running... (port=%i, name=%s, max players=%i, debug=%s)\n" "btserver -d for debug mode (monitor).\n",usuario.port,usuario.server_name,MAXPLAYER,deb[usuario.debug]); /* Set default parameters */ for(i=0;i<MAXPLAYER;i++) { usuario.nro_tot[i]=0; usuario.nro_fd[i]=0; ctable(i); } if(getrlimit(RLIMIT_NOFILE,&limit_info) <0) { perror("btserver getrlimit error"); exit(1); } sock=socket(AF_INET,SOCK_STREAM,0); if(sock <0) { perror("btserver socket error"); exit(1); } server.sin_family=AF_INET; server.sin_addr.s_addr=htonl(INADDR_ANY); server.sin_port=htons(usuario.port); if(bind(sock,(struct sockaddr *)&server,sizeof(server))< 0) { perror("btserver bind error"); exit(2); } if(usuario.debug==TRUE) init_screen(); listen(sock,10); max_fd=sock; FD_ZERO(&test_set); FD_SET(sock,&test_set); while(1) { memcpy(&ready_set,&test_set,sizeof(test_set)); select(max_fd+1,&ready_set,NULL,NULL,NULL); if(FD_ISSET(sock,&ready_set)) { client_len = sizeof(client); fd=accept(sock,(struct sockaddr *)&client,&client_len); FD_SET(fd,&test_set); if(fd>max_fd) max_fd=fd; } for(fd=0;fd<=max_fd;fd++) { if((fd!=sock) && FD_ISSET(fd,&ready_set)) { if(play_batnav(fd)<0) { for(i=0;i<MAXPLAYER;i++) { /* before closing...*/ if ( (usuario.nro_fd[i]!=sock) && (fd==usuario.nro_fd[i]) ) { bnexit(i,1); break; } } close(fd); FD_CLR(fd,&test_set); } } /* if(fd!=sock */ } /* for(fd=0) */ } /* while(1) */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -