Advertisement
Guest User

isas.c

a guest
Feb 24th, 2020
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 30.70 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <unistd.h>
  6. #include <pthread.h>
  7. #include <sys/types.h>
  8. #include <fcntl.h>
  9. #include <sys/socket.h>
  10. #include <netdb.h>
  11. #include <netinet/in.h>
  12. #include <arpa/inet.h>
  13. #include <signal.h>
  14.  
  15. #define MAX 300
  16. #define QUEUE 30
  17. #define ROWS 10
  18. #define COLS 20
  19. #define ANSI_COLOR_YELLOW "\x1b[01;33m"
  20. #define ANSI_COLOR_RESET "\x1b[0m"
  21.  
  22. int connectedClients=0;
  23. int disconnectedClients=0;
  24. int pack=0; //pacchi totali nella matrice: il gioco termina quando si azzerano i pacchi
  25. int flagGame=1; //flag per dare il via ad una nuova sessione di gioco una volta terminata quella corrente
  26. char game[ROWS][COLS]; //matrice di gioco
  27.  
  28. pthread_mutex_t ClientMutex = PTHREAD_MUTEX_INITIALIZER; //per la sincronizzazione tra i thread client
  29. pthread_mutex_t FileUserMutex = PTHREAD_MUTEX_INITIALIZER; //per il file FileUSER.txt
  30. pthread_mutex_t FileLogMutex = PTHREAD_MUTEX_INITIALIZER; //per il file FileLOG.txt
  31. pthread_mutex_t MatrixMutex = PTHREAD_MUTEX_INITIALIZER; //per la matrice di gioco
  32. pthread_mutex_t PackMutex = PTHREAD_MUTEX_INITIALIZER; //per il numero globale di pacchi
  33. pthread_mutex_t PackTimeMutex = PTHREAD_MUTEX_INITIALIZER; //per la matrice astratta di pacchi
  34.  
  35.  
  36. struct pack{ //struttura dati associata ad ogni pacco
  37.  
  38.     int check; //assume valore 0 o 1 se il pacco è stato prelevato
  39.     double time; //tempo di scadenza
  40.     time_t timeDeliver; //tempo consegna
  41.     time_t timePick; //tempo di prelevamento
  42.  
  43. };
  44. struct pack packTime[ROWS][COLS]; //matrice di struct pack
  45.  
  46. struct user { //struttura dati associata ad ogni utente
  47.  
  48.     int sockfd; // valore della connessione
  49.     int logged; // assume valore 0 o 1 se l'utente è loggato o no
  50.     char username[30]; //username login
  51.     char password[30]; //password login
  52.     int x; //riga della matrice dove si trova l'utente
  53.     int y; //colonna della matrice dove si trova l'utente
  54.     int xp; //riga del pacco prelevato dall'utente nella matrice
  55.     int yp; //colonna del pacco prelevato dall'utente nella matrice
  56.     int packages; //assume valore 0 o 1 se il giocatore ha prelevato un pacco(1 pacco alla volta)
  57.     int totalPack; //numero totale di pacchi prelevati in una sessione
  58.     int inGame; //assume valore 0 o 1 se l'utente è in sessione di gioco
  59.  
  60. };
  61. typedef struct user t_user;
  62. t_user *OnlineUsers[QUEUE]; //array di puntatori a struct user
  63.  
  64.  
  65. //FUNZIONI
  66.  
  67.  
  68. /* Add clients to queue */
  69. void QueueAdd(t_user *user){
  70.  
  71.     for(int i=0;i<QUEUE;i++){
  72.         if(!OnlineUsers[i]){
  73.             pthread_mutex_lock(&ClientMutex);
  74.             OnlineUsers[i]=user;
  75.             memset(OnlineUsers[i]->username,'\0',sizeof(OnlineUsers[i]->username));
  76.             memset(OnlineUsers[i]->password,'\0',sizeof(OnlineUsers[i]->password));
  77.             OnlineUsers[i]->logged=0;
  78.             OnlineUsers[i]->inGame=0;
  79.             OnlineUsers[i]->packages=0;
  80.             OnlineUsers[i]->totalPack=0;
  81.             pthread_mutex_unlock(&ClientMutex);
  82.             break;
  83.         }
  84.     }
  85. }
  86.  
  87. /* Checks some user properties based on tha FLAG */
  88. int SearchUser(int connection, int flag, char buffer[]){
  89.  
  90.     int ret=-1, max=0, j=0;
  91.     char user[MAX];
  92.  
  93.     if(flag==4){
  94.         while(buffer[j]!=' ') j++;
  95.         strncpy(user,&buffer[0],j); //estraggo username
  96.         user[j+1]='\0';
  97.     }
  98.     for(int i=0;i<QUEUE; i++){
  99.         if(OnlineUsers[i]){
  100.             if(flag==1 && OnlineUsers[i]->sockfd==connection)ret=i; //ritorno la connessione
  101.             if(flag==2 && OnlineUsers[i]->logged==1 && max<OnlineUsers[i]->totalPack){ //cerco il vincitore
  102.                 max=OnlineUsers[i]->totalPack;
  103.                 ret=OnlineUsers[i]->sockfd;
  104.             }
  105.             if(flag==3 && OnlineUsers[i]->sockfd==connection && OnlineUsers[i]->logged==1) ret=1; //utente loggato
  106.             if(flag==4 && strcmp(OnlineUsers[i]->username,user)==0) ret=1; //credenziali gia esistenti
  107.         }
  108.     }
  109.     return ret;
  110. }
  111.  
  112. /* Remove clients from queue */
  113. void QueueRemove(int connection){
  114.  
  115.     pthread_mutex_lock(&ClientMutex);
  116.     OnlineUsers[SearchUser(connection,1,NULL)]=NULL;
  117.     pthread_mutex_unlock(&ClientMutex);
  118. }
  119.  
  120. /* Insert credentials of an user logged in into queue */
  121. void PopulateQueue(char buffer[], int length, int connection){
  122.  
  123.     char user[MAX], pwd[MAX];
  124.     int j=0;
  125.  
  126.     for(int i=0; i<QUEUE; i++){
  127.         if(OnlineUsers[i]&&OnlineUsers[i]->sockfd==connection){
  128.             pthread_mutex_lock(&ClientMutex);
  129.             OnlineUsers[i]->logged=1;
  130.             pthread_mutex_unlock(&ClientMutex);
  131.  
  132.             while(buffer[j]!=' ') j++;
  133.             pthread_mutex_lock(&ClientMutex);
  134.             strncpy(user,&buffer[0],j); //copio lo username
  135.             user[j+1]='\0';
  136.  
  137.             memcpy(OnlineUsers[i]->username,user,j);
  138.             strncpy(pwd,&buffer[++j],length); //copio la password
  139.             pwd[length-j]='\0';
  140.             memcpy(OnlineUsers[i]->password,pwd,length-j);
  141.             pthread_mutex_unlock(&ClientMutex);
  142.             break;
  143.         }
  144.     }
  145. }
  146.  
  147. /* Delete client's connection after an abort */
  148. void ClientAbort(int connection){
  149.  
  150.     pthread_mutex_lock(&ClientMutex);
  151.     connectedClients--; //aggiorno variabili globali
  152.     disconnectedClients++;
  153.     pthread_mutex_unlock(&ClientMutex);
  154.     QueueRemove(connection); //rimuovo il client dalla coda di quelli connessi
  155.  
  156.     printf("[+]Client [%d] aborted.\n", connection);
  157.     signal(SIGPIPE,SIG_IGN); //se un client termina in modo anomalo gestisco SIGPIPE e non faccio terminare il server
  158. }
  159.  
  160. /* Create FileLOG with all activities of users: connection, packages picked up, etc. */
  161. void FileLogUser(struct sockaddr_in Caddr, int connection, time_t pack, int flag){
  162.  
  163.     srand(time(NULL));
  164.     int nbytes=0, fd=0;
  165.     char buffer[MAX];
  166.     time_t rawtime;
  167.     time(&rawtime);
  168.     struct tm * timeinfo=localtime(&rawtime);
  169.  
  170.     if((fd=open("FileLOG.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR))<0){
  171.         perror("[-]Error FileLOG.\n");
  172.         exit(1);
  173.     }
  174.     if(!fd) perror("[-]FileLOG not exist.\n");
  175.     else{
  176.         if(flag==1) nbytes=sprintf(buffer,"[IP]: %s\t[CURRENT LOCAL TIME & DATE]: %s", inet_ntoa(Caddr.sin_addr), asctime(timeinfo));
  177.         if(flag==2 && OnlineUsers[SearchUser(connection,1,NULL)]->inGame==0) nbytes=sprintf(buffer,"[USER]: %s\t[CURRENT LOCAL TIME & DATE]:    %s", OnlineUsers[SearchUser(connection,1,NULL)]->username,asctime(timeinfo));
  178.         else if(flag==2 && OnlineUsers[SearchUser(connection,1,NULL)]->inGame!=0) nbytes=sprintf(buffer,"[USER]: %s\t[PACKAGE DELIVER'S TIME & DATE]: %s",OnlineUsers[SearchUser(connection,1,NULL)]->username,ctime(&pack));
  179.  
  180.         pthread_mutex_lock(&FileLogMutex);
  181.         write(fd,buffer,nbytes);
  182.         pthread_mutex_unlock(&FileLogMutex);
  183.     }
  184.     close(fd);
  185. }
  186.  
  187. /* Verify that the user is present in the FileUser */
  188. int CheckUser(char *buffer){
  189.  
  190.     char user[MAX], pwd[MAX];
  191.     FILE *fd;
  192.  
  193.     if((fd=fopen("FileUSER.txt","r"))<0){
  194.         perror("[-]Error FileUSER.\n");
  195.         exit(1);
  196.     }
  197.     if(!fd) perror("[-]FileUSER not exist.\n");
  198.     else{
  199.         while(!feof(fd)){
  200.             fscanf(fd,"%s %s", user, pwd);
  201.             strcat(user," ");
  202.             strcat(user, pwd);
  203.             strcat(user,"\n");
  204.             if(strcmp(buffer,user)==0) return 1;
  205.         }
  206.     }
  207.     return 0;
  208. }
  209.  
  210. /* Register the user */
  211. void Registration(int connection){
  212.  
  213.     char buffer[MAX], buffer2[MAX];
  214.     int nbytes=0, fd=0;
  215.  
  216.     if((fd=open("FileUSER.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR))<0){
  217.         perror("[-]Error FileUSER.\n");
  218.         exit(1);
  219.     }
  220.     else{
  221.         if(SearchUser(connection,3,NULL)!=1){
  222.  
  223.             nbytes=sprintf(buffer2,"OK");
  224.             write(connection,buffer2,nbytes);
  225.  
  226.             nbytes=read(connection,buffer,MAX);
  227.             buffer[nbytes]='\0';
  228.             nbytes=read(connection,buffer2,MAX);
  229.             buffer2[nbytes]='\0';
  230.  
  231.             if(strcmp(buffer,"abort")==0)ClientAbort(connection);
  232.             else{
  233.                 strcat(buffer," ");
  234.                 strcat(buffer,buffer2);
  235.                 strcat(buffer,"\n");
  236.  
  237.                 if(CheckUser(buffer)==0){
  238.                     pthread_mutex_lock(&FileUserMutex);
  239.                     write(fd,buffer,strlen(buffer));
  240.                     pthread_mutex_unlock(&FileUserMutex);
  241.                     nbytes=sprintf(buffer2,"[+]Registered successfully.\n");
  242.                     printf("[+]Client [%d] registered.\n",connection);
  243.                 }
  244.                 else nbytes=sprintf(buffer2,"[+]User with these credentials already exists, please retry.\n");
  245.  
  246.                 write(connection,buffer2,nbytes);
  247.                 close(fd);
  248.             }
  249.         }
  250.         else{
  251.             nbytes=sprintf(buffer2,"[+]You cannot register, you already logged in.\n");
  252.             write(connection,buffer2,nbytes);
  253.         }
  254.     }
  255. }
  256.  
  257. /* Login the user */
  258. void Login(int connection){
  259.  
  260.     int nbytes=0;
  261.     char buffer[MAX], buffer2[MAX];
  262.     time_t TimeNULL;
  263.     struct sockaddr_in Caddr;
  264.  
  265.     nbytes=read(connection,buffer,MAX);
  266.     buffer[nbytes]='\0';
  267.     nbytes=read(connection,buffer2,MAX);
  268.     buffer2[nbytes]='\0';
  269.  
  270.     if(strcmp(buffer,"abort")==0)ClientAbort(connection);
  271.     else{
  272.         strcat(buffer," ");
  273.         strcat(buffer,buffer2);
  274.         strcat(buffer,"\n");
  275.  
  276.         if(SearchUser(connection,4,buffer)!=1){
  277.             if(CheckUser(buffer)==1&&SearchUser(connection,3,NULL)!=1){
  278.                 nbytes=sprintf(buffer2,"[+]Login done successfully!\n");
  279.                 PopulateQueue(buffer,strlen(buffer),connection);
  280.                 FileLogUser(Caddr,connection,TimeNULL,2);
  281.                 printf("[+]Client [%d] logged in.\n",connection);
  282.             }
  283.             else if(CheckUser(buffer)==0) nbytes=sprintf(buffer2,"[+]You're not registered to login or bad credentials, retry.\n");
  284.  
  285.             else if(SearchUser(connection,3,NULL)==1) nbytes=sprintf(buffer2,"[+]Login already done.\n");
  286.         }
  287.         else nbytes=sprintf(buffer2,"[+]Login already done by another user with these credentials.\n");
  288.  
  289.         write(connection,buffer2,nbytes);
  290.     }
  291. }
  292.  
  293. /* List of logged in users */
  294. void ConnectedUsers(int connection,int var){
  295.  
  296.     int nbytes=0;
  297.     char message[MAX], buffer[MAX];
  298.  
  299.     *message='\0';
  300.     for(int i=0;i<QUEUE;i++){
  301.         if(OnlineUsers[i]){
  302.             memcpy(buffer,OnlineUsers[i]->username, sizeof(OnlineUsers[i]->username));
  303.             strcat(message, buffer);
  304.             strcat(message, "-");
  305.         }
  306.     }
  307.     if(var==4)strcat(message,"\n");
  308.     nbytes=strlen(message);
  309.     write(connection,message,nbytes);
  310. }
  311.  
  312. void Dis_ConnectedClients(int connection, int flag){
  313.  
  314.     int nbytes=0;
  315.     char buffer[MAX];
  316.  
  317.     if(flag==1) nbytes=sprintf(buffer,"[+]Number of connected clients: %d\n", connectedClients);
  318.     else if(flag==2) nbytes=sprintf(buffer,"[+]Number of disconnected clients: %d\n", disconnectedClients);
  319.     write(connection,buffer,nbytes);
  320. }
  321.  
  322. /* Insert user into the matrix game */
  323. void InsertUser(int connection){
  324.  
  325.     int index1=0, index2=0, user=0;
  326.  
  327.     for(int i=0;i<ROWS;i++){
  328.         for(int j=0;j<COLS;j++){
  329.  
  330.             index1=rand()%COLS;
  331.             index2=rand()%COLS;
  332.  
  333.             if(user==0&&game[index1][index2]==' '){
  334.                 user++; //effettuo tale operazione una volta sola per 1 utente
  335.  
  336.                 pthread_mutex_lock(&MatrixMutex);
  337.                 game[index1][index2]='A'+connection;
  338.                 pthread_mutex_unlock(&MatrixMutex);
  339.  
  340.                 pthread_mutex_lock(&ClientMutex);
  341.                 OnlineUsers[SearchUser(connection,1,NULL)]->x=index1;
  342.                 OnlineUsers[SearchUser(connection,1,NULL)]->y=index2;
  343.                 OnlineUsers[SearchUser(connection,1,NULL)]->inGame=1;
  344.                 OnlineUsers[SearchUser(connection,1,NULL)]->packages=0;
  345.                 OnlineUsers[SearchUser(connection,1,NULL)]->totalPack=0;
  346.                 pthread_mutex_unlock(&ClientMutex);
  347.                 break;
  348.             }
  349.         }
  350.     }
  351. }
  352.  
  353. /* Handle that checks the validity of the time of each package(it constantly works) */
  354. void *HandleTime(){
  355.  
  356.     time_t now;
  357.     srand(time(NULL));
  358.  
  359.     while(1){ //controlla costantemente
  360.  
  361.         for(int i=0;i<ROWS;i++){
  362.             for(int j=0;j<COLS;j++){
  363.                 if(packTime[i][j].check==1){
  364.                     time(&now);
  365.                     if(difftime(now,packTime[i][j].timePick)>packTime[i][j].time){
  366.                         pthread_mutex_lock(&PackTimeMutex);
  367.                         packTime[i][j].time=0; //tempo scaduto
  368.                         pthread_mutex_unlock(&PackTimeMutex);
  369.                     }
  370.                 }
  371.             }
  372.         }
  373.     }
  374.     pthread_detach(pthread_self());
  375.     pthread_exit(0);
  376. }
  377.  
  378. /* Create the matrix game */
  379. void MakeMatrix(){
  380.  
  381.     int index1=0, index2=0, destination=0, obstacles=15, pkg=15;
  382.     pthread_t tid;
  383.  
  384.     for(int i=0;i<ROWS;i++){
  385.         for(int j=0;j<COLS;j++) game[i][j]=' '; //inizializzo la matrice
  386.     }
  387.  
  388.     while(obstacles>0){
  389.         for(int i=0;i<COLS;i++){
  390.  
  391.             index1=rand()%COLS;
  392.             index2=rand()%COLS;
  393.  
  394.             if(obstacles>0 && game[index1][index2]==' '){
  395.                 pthread_mutex_lock(&MatrixMutex);
  396.                 game[index1][index2]='o'; //pongo un ostacolo in posizione random
  397.                 pthread_mutex_unlock(&MatrixMutex);
  398.                 obstacles--;
  399.             }
  400.         }
  401.     }
  402.     while(pkg>0){
  403.         for(int i=0;i<COLS;i++){
  404.  
  405.             index1=rand()%COLS;
  406.             index2=rand()%COLS;
  407.  
  408.             if(pkg>0 && game[index1][index2]==' '){
  409.                 pthread_mutex_lock(&MatrixMutex);
  410.                 game[index1][index2]='+'; //pongo un pacco in posizione random
  411.                 pthread_mutex_unlock(&MatrixMutex);
  412.                 pthread_mutex_lock(&PackTimeMutex);
  413.                 packTime[index1][index2].time=(rand()%(12-7))+7; //minimo di 7 secondi massimo 11
  414.                 packTime[index1][index2].check=0;
  415.                 pthread_mutex_unlock(&PackTimeMutex);
  416.                 pthread_mutex_lock(&PackMutex);
  417.                 pack++; //incremento numero totale di pacchi
  418.                 pthread_mutex_unlock(&PackMutex);
  419.                 pkg--;
  420.             }
  421.         }
  422.     }
  423.     for(int i=0;i<COLS;i++){
  424.  
  425.         index1=rand()%COLS;
  426.         index2=rand()%COLS;
  427.  
  428.         if(destination==0 && game[index1][index2]==' '){
  429.             destination++;
  430.             pthread_mutex_lock(&MatrixMutex);
  431.             game[index1][index2]='X'; //pongo una destinazione in posizione random
  432.             pthread_mutex_unlock(&MatrixMutex);
  433.         }
  434.     }
  435.     pthread_create(&tid,NULL,&HandleTime,NULL); //creo un thread che analizza costantemente la validità dei pacchi prelevati dagli utenti
  436. }
  437.  
  438. /* Verify the validity of the time of every packages picked up and puts check as zero */
  439. int DeletePack(int riga, int colonna){
  440.  
  441.     if(packTime[riga][colonna].check==1){
  442.  
  443.         pthread_mutex_lock(&PackTimeMutex);
  444.         packTime[riga][colonna].check=0;
  445.         pthread_mutex_unlock(&PackTimeMutex);
  446.         if(packTime[riga][colonna].time!=0) return 1;
  447.         else return 0;
  448.     }
  449.     return 0;
  450. }
  451.  
  452. /* Find the pack's coordinates picked up by user into the matrix game */
  453. int SearchPack(int connection, int flag){
  454.  
  455.     int ret=0;
  456.  
  457.     if(flag==1) ret=OnlineUsers[SearchUser(connection,1,NULL)]->xp;
  458.     else ret=OnlineUsers[SearchUser(connection,1,NULL)]->yp;
  459.     return ret;
  460. }
  461.  
  462. /* Apply changes to the matrix and users during the game */
  463. void ApplyChanges(int x_last, int y_last, int x_new, int y_new, int user, int flag, int connection){
  464.  
  465.     struct sockaddr_in Caddr;
  466.    
  467.     if(flag==1){
  468.         pthread_mutex_lock(&MatrixMutex);
  469.         game[x_last][y_last]=' ';
  470.         game[x_new][y_new]='A'+connection;
  471.         pthread_mutex_unlock(&MatrixMutex);
  472.         pthread_mutex_lock(&ClientMutex);
  473.         OnlineUsers[user]->x=x_new;
  474.         OnlineUsers[user]->y=y_new;
  475.         pthread_mutex_unlock(&ClientMutex);
  476.     }
  477.     if(flag==2){
  478.         pthread_mutex_lock(&PackTimeMutex);
  479.         time(&(packTime[x_new][y_new].timePick));
  480.         pthread_mutex_unlock(&PackTimeMutex);
  481.         pthread_mutex_lock(&MatrixMutex);
  482.         game[x_new][y_new]=' ';
  483.         pthread_mutex_unlock(&MatrixMutex);
  484.         pthread_mutex_lock(&ClientMutex);
  485.         OnlineUsers[user]->packages++;
  486.         OnlineUsers[user]->xp=x_new;
  487.         OnlineUsers[user]->yp=y_new;
  488.         pthread_mutex_unlock(&ClientMutex);
  489.         pthread_mutex_lock(&PackTimeMutex);
  490.         packTime[x_new][y_new].check=1;
  491.         pthread_mutex_unlock(&PackTimeMutex);
  492.     }
  493.     if(flag==3){
  494.         pthread_mutex_lock(&PackTimeMutex);
  495.         time(&(packTime[x_new][y_new].timeDeliver));
  496.         pthread_mutex_unlock(&PackTimeMutex);
  497.         FileLogUser(Caddr,connection,packTime[x_new][y_new].timeDeliver,2);
  498.         pthread_mutex_lock(&ClientMutex);
  499.         OnlineUsers[user]->totalPack++;
  500.         OnlineUsers[user]->packages--;
  501.         pthread_mutex_unlock(&ClientMutex);
  502.         pthread_mutex_lock(&PackMutex);
  503.         pack--;
  504.         pthread_mutex_unlock(&PackMutex);
  505.     }
  506.     if(flag==4){
  507.         pthread_mutex_lock(&ClientMutex);
  508.         OnlineUsers[user]->packages--;
  509.         pthread_mutex_unlock(&ClientMutex);
  510.         pthread_mutex_lock(&PackMutex);
  511.         pack--;
  512.         pthread_mutex_unlock(&PackMutex);
  513.     }
  514. }
  515.  
  516. void PressN(int connection){
  517.  
  518.     char buffer[MAX];
  519.     int nbytes=0, indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
  520.  
  521.     if((index1+1)<ROWS){ // non esce dalla matrice
  522.         if (game[index1+1][index2]==' '){ // non c'è un ostacolo
  523.             ApplyChanges(index1,index2,index1+1,index2,indexUser,1,connection);
  524.             nbytes=sprintf(buffer,"ok");
  525.         }
  526.         else if(game[index1+1][index2]=='-' || game[index1+1][index2]=='o'){ // ostacolo
  527.             if(game[index1+1][index2]=='o'){
  528.                 pthread_mutex_lock(&MatrixMutex);
  529.                 game[index1+1][index2]='-';
  530.                 pthread_mutex_unlock(&MatrixMutex);
  531.             }
  532.             nbytes=sprintf(buffer,"[!]Took an obstacle.");
  533.         }
  534.         else if(game[index1+1][index2]!='X'&&game[index1+1][index2]!='+'&&game[index1+1][index2]!='o'&&game[index1+1][index2]!='-'&& game[index1+1][index2]!=' ') nbytes=sprintf(buffer,"[!]Run into another user."); //scontro con altri giocatori
  535.  
  536.         else if(game[index1+1][index2]=='+' && OnlineUsers[indexUser]->packages==0){ // pacco
  537.             nbytes=sprintf(buffer,"[+]Package picked up->[%.2f]seconds left.", packTime[index1+1][index2].time);
  538.             ApplyChanges(index1,index2,index1+1,index2,indexUser,2,connection);
  539.         }
  540.         else if(game[index1+1][index2]=='+' && OnlineUsers[indexUser]->packages!=0)nbytes=sprintf(buffer,"[!]You have a package yet.");
  541.  
  542.         else if(game[index1+1][index2]=='X' && OnlineUsers[indexUser]->packages!=0){ // destinazione
  543.             if(DeletePack(SearchPack(connection,1),SearchPack(connection,2))==1){
  544.                 ApplyChanges(index1,index2,index1+1,index2,indexUser,3,connection);
  545.                 nbytes=sprintf(buffer,"[+]Package delivered.");
  546.             }
  547.             else{
  548.                 ApplyChanges(index1,index2,index1+1,index2,indexUser,4,connection);
  549.                 nbytes=sprintf(buffer,"[!]Time out, package lost.");
  550.             }
  551.         }
  552.         else if(game[index1+1][index2]=='X' && OnlineUsers[indexUser]->packages==0)nbytes=sprintf(buffer,"[!]You haven't packages to deliver.");
  553.     }
  554.     else nbytes=sprintf(buffer,"[!]Move not valide, retry.");
  555.  
  556.     write(connection,buffer,MAX);
  557.     write(connection,game,sizeof(game));
  558. }
  559.  
  560. void PressS(int connection){
  561.  
  562.     char buffer[MAX];
  563.     int nbytes=0, indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
  564.  
  565.     if((index2-1)>=0){ // non esce dalla matrice
  566.         if (game[index1][index2-1]==' '){ // non c'è un ostacolo
  567.             ApplyChanges(index1,index2,index1,index2-1,indexUser,1,connection);
  568.             nbytes=sprintf(buffer,"ok");
  569.         }
  570.         else if(game[index1][index2-1]=='-' || game[index1][index2-1]=='o'){ // ostacolo
  571.             if(game[index1][index2-1]=='o'){
  572.                 pthread_mutex_lock(&MatrixMutex);
  573.                 game[index1][index2-1]='-';
  574.                 pthread_mutex_unlock(&MatrixMutex);
  575.             }
  576.             nbytes=sprintf(buffer,"[!]Took an obstacle.");
  577.         }
  578.         else if(game[index1][index2-1]!='X'&&game[index1][index2-1]!='+'&&game[index1][index2-1]!='o'&&game[index1][index2-1]!='-'&& game[index1][index2-1]!=' ') nbytes=sprintf(buffer,"[!]Run into another user."); //scontro altri giocatori
  579.  
  580.         else if(game[index1][index2-1]=='+' && OnlineUsers[indexUser]->packages==0){ // pacco
  581.             nbytes=sprintf(buffer,"[+]Package picked up->[%.2f]seconds left.", packTime[index1][index2-1].time);
  582.             ApplyChanges(index1,index2,index1,index2-1,indexUser,2,connection);
  583.         }
  584.         else if(game[index1][index2-1]=='+' && OnlineUsers[indexUser]->packages!=0)nbytes=sprintf(buffer,"[!]You have a package yet.");
  585.  
  586.         else if(game[index1][index2-1]=='X' && OnlineUsers[indexUser]->packages!=0){ // destinazione
  587.             if(DeletePack(SearchPack(connection,1),SearchPack(connection,2))==1){
  588.                 ApplyChanges(index1,index2,index1,index2-1,indexUser,3,connection);
  589.                 nbytes=sprintf(buffer,"[+]Package delivered.");
  590.             }
  591.             else{
  592.                 ApplyChanges(index1,index2,index1,index2-1,indexUser,4,connection);
  593.                 nbytes=sprintf(buffer,"[!]Time out, package lost.");
  594.             }
  595.         }
  596.         else if(game[index1][index2-1]=='X' && OnlineUsers[indexUser]->packages==0)nbytes=sprintf(buffer,"[!]You haven't packages to deliver.");
  597.     }
  598.     else nbytes=sprintf(buffer,"[+]Move not valide, retry.");
  599.  
  600.     write(connection,buffer,MAX);
  601.     write(connection,game,sizeof(game));
  602. }
  603.  
  604. void PressO(int connection){
  605.  
  606.     char buffer[MAX];
  607.     int nbytes=0, indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
  608.  
  609.     if((index2+1)<COLS){ // non esce dalla matrice
  610.         if (game[index1][index2+1]==' '){ // non c'è un ostacolo
  611.             ApplyChanges(index1,index2,index1,index2+1,indexUser,1,connection);
  612.             nbytes=sprintf(buffer,"ok");
  613.         }
  614.         else if(game[index1][index2+1]=='-' || game[index1][index2+1]=='o'){ // ostacolo
  615.             if(game[index1][index2+1]=='o'){
  616.                 pthread_mutex_lock(&MatrixMutex);
  617.                 game[index1][index2+1]='-';
  618.                 pthread_mutex_unlock(&MatrixMutex);
  619.             }
  620.             nbytes=sprintf(buffer,"[!]Took an obstacle.");
  621.         }
  622.         else if(game[index1][index2+1]!='X'&&game[index1][index2+1]!='+'&&game[index1][index2+1]!='o'&&game[index1][index2+1]!='-'&& game[index1][index2+1]!=' ') nbytes=sprintf(buffer,"[!]Run into another user."); //scontro con altri giocatori
  623.  
  624.         else if(game[index1][index2+1]=='+' && OnlineUsers[indexUser]->packages==0){ // pacco
  625.             nbytes=sprintf(buffer,"[+]Package picked up->[%.2f]seconds left.", packTime[index1][index2+1].time);
  626.             ApplyChanges(index1,index2,index1,index2+1,indexUser,2,connection);
  627.         }
  628.         else if(game[index1][index2+1]=='+' && OnlineUsers[indexUser]->packages!=0) nbytes=sprintf(buffer,"[!]You have a package yet.");
  629.        
  630.         else if(game[index1][index2+1]=='X' && OnlineUsers[indexUser]->packages!=0){ // destinazione
  631.             if(DeletePack(SearchPack(connection,1),SearchPack(connection,2))==1){
  632.                 ApplyChanges(index1,index2,index1,index2+1,indexUser,3,connection);
  633.                 nbytes=sprintf(buffer,"[+]Package delivered.");
  634.             }
  635.             else{
  636.                 ApplyChanges(index1,index2,index1,index2+1,indexUser,4,connection);
  637.                 nbytes=sprintf(buffer,"[!]Time out, package lost.");
  638.             }
  639.         }
  640.         else if(game[index1][index2+1]=='X' && OnlineUsers[indexUser]->packages==0)nbytes=sprintf(buffer,"[!]You haven't packages to deliver.");
  641.     }
  642.     else nbytes=sprintf(buffer,"[!]Move not valide, retry.");
  643.  
  644.     write(connection,buffer,MAX);
  645.     write(connection,game,sizeof(game));
  646. }
  647.  
  648. void PressE(int connection){
  649.  
  650.     char buffer[MAX];
  651.     int nbytes=0, indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
  652.  
  653.     if((index1-1)>=0){ // non esce dalla matrice
  654.         if (game[index1-1][index2]==' '){ // non c'è un ostacolo
  655.             ApplyChanges(index1,index2,index1-1,index2,indexUser,1,connection);
  656.             nbytes=sprintf(buffer,"ok");
  657.         }
  658.         else if(game[index1-1][index2]=='-' || game[index1-1][index2]=='o'){ // ostacolo
  659.             if(game[index1-1][index2]=='o'){
  660.                 pthread_mutex_lock(&MatrixMutex);
  661.                 game[index1-1][index2]='-';
  662.                 pthread_mutex_unlock(&MatrixMutex);
  663.             }
  664.             nbytes=sprintf(buffer,"[!]Took an obstacle.");
  665.         }
  666.         else if(game[index1-1][index2]!='X'&&game[index1-1][index2]!='+'&&game[index1-1][index2]!='o'&&game[index1-1][index2]!='-'&& game[index1-1][index2]!=' ') nbytes=sprintf(buffer,"[!]Run into another user."); //scontro con altri giocatori
  667.  
  668.         else if(game[index1-1][index2]=='+' && OnlineUsers[indexUser]->packages==0){ // pacco
  669.             nbytes=sprintf(buffer,"[+]Package picked up->[%.2f]seconds left.", packTime[index1-1][index2].time);
  670.             ApplyChanges(index1,index2,index1-1,index2,indexUser,2,connection);
  671.         }
  672.         else if (game[index1-1][index2]=='+' && OnlineUsers[indexUser]->packages!=0) nbytes=sprintf(buffer,"[!]You have a package yet.");
  673.  
  674.         else if(game[index1-1][index2]=='X' && OnlineUsers[indexUser]->packages!=0){ // destinazione
  675.             if(DeletePack(SearchPack(connection,1),SearchPack(connection,2))==1){
  676.                 ApplyChanges(index1,index2,index1-1,index2,indexUser,3,connection);
  677.                 nbytes=sprintf(buffer,"[+]Package delivered.");
  678.             }
  679.             else{
  680.                 ApplyChanges(index1,index2,index1-1,index2,indexUser,4,connection);
  681.                 nbytes=sprintf(buffer,"[!]Time out, package lost.");
  682.             }
  683.         }
  684.         else if(game[index1-1][index2]=='X' && OnlineUsers[indexUser]->packages==0)nbytes=sprintf(buffer,"[!]You haven't packages to deliver.");
  685.     }
  686.     else nbytes=sprintf(buffer,"[!]Move not valide, retry.");
  687.  
  688.     write(connection,buffer,MAX);
  689.     write(connection,game,sizeof(game));
  690. }
  691.  
  692. /* If an user quit the game, he's removed from the matrix game */
  693. void RemoveFromGame(int connection){
  694.  
  695.     int indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
  696.  
  697.     pthread_mutex_lock(&ClientMutex);
  698.     OnlineUsers[indexUser]->inGame=0;
  699.     OnlineUsers[indexUser]->totalPack=0;
  700.     OnlineUsers[indexUser]->packages=0;
  701.     pthread_mutex_unlock(&ClientMutex);
  702.  
  703.     pthread_mutex_lock(&MatrixMutex);
  704.     game[index1][index2]=' ';
  705.     pthread_mutex_unlock(&MatrixMutex);
  706. }
  707.  
  708. /* Switch that manages the movement into the matrix game */
  709. void SwitchMatrix(int scelta,int connection){
  710.  
  711.     int nbytes=0;
  712.     char buffer[MAX];
  713.  
  714.     switch(scelta){
  715.  
  716.         case 101: //E: up
  717.             PressE(connection);
  718.             break;
  719.  
  720.         case 110: //N: down
  721.             PressN(connection);
  722.             break;
  723.  
  724.         case 111: //O: right
  725.             PressO(connection);
  726.             break;
  727.  
  728.         case 115: //S: left
  729.             PressS(connection);
  730.             break;
  731.  
  732.         case 116: //utenti online
  733.             ConnectedUsers(connection,116);
  734.             write(connection,game,sizeof(game));
  735.             break;
  736.     }
  737.     if(pack==0) nbytes=sprintf(buffer,"THE WINNER IS: PLAYER [%c] !", 'A'+SearchUser(-1,2,NULL)); //decreto il vincitore
  738.     else nbytes=sprintf(buffer,"noendgame"); //continuo il gioco
  739.     write(connection,buffer,MAX);
  740. }
  741.  
  742. /* Handle that generates new session game when number of packages is zero */
  743. void *HandleMatrix(){
  744.  
  745.     while(1){
  746.         if(pack==0&&flagGame==1){ //se i pacchi sono azzerati e non ci sono utenti che stanno ancora nella matrice di gioco
  747.             sleep(4);
  748.             flagGame=0;
  749.             MakeMatrix(); //creo la sessione di gioco
  750.             printf("[+]New matrix created.\n");
  751.         }
  752.     }
  753.     pthread_detach(pthread_self());
  754.     pthread_exit(0);
  755. }
  756.  
  757. /* Base switch for every clients */
  758. void SwitchMenu(int scelta, int connection){
  759.  
  760.     char buffer[MAX];
  761.     int nbytes=0, flag=0, var=0;
  762.  
  763.     switch(scelta){
  764.  
  765.         case 1:
  766.             Dis_ConnectedClients(connection,1);
  767.             break;
  768.  
  769.         case 2:
  770.             Dis_ConnectedClients(connection,2);
  771.             break;
  772.  
  773.         case 3:
  774.             Registration(connection);
  775.             break;
  776.  
  777.         case 4:
  778.             ConnectedUsers(connection,4);
  779.             break;
  780.  
  781.         case 5:
  782.             Login(connection);
  783.             break;
  784.  
  785.         case 6:
  786.             if(SearchUser(connection,3,NULL)==1){ //utente loggato
  787.  
  788.                 nbytes=sprintf(buffer,"OK");
  789.                 write(connection,buffer,MAX);
  790.  
  791.                 InsertUser(connection);
  792.                 printf("[+]Client [%d] starts game.\n", connection);
  793.                 nbytes=sprintf(buffer,"[+]YOU'RE THE PLAYER: [%c]\n", 'A'+connection);
  794.  
  795.                 write(connection,game,sizeof(game)); //invio al client la matrice
  796.                 write(connection,buffer,MAX);
  797.                
  798.                 while(pack>0){
  799.  
  800.                     if(flag) break;
  801.                     nbytes=read(connection,buffer,MAX);
  802.                     buffer[nbytes]='\0';
  803.  
  804.                     if(strcmp(buffer,"exit\n")==0){
  805.                         printf("[+]Client [%d] exited from game.\n", connection);
  806.                         RemoveFromGame(connection);
  807.                         flag=1;
  808.                     }
  809.                     else if(strcmp(buffer,"abort")==0){
  810.                         RemoveFromGame(connection);
  811.                         flag=1;
  812.                         ClientAbort(connection); //gestisco il segnale e disconetto il client che ha abortito
  813.                     }
  814.                     else if((strcmp(buffer,"\n")==0) || (strcmp(buffer,"s\n")!=0&&strcmp(buffer,"o\n")!=0
  815.                             &&strcmp(buffer,"e\n")!=0&&strcmp(buffer,"n\n")!=0&&strcmp(buffer,"S\n")!=0
  816.                                 &&strcmp(buffer,"O\n")!=0&&strcmp(buffer,"E\n")!=0&&strcmp(buffer,"N\n")!=0
  817.                                     &&strcmp(buffer,"4\n")!=0))continue;
  818.                     else{
  819.                         if(strcmp(buffer,"s\n")==0 || strcmp(buffer,"S\n")==0) var=115;
  820.                         else if(strcmp(buffer,"e\n")==0 || strcmp(buffer,"E\n")==0) var=101;
  821.                         else if(strcmp(buffer,"o\n")==0 || strcmp(buffer,"O\n")==0) var=111;
  822.                         else if(strcmp(buffer,"n\n")==0 || strcmp(buffer,"N\n")==0) var=110;
  823.                         else if(strcmp(buffer,"4\n")==0) var=116;
  824.  
  825.                         SwitchMatrix(var,connection); //switch con le mosse del gioco
  826.                     }
  827.                 }
  828.                 if(pack==0)flagGame=1;
  829.             }
  830.             else{ //utente non loggato
  831.                 nbytes=sprintf(buffer,"NOK");
  832.                 write(connection,buffer,MAX);
  833.             }
  834.             break;
  835.  
  836.         default:
  837.             nbytes=sprintf(buffer,"[!]Command not valid, retry.\n");
  838.             write(connection,buffer,nbytes);
  839.             break;
  840.     }
  841. }
  842.  
  843. /* Disconnect client thread and delete its connection */
  844. void DisconnectThreads(int connection){
  845.  
  846.     pthread_mutex_lock(&ClientMutex);
  847.     disconnectedClients++;
  848.     connectedClients--;
  849.     pthread_mutex_unlock(&ClientMutex);
  850.  
  851.     close(connection);
  852.     pthread_detach(pthread_self());
  853.     pthread_exit(0);
  854. }
  855.  
  856. /* Handle all comunication with user */
  857. void *HandleClient(void *arg){
  858.  
  859.     int nbytes=0, flag=0, var=0, connection=0;
  860.     char buffer[MAX];
  861.  
  862.     connection=*((int*) arg);
  863.     pthread_mutex_lock(&ClientMutex);
  864.     connectedClients++;
  865.     pthread_mutex_unlock(&ClientMutex);
  866.  
  867.     while(1){
  868.  
  869.         if(flag) break;
  870.         nbytes=read(connection,buffer,MAX); //leggo il messaggio del client
  871.         buffer[nbytes]='\0';
  872.  
  873.         if(strcmp(buffer,"abort")==0){
  874.             printf("[+]Client [%d] aborted.\n",connection);
  875.             QueueRemove(connection);
  876.             flag=1;
  877.             signal(SIGPIPE,SIG_IGN); //gestisco il segnale in modo che il server non cade
  878.         }
  879.         else if(strcmp(buffer,"exit\n")==0){
  880.             printf("[+]Client [%d] disconnected.\n",connection);
  881.             QueueRemove(connection);
  882.             flag=1;
  883.         }
  884.         else{
  885.             var=atoi(buffer);
  886.             SwitchMenu(var,connection); //switch con le varie funzionalità
  887.         }
  888.     }
  889.     DisconnectThreads(connection);
  890. }
  891.  
  892. /* Base function that creates client threads */
  893. void MainThread(int sockfd){
  894.  
  895.     while(1){
  896.  
  897.         int connection=0, *thread_sd;
  898.         time_t TimeNULL;
  899.         pthread_t tid;
  900.         struct sockaddr_in Caddr;
  901.         socklen_t client_len=sizeof(Caddr);
  902.  
  903.         connection=accept(sockfd,NULL,NULL);
  904.         if(getpeername(connection,(struct sockaddr *)&Caddr,&client_len)<0) printf("[-]Error peername.\n");
  905.  
  906.         t_user *user=(t_user *)malloc(sizeof(t_user)); //alloca memoria per il client da inserire nella struttura apposita
  907.         user->sockfd=connection;
  908.  
  909.         QueueAdd(user); //aggiunge il client alla coda
  910.         FileLogUser(Caddr,connection,TimeNULL,1); //aggiungo il client al FileLOG
  911.  
  912.         thread_sd=(int *)malloc(sizeof(int));
  913.         *thread_sd=connection;
  914.         printf("[+]Server: new connection from [%d]\n", connection);
  915.         pthread_create(&tid,NULL,&HandleClient,(void*)thread_sd); //thread univoco per ogni client
  916.     }
  917.     close(sockfd);
  918. }
  919.  
  920. /* TCP Socket configuration */
  921. void SocketTCP(int PORT){
  922.  
  923.     int sockfd, bind_var, connection;
  924.     struct sockaddr_in Saddr;
  925.     pthread_t tidm;
  926.  
  927.     system("clear");
  928.     printf(ANSI_COLOR_YELLOW "\n\n\t\t\t* * *S  E  R  V  E  R* * *\n\n" ANSI_COLOR_RESET);
  929.  
  930.     if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
  931.         printf("[-]Error socket.\n");
  932.         exit(1);
  933.     }
  934.     else printf("[+]ServerSocket created.\n");
  935.  
  936.     Saddr.sin_family=AF_INET;
  937.     Saddr.sin_port=htons(PORT);
  938.     Saddr.sin_addr.s_addr=htonl(INADDR_ANY);
  939.  
  940.     if((setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&(int){1},sizeof(int))<0)){
  941.         printf("[-]Error sockopt.\n");
  942.         exit(1);
  943.     }
  944.     if((bind_var=bind(sockfd,(struct sockaddr*)&Saddr, sizeof(Saddr)))<0){
  945.         printf("[-]Error binding.\n");
  946.         exit(1);
  947.     }
  948.     else printf("[+]Bind to port_number[%d]\n", PORT);
  949.  
  950.     if(listen(sockfd,10)==0) printf("[+]Listening...\n\n");
  951.     else printf("[-]Error Listening...\n");
  952.  
  953.     pthread_create(&tidm,NULL,&HandleMatrix,NULL); //thread che valuta lo stato dei giocatori per creare una nuova sessione
  954.     MainThread(sockfd);
  955.  
  956.     close(sockfd);
  957. }
  958.  
  959. /* Check that number of argument inserted by user on command line is correct */
  960. int CheckNumberArguments(int argc){
  961.  
  962.     if(argc==2) return 1;
  963.     else return 0;
  964. }
  965.  
  966. /* Main process */
  967. int main(int argc, char **argv){
  968.    
  969.     signal(SIGPIPE,SIG_IGN);
  970.    
  971.     if(CheckNumberArguments(argc)) SocketTCP(atoi(argv[1]));
  972.     else printf("[!]Please enter the correct number of arguments.\n");
  973.  
  974.     return 0;
  975. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement