Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <signal.h>
- #define MAX 300
- #define QUEUE 30
- #define ROWS 10
- #define COLS 20
- #define ANSI_COLOR_YELLOW "\x1b[01;33m"
- #define ANSI_COLOR_RESET "\x1b[0m"
- int connectedClients=0;
- int disconnectedClients=0;
- int pack=0; //pacchi totali nella matrice: il gioco termina quando si azzerano i pacchi
- int flagGame=1; //flag per dare il via ad una nuova sessione di gioco una volta terminata quella corrente
- char game[ROWS][COLS]; //matrice di gioco
- pthread_mutex_t ClientMutex = PTHREAD_MUTEX_INITIALIZER; //per la sincronizzazione tra i thread client
- pthread_mutex_t FileUserMutex = PTHREAD_MUTEX_INITIALIZER; //per il file FileUSER.txt
- pthread_mutex_t FileLogMutex = PTHREAD_MUTEX_INITIALIZER; //per il file FileLOG.txt
- pthread_mutex_t MatrixMutex = PTHREAD_MUTEX_INITIALIZER; //per la matrice di gioco
- pthread_mutex_t PackMutex = PTHREAD_MUTEX_INITIALIZER; //per il numero globale di pacchi
- pthread_mutex_t PackTimeMutex = PTHREAD_MUTEX_INITIALIZER; //per la matrice astratta di pacchi
- struct pack{ //struttura dati associata ad ogni pacco
- int check; //assume valore 0 o 1 se il pacco è stato prelevato
- double time; //tempo di scadenza
- time_t timeDeliver; //tempo consegna
- time_t timePick; //tempo di prelevamento
- };
- struct pack packTime[ROWS][COLS]; //matrice di struct pack
- struct user { //struttura dati associata ad ogni utente
- int sockfd; // valore della connessione
- int logged; // assume valore 0 o 1 se l'utente è loggato o no
- char username[30]; //username login
- char password[30]; //password login
- int x; //riga della matrice dove si trova l'utente
- int y; //colonna della matrice dove si trova l'utente
- int xp; //riga del pacco prelevato dall'utente nella matrice
- int yp; //colonna del pacco prelevato dall'utente nella matrice
- int packages; //assume valore 0 o 1 se il giocatore ha prelevato un pacco(1 pacco alla volta)
- int totalPack; //numero totale di pacchi prelevati in una sessione
- int inGame; //assume valore 0 o 1 se l'utente è in sessione di gioco
- };
- typedef struct user t_user;
- t_user *OnlineUsers[QUEUE]; //array di puntatori a struct user
- //FUNZIONI
- /* Add clients to queue */
- void QueueAdd(t_user *user){
- for(int i=0;i<QUEUE;i++){
- if(!OnlineUsers[i]){
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[i]=user;
- memset(OnlineUsers[i]->username,'\0',sizeof(OnlineUsers[i]->username));
- memset(OnlineUsers[i]->password,'\0',sizeof(OnlineUsers[i]->password));
- OnlineUsers[i]->logged=0;
- OnlineUsers[i]->inGame=0;
- OnlineUsers[i]->packages=0;
- OnlineUsers[i]->totalPack=0;
- pthread_mutex_unlock(&ClientMutex);
- break;
- }
- }
- }
- /* Checks some user properties based on tha FLAG */
- int SearchUser(int connection, int flag, char buffer[]){
- int ret=-1, max=0, j=0;
- char user[MAX];
- if(flag==4){
- while(buffer[j]!=' ') j++;
- strncpy(user,&buffer[0],j); //estraggo username
- user[j+1]='\0';
- }
- for(int i=0;i<QUEUE; i++){
- if(OnlineUsers[i]){
- if(flag==1 && OnlineUsers[i]->sockfd==connection)ret=i; //ritorno la connessione
- if(flag==2 && OnlineUsers[i]->logged==1 && max<OnlineUsers[i]->totalPack){ //cerco il vincitore
- max=OnlineUsers[i]->totalPack;
- ret=OnlineUsers[i]->sockfd;
- }
- if(flag==3 && OnlineUsers[i]->sockfd==connection && OnlineUsers[i]->logged==1) ret=1; //utente loggato
- if(flag==4 && strcmp(OnlineUsers[i]->username,user)==0) ret=1; //credenziali gia esistenti
- }
- }
- return ret;
- }
- /* Remove clients from queue */
- void QueueRemove(int connection){
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[SearchUser(connection,1,NULL)]=NULL;
- pthread_mutex_unlock(&ClientMutex);
- }
- /* Insert credentials of an user logged in into queue */
- void PopulateQueue(char buffer[], int length, int connection){
- char user[MAX], pwd[MAX];
- int j=0;
- for(int i=0; i<QUEUE; i++){
- if(OnlineUsers[i]&&OnlineUsers[i]->sockfd==connection){
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[i]->logged=1;
- pthread_mutex_unlock(&ClientMutex);
- while(buffer[j]!=' ') j++;
- pthread_mutex_lock(&ClientMutex);
- strncpy(user,&buffer[0],j); //copio lo username
- user[j+1]='\0';
- memcpy(OnlineUsers[i]->username,user,j);
- strncpy(pwd,&buffer[++j],length); //copio la password
- pwd[length-j]='\0';
- memcpy(OnlineUsers[i]->password,pwd,length-j);
- pthread_mutex_unlock(&ClientMutex);
- break;
- }
- }
- }
- /* Delete client's connection after an abort */
- void ClientAbort(int connection){
- pthread_mutex_lock(&ClientMutex);
- connectedClients--; //aggiorno variabili globali
- disconnectedClients++;
- pthread_mutex_unlock(&ClientMutex);
- QueueRemove(connection); //rimuovo il client dalla coda di quelli connessi
- printf("[+]Client [%d] aborted.\n", connection);
- signal(SIGPIPE,SIG_IGN); //se un client termina in modo anomalo gestisco SIGPIPE e non faccio terminare il server
- }
- /* Create FileLOG with all activities of users: connection, packages picked up, etc. */
- void FileLogUser(struct sockaddr_in Caddr, int connection, time_t pack, int flag){
- srand(time(NULL));
- int nbytes=0, fd=0;
- char buffer[MAX];
- time_t rawtime;
- time(&rawtime);
- struct tm * timeinfo=localtime(&rawtime);
- if((fd=open("FileLOG.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR))<0){
- perror("[-]Error FileLOG.\n");
- exit(1);
- }
- if(!fd) perror("[-]FileLOG not exist.\n");
- else{
- if(flag==1) nbytes=sprintf(buffer,"[IP]: %s\t[CURRENT LOCAL TIME & DATE]: %s", inet_ntoa(Caddr.sin_addr), asctime(timeinfo));
- 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));
- 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));
- pthread_mutex_lock(&FileLogMutex);
- write(fd,buffer,nbytes);
- pthread_mutex_unlock(&FileLogMutex);
- }
- close(fd);
- }
- /* Verify that the user is present in the FileUser */
- int CheckUser(char *buffer){
- char user[MAX], pwd[MAX];
- FILE *fd;
- if((fd=fopen("FileUSER.txt","r"))<0){
- perror("[-]Error FileUSER.\n");
- exit(1);
- }
- if(!fd) perror("[-]FileUSER not exist.\n");
- else{
- while(!feof(fd)){
- fscanf(fd,"%s %s", user, pwd);
- strcat(user," ");
- strcat(user, pwd);
- strcat(user,"\n");
- if(strcmp(buffer,user)==0) return 1;
- }
- }
- return 0;
- }
- /* Register the user */
- void Registration(int connection){
- char buffer[MAX], buffer2[MAX];
- int nbytes=0, fd=0;
- if((fd=open("FileUSER.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR))<0){
- perror("[-]Error FileUSER.\n");
- exit(1);
- }
- else{
- if(SearchUser(connection,3,NULL)!=1){
- nbytes=sprintf(buffer2,"OK");
- write(connection,buffer2,nbytes);
- nbytes=read(connection,buffer,MAX);
- buffer[nbytes]='\0';
- nbytes=read(connection,buffer2,MAX);
- buffer2[nbytes]='\0';
- if(strcmp(buffer,"abort")==0)ClientAbort(connection);
- else{
- strcat(buffer," ");
- strcat(buffer,buffer2);
- strcat(buffer,"\n");
- if(CheckUser(buffer)==0){
- pthread_mutex_lock(&FileUserMutex);
- write(fd,buffer,strlen(buffer));
- pthread_mutex_unlock(&FileUserMutex);
- nbytes=sprintf(buffer2,"[+]Registered successfully.\n");
- printf("[+]Client [%d] registered.\n",connection);
- }
- else nbytes=sprintf(buffer2,"[+]User with these credentials already exists, please retry.\n");
- write(connection,buffer2,nbytes);
- close(fd);
- }
- }
- else{
- nbytes=sprintf(buffer2,"[+]You cannot register, you already logged in.\n");
- write(connection,buffer2,nbytes);
- }
- }
- }
- /* Login the user */
- void Login(int connection){
- int nbytes=0;
- char buffer[MAX], buffer2[MAX];
- time_t TimeNULL;
- struct sockaddr_in Caddr;
- nbytes=read(connection,buffer,MAX);
- buffer[nbytes]='\0';
- nbytes=read(connection,buffer2,MAX);
- buffer2[nbytes]='\0';
- if(strcmp(buffer,"abort")==0)ClientAbort(connection);
- else{
- strcat(buffer," ");
- strcat(buffer,buffer2);
- strcat(buffer,"\n");
- if(SearchUser(connection,4,buffer)!=1){
- if(CheckUser(buffer)==1&&SearchUser(connection,3,NULL)!=1){
- nbytes=sprintf(buffer2,"[+]Login done successfully!\n");
- PopulateQueue(buffer,strlen(buffer),connection);
- FileLogUser(Caddr,connection,TimeNULL,2);
- printf("[+]Client [%d] logged in.\n",connection);
- }
- else if(CheckUser(buffer)==0) nbytes=sprintf(buffer2,"[+]You're not registered to login or bad credentials, retry.\n");
- else if(SearchUser(connection,3,NULL)==1) nbytes=sprintf(buffer2,"[+]Login already done.\n");
- }
- else nbytes=sprintf(buffer2,"[+]Login already done by another user with these credentials.\n");
- write(connection,buffer2,nbytes);
- }
- }
- /* List of logged in users */
- void ConnectedUsers(int connection,int var){
- int nbytes=0;
- char message[MAX], buffer[MAX];
- *message='\0';
- for(int i=0;i<QUEUE;i++){
- if(OnlineUsers[i]){
- memcpy(buffer,OnlineUsers[i]->username, sizeof(OnlineUsers[i]->username));
- strcat(message, buffer);
- strcat(message, "-");
- }
- }
- if(var==4)strcat(message,"\n");
- nbytes=strlen(message);
- write(connection,message,nbytes);
- }
- void Dis_ConnectedClients(int connection, int flag){
- int nbytes=0;
- char buffer[MAX];
- if(flag==1) nbytes=sprintf(buffer,"[+]Number of connected clients: %d\n", connectedClients);
- else if(flag==2) nbytes=sprintf(buffer,"[+]Number of disconnected clients: %d\n", disconnectedClients);
- write(connection,buffer,nbytes);
- }
- /* Insert user into the matrix game */
- void InsertUser(int connection){
- int index1=0, index2=0, user=0;
- for(int i=0;i<ROWS;i++){
- for(int j=0;j<COLS;j++){
- index1=rand()%COLS;
- index2=rand()%COLS;
- if(user==0&&game[index1][index2]==' '){
- user++; //effettuo tale operazione una volta sola per 1 utente
- pthread_mutex_lock(&MatrixMutex);
- game[index1][index2]='A'+connection;
- pthread_mutex_unlock(&MatrixMutex);
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[SearchUser(connection,1,NULL)]->x=index1;
- OnlineUsers[SearchUser(connection,1,NULL)]->y=index2;
- OnlineUsers[SearchUser(connection,1,NULL)]->inGame=1;
- OnlineUsers[SearchUser(connection,1,NULL)]->packages=0;
- OnlineUsers[SearchUser(connection,1,NULL)]->totalPack=0;
- pthread_mutex_unlock(&ClientMutex);
- break;
- }
- }
- }
- }
- /* Handle that checks the validity of the time of each package(it constantly works) */
- void *HandleTime(){
- time_t now;
- srand(time(NULL));
- while(1){ //controlla costantemente
- for(int i=0;i<ROWS;i++){
- for(int j=0;j<COLS;j++){
- if(packTime[i][j].check==1){
- time(&now);
- if(difftime(now,packTime[i][j].timePick)>packTime[i][j].time){
- pthread_mutex_lock(&PackTimeMutex);
- packTime[i][j].time=0; //tempo scaduto
- pthread_mutex_unlock(&PackTimeMutex);
- }
- }
- }
- }
- }
- pthread_detach(pthread_self());
- pthread_exit(0);
- }
- /* Create the matrix game */
- void MakeMatrix(){
- int index1=0, index2=0, destination=0, obstacles=15, pkg=15;
- pthread_t tid;
- for(int i=0;i<ROWS;i++){
- for(int j=0;j<COLS;j++) game[i][j]=' '; //inizializzo la matrice
- }
- while(obstacles>0){
- for(int i=0;i<COLS;i++){
- index1=rand()%COLS;
- index2=rand()%COLS;
- if(obstacles>0 && game[index1][index2]==' '){
- pthread_mutex_lock(&MatrixMutex);
- game[index1][index2]='o'; //pongo un ostacolo in posizione random
- pthread_mutex_unlock(&MatrixMutex);
- obstacles--;
- }
- }
- }
- while(pkg>0){
- for(int i=0;i<COLS;i++){
- index1=rand()%COLS;
- index2=rand()%COLS;
- if(pkg>0 && game[index1][index2]==' '){
- pthread_mutex_lock(&MatrixMutex);
- game[index1][index2]='+'; //pongo un pacco in posizione random
- pthread_mutex_unlock(&MatrixMutex);
- pthread_mutex_lock(&PackTimeMutex);
- packTime[index1][index2].time=(rand()%(12-7))+7; //minimo di 7 secondi massimo 11
- packTime[index1][index2].check=0;
- pthread_mutex_unlock(&PackTimeMutex);
- pthread_mutex_lock(&PackMutex);
- pack++; //incremento numero totale di pacchi
- pthread_mutex_unlock(&PackMutex);
- pkg--;
- }
- }
- }
- for(int i=0;i<COLS;i++){
- index1=rand()%COLS;
- index2=rand()%COLS;
- if(destination==0 && game[index1][index2]==' '){
- destination++;
- pthread_mutex_lock(&MatrixMutex);
- game[index1][index2]='X'; //pongo una destinazione in posizione random
- pthread_mutex_unlock(&MatrixMutex);
- }
- }
- pthread_create(&tid,NULL,&HandleTime,NULL); //creo un thread che analizza costantemente la validità dei pacchi prelevati dagli utenti
- }
- /* Verify the validity of the time of every packages picked up and puts check as zero */
- int DeletePack(int riga, int colonna){
- if(packTime[riga][colonna].check==1){
- pthread_mutex_lock(&PackTimeMutex);
- packTime[riga][colonna].check=0;
- pthread_mutex_unlock(&PackTimeMutex);
- if(packTime[riga][colonna].time!=0) return 1;
- else return 0;
- }
- return 0;
- }
- /* Find the pack's coordinates picked up by user into the matrix game */
- int SearchPack(int connection, int flag){
- int ret=0;
- if(flag==1) ret=OnlineUsers[SearchUser(connection,1,NULL)]->xp;
- else ret=OnlineUsers[SearchUser(connection,1,NULL)]->yp;
- return ret;
- }
- /* Apply changes to the matrix and users during the game */
- void ApplyChanges(int x_last, int y_last, int x_new, int y_new, int user, int flag, int connection){
- struct sockaddr_in Caddr;
- if(flag==1){
- pthread_mutex_lock(&MatrixMutex);
- game[x_last][y_last]=' ';
- game[x_new][y_new]='A'+connection;
- pthread_mutex_unlock(&MatrixMutex);
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[user]->x=x_new;
- OnlineUsers[user]->y=y_new;
- pthread_mutex_unlock(&ClientMutex);
- }
- if(flag==2){
- pthread_mutex_lock(&PackTimeMutex);
- time(&(packTime[x_new][y_new].timePick));
- pthread_mutex_unlock(&PackTimeMutex);
- pthread_mutex_lock(&MatrixMutex);
- game[x_new][y_new]=' ';
- pthread_mutex_unlock(&MatrixMutex);
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[user]->packages++;
- OnlineUsers[user]->xp=x_new;
- OnlineUsers[user]->yp=y_new;
- pthread_mutex_unlock(&ClientMutex);
- pthread_mutex_lock(&PackTimeMutex);
- packTime[x_new][y_new].check=1;
- pthread_mutex_unlock(&PackTimeMutex);
- }
- if(flag==3){
- pthread_mutex_lock(&PackTimeMutex);
- time(&(packTime[x_new][y_new].timeDeliver));
- pthread_mutex_unlock(&PackTimeMutex);
- FileLogUser(Caddr,connection,packTime[x_new][y_new].timeDeliver,2);
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[user]->totalPack++;
- OnlineUsers[user]->packages--;
- pthread_mutex_unlock(&ClientMutex);
- pthread_mutex_lock(&PackMutex);
- pack--;
- pthread_mutex_unlock(&PackMutex);
- }
- if(flag==4){
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[user]->packages--;
- pthread_mutex_unlock(&ClientMutex);
- pthread_mutex_lock(&PackMutex);
- pack--;
- pthread_mutex_unlock(&PackMutex);
- }
- }
- void PressN(int connection){
- char buffer[MAX];
- int nbytes=0, indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
- if((index1+1)<ROWS){ // non esce dalla matrice
- if (game[index1+1][index2]==' '){ // non c'è un ostacolo
- ApplyChanges(index1,index2,index1+1,index2,indexUser,1,connection);
- nbytes=sprintf(buffer,"ok");
- }
- else if(game[index1+1][index2]=='-' || game[index1+1][index2]=='o'){ // ostacolo
- if(game[index1+1][index2]=='o'){
- pthread_mutex_lock(&MatrixMutex);
- game[index1+1][index2]='-';
- pthread_mutex_unlock(&MatrixMutex);
- }
- nbytes=sprintf(buffer,"[!]Took an obstacle.");
- }
- 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
- else if(game[index1+1][index2]=='+' && OnlineUsers[indexUser]->packages==0){ // pacco
- nbytes=sprintf(buffer,"[+]Package picked up->[%.2f]seconds left.", packTime[index1+1][index2].time);
- ApplyChanges(index1,index2,index1+1,index2,indexUser,2,connection);
- }
- else if(game[index1+1][index2]=='+' && OnlineUsers[indexUser]->packages!=0)nbytes=sprintf(buffer,"[!]You have a package yet.");
- else if(game[index1+1][index2]=='X' && OnlineUsers[indexUser]->packages!=0){ // destinazione
- if(DeletePack(SearchPack(connection,1),SearchPack(connection,2))==1){
- ApplyChanges(index1,index2,index1+1,index2,indexUser,3,connection);
- nbytes=sprintf(buffer,"[+]Package delivered.");
- }
- else{
- ApplyChanges(index1,index2,index1+1,index2,indexUser,4,connection);
- nbytes=sprintf(buffer,"[!]Time out, package lost.");
- }
- }
- else if(game[index1+1][index2]=='X' && OnlineUsers[indexUser]->packages==0)nbytes=sprintf(buffer,"[!]You haven't packages to deliver.");
- }
- else nbytes=sprintf(buffer,"[!]Move not valide, retry.");
- write(connection,buffer,MAX);
- write(connection,game,sizeof(game));
- }
- void PressS(int connection){
- char buffer[MAX];
- int nbytes=0, indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
- if((index2-1)>=0){ // non esce dalla matrice
- if (game[index1][index2-1]==' '){ // non c'è un ostacolo
- ApplyChanges(index1,index2,index1,index2-1,indexUser,1,connection);
- nbytes=sprintf(buffer,"ok");
- }
- else if(game[index1][index2-1]=='-' || game[index1][index2-1]=='o'){ // ostacolo
- if(game[index1][index2-1]=='o'){
- pthread_mutex_lock(&MatrixMutex);
- game[index1][index2-1]='-';
- pthread_mutex_unlock(&MatrixMutex);
- }
- nbytes=sprintf(buffer,"[!]Took an obstacle.");
- }
- 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
- else if(game[index1][index2-1]=='+' && OnlineUsers[indexUser]->packages==0){ // pacco
- nbytes=sprintf(buffer,"[+]Package picked up->[%.2f]seconds left.", packTime[index1][index2-1].time);
- ApplyChanges(index1,index2,index1,index2-1,indexUser,2,connection);
- }
- else if(game[index1][index2-1]=='+' && OnlineUsers[indexUser]->packages!=0)nbytes=sprintf(buffer,"[!]You have a package yet.");
- else if(game[index1][index2-1]=='X' && OnlineUsers[indexUser]->packages!=0){ // destinazione
- if(DeletePack(SearchPack(connection,1),SearchPack(connection,2))==1){
- ApplyChanges(index1,index2,index1,index2-1,indexUser,3,connection);
- nbytes=sprintf(buffer,"[+]Package delivered.");
- }
- else{
- ApplyChanges(index1,index2,index1,index2-1,indexUser,4,connection);
- nbytes=sprintf(buffer,"[!]Time out, package lost.");
- }
- }
- else if(game[index1][index2-1]=='X' && OnlineUsers[indexUser]->packages==0)nbytes=sprintf(buffer,"[!]You haven't packages to deliver.");
- }
- else nbytes=sprintf(buffer,"[+]Move not valide, retry.");
- write(connection,buffer,MAX);
- write(connection,game,sizeof(game));
- }
- void PressO(int connection){
- char buffer[MAX];
- int nbytes=0, indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
- if((index2+1)<COLS){ // non esce dalla matrice
- if (game[index1][index2+1]==' '){ // non c'è un ostacolo
- ApplyChanges(index1,index2,index1,index2+1,indexUser,1,connection);
- nbytes=sprintf(buffer,"ok");
- }
- else if(game[index1][index2+1]=='-' || game[index1][index2+1]=='o'){ // ostacolo
- if(game[index1][index2+1]=='o'){
- pthread_mutex_lock(&MatrixMutex);
- game[index1][index2+1]='-';
- pthread_mutex_unlock(&MatrixMutex);
- }
- nbytes=sprintf(buffer,"[!]Took an obstacle.");
- }
- 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
- else if(game[index1][index2+1]=='+' && OnlineUsers[indexUser]->packages==0){ // pacco
- nbytes=sprintf(buffer,"[+]Package picked up->[%.2f]seconds left.", packTime[index1][index2+1].time);
- ApplyChanges(index1,index2,index1,index2+1,indexUser,2,connection);
- }
- else if(game[index1][index2+1]=='+' && OnlineUsers[indexUser]->packages!=0) nbytes=sprintf(buffer,"[!]You have a package yet.");
- else if(game[index1][index2+1]=='X' && OnlineUsers[indexUser]->packages!=0){ // destinazione
- if(DeletePack(SearchPack(connection,1),SearchPack(connection,2))==1){
- ApplyChanges(index1,index2,index1,index2+1,indexUser,3,connection);
- nbytes=sprintf(buffer,"[+]Package delivered.");
- }
- else{
- ApplyChanges(index1,index2,index1,index2+1,indexUser,4,connection);
- nbytes=sprintf(buffer,"[!]Time out, package lost.");
- }
- }
- else if(game[index1][index2+1]=='X' && OnlineUsers[indexUser]->packages==0)nbytes=sprintf(buffer,"[!]You haven't packages to deliver.");
- }
- else nbytes=sprintf(buffer,"[!]Move not valide, retry.");
- write(connection,buffer,MAX);
- write(connection,game,sizeof(game));
- }
- void PressE(int connection){
- char buffer[MAX];
- int nbytes=0, indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
- if((index1-1)>=0){ // non esce dalla matrice
- if (game[index1-1][index2]==' '){ // non c'è un ostacolo
- ApplyChanges(index1,index2,index1-1,index2,indexUser,1,connection);
- nbytes=sprintf(buffer,"ok");
- }
- else if(game[index1-1][index2]=='-' || game[index1-1][index2]=='o'){ // ostacolo
- if(game[index1-1][index2]=='o'){
- pthread_mutex_lock(&MatrixMutex);
- game[index1-1][index2]='-';
- pthread_mutex_unlock(&MatrixMutex);
- }
- nbytes=sprintf(buffer,"[!]Took an obstacle.");
- }
- 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
- else if(game[index1-1][index2]=='+' && OnlineUsers[indexUser]->packages==0){ // pacco
- nbytes=sprintf(buffer,"[+]Package picked up->[%.2f]seconds left.", packTime[index1-1][index2].time);
- ApplyChanges(index1,index2,index1-1,index2,indexUser,2,connection);
- }
- else if (game[index1-1][index2]=='+' && OnlineUsers[indexUser]->packages!=0) nbytes=sprintf(buffer,"[!]You have a package yet.");
- else if(game[index1-1][index2]=='X' && OnlineUsers[indexUser]->packages!=0){ // destinazione
- if(DeletePack(SearchPack(connection,1),SearchPack(connection,2))==1){
- ApplyChanges(index1,index2,index1-1,index2,indexUser,3,connection);
- nbytes=sprintf(buffer,"[+]Package delivered.");
- }
- else{
- ApplyChanges(index1,index2,index1-1,index2,indexUser,4,connection);
- nbytes=sprintf(buffer,"[!]Time out, package lost.");
- }
- }
- else if(game[index1-1][index2]=='X' && OnlineUsers[indexUser]->packages==0)nbytes=sprintf(buffer,"[!]You haven't packages to deliver.");
- }
- else nbytes=sprintf(buffer,"[!]Move not valide, retry.");
- write(connection,buffer,MAX);
- write(connection,game,sizeof(game));
- }
- /* If an user quit the game, he's removed from the matrix game */
- void RemoveFromGame(int connection){
- int indexUser=SearchUser(connection,1,NULL), index1=OnlineUsers[indexUser]->x, index2=OnlineUsers[indexUser]->y;
- pthread_mutex_lock(&ClientMutex);
- OnlineUsers[indexUser]->inGame=0;
- OnlineUsers[indexUser]->totalPack=0;
- OnlineUsers[indexUser]->packages=0;
- pthread_mutex_unlock(&ClientMutex);
- pthread_mutex_lock(&MatrixMutex);
- game[index1][index2]=' ';
- pthread_mutex_unlock(&MatrixMutex);
- }
- /* Switch that manages the movement into the matrix game */
- void SwitchMatrix(int scelta,int connection){
- int nbytes=0;
- char buffer[MAX];
- switch(scelta){
- case 101: //E: up
- PressE(connection);
- break;
- case 110: //N: down
- PressN(connection);
- break;
- case 111: //O: right
- PressO(connection);
- break;
- case 115: //S: left
- PressS(connection);
- break;
- case 116: //utenti online
- ConnectedUsers(connection,116);
- write(connection,game,sizeof(game));
- break;
- }
- if(pack==0) nbytes=sprintf(buffer,"THE WINNER IS: PLAYER [%c] !", 'A'+SearchUser(-1,2,NULL)); //decreto il vincitore
- else nbytes=sprintf(buffer,"noendgame"); //continuo il gioco
- write(connection,buffer,MAX);
- }
- /* Handle that generates new session game when number of packages is zero */
- void *HandleMatrix(){
- while(1){
- if(pack==0&&flagGame==1){ //se i pacchi sono azzerati e non ci sono utenti che stanno ancora nella matrice di gioco
- sleep(4);
- flagGame=0;
- MakeMatrix(); //creo la sessione di gioco
- printf("[+]New matrix created.\n");
- }
- }
- pthread_detach(pthread_self());
- pthread_exit(0);
- }
- /* Base switch for every clients */
- void SwitchMenu(int scelta, int connection){
- char buffer[MAX];
- int nbytes=0, flag=0, var=0;
- switch(scelta){
- case 1:
- Dis_ConnectedClients(connection,1);
- break;
- case 2:
- Dis_ConnectedClients(connection,2);
- break;
- case 3:
- Registration(connection);
- break;
- case 4:
- ConnectedUsers(connection,4);
- break;
- case 5:
- Login(connection);
- break;
- case 6:
- if(SearchUser(connection,3,NULL)==1){ //utente loggato
- nbytes=sprintf(buffer,"OK");
- write(connection,buffer,MAX);
- InsertUser(connection);
- printf("[+]Client [%d] starts game.\n", connection);
- nbytes=sprintf(buffer,"[+]YOU'RE THE PLAYER: [%c]\n", 'A'+connection);
- write(connection,game,sizeof(game)); //invio al client la matrice
- write(connection,buffer,MAX);
- while(pack>0){
- if(flag) break;
- nbytes=read(connection,buffer,MAX);
- buffer[nbytes]='\0';
- if(strcmp(buffer,"exit\n")==0){
- printf("[+]Client [%d] exited from game.\n", connection);
- RemoveFromGame(connection);
- flag=1;
- }
- else if(strcmp(buffer,"abort")==0){
- RemoveFromGame(connection);
- flag=1;
- ClientAbort(connection); //gestisco il segnale e disconetto il client che ha abortito
- }
- else if((strcmp(buffer,"\n")==0) || (strcmp(buffer,"s\n")!=0&&strcmp(buffer,"o\n")!=0
- &&strcmp(buffer,"e\n")!=0&&strcmp(buffer,"n\n")!=0&&strcmp(buffer,"S\n")!=0
- &&strcmp(buffer,"O\n")!=0&&strcmp(buffer,"E\n")!=0&&strcmp(buffer,"N\n")!=0
- &&strcmp(buffer,"4\n")!=0))continue;
- else{
- if(strcmp(buffer,"s\n")==0 || strcmp(buffer,"S\n")==0) var=115;
- else if(strcmp(buffer,"e\n")==0 || strcmp(buffer,"E\n")==0) var=101;
- else if(strcmp(buffer,"o\n")==0 || strcmp(buffer,"O\n")==0) var=111;
- else if(strcmp(buffer,"n\n")==0 || strcmp(buffer,"N\n")==0) var=110;
- else if(strcmp(buffer,"4\n")==0) var=116;
- SwitchMatrix(var,connection); //switch con le mosse del gioco
- }
- }
- if(pack==0)flagGame=1;
- }
- else{ //utente non loggato
- nbytes=sprintf(buffer,"NOK");
- write(connection,buffer,MAX);
- }
- break;
- default:
- nbytes=sprintf(buffer,"[!]Command not valid, retry.\n");
- write(connection,buffer,nbytes);
- break;
- }
- }
- /* Disconnect client thread and delete its connection */
- void DisconnectThreads(int connection){
- pthread_mutex_lock(&ClientMutex);
- disconnectedClients++;
- connectedClients--;
- pthread_mutex_unlock(&ClientMutex);
- close(connection);
- pthread_detach(pthread_self());
- pthread_exit(0);
- }
- /* Handle all comunication with user */
- void *HandleClient(void *arg){
- int nbytes=0, flag=0, var=0, connection=0;
- char buffer[MAX];
- connection=*((int*) arg);
- pthread_mutex_lock(&ClientMutex);
- connectedClients++;
- pthread_mutex_unlock(&ClientMutex);
- while(1){
- if(flag) break;
- nbytes=read(connection,buffer,MAX); //leggo il messaggio del client
- buffer[nbytes]='\0';
- if(strcmp(buffer,"abort")==0){
- printf("[+]Client [%d] aborted.\n",connection);
- QueueRemove(connection);
- flag=1;
- signal(SIGPIPE,SIG_IGN); //gestisco il segnale in modo che il server non cade
- }
- else if(strcmp(buffer,"exit\n")==0){
- printf("[+]Client [%d] disconnected.\n",connection);
- QueueRemove(connection);
- flag=1;
- }
- else{
- var=atoi(buffer);
- SwitchMenu(var,connection); //switch con le varie funzionalità
- }
- }
- DisconnectThreads(connection);
- }
- /* Base function that creates client threads */
- void MainThread(int sockfd){
- while(1){
- int connection=0, *thread_sd;
- time_t TimeNULL;
- pthread_t tid;
- struct sockaddr_in Caddr;
- socklen_t client_len=sizeof(Caddr);
- connection=accept(sockfd,NULL,NULL);
- if(getpeername(connection,(struct sockaddr *)&Caddr,&client_len)<0) printf("[-]Error peername.\n");
- t_user *user=(t_user *)malloc(sizeof(t_user)); //alloca memoria per il client da inserire nella struttura apposita
- user->sockfd=connection;
- QueueAdd(user); //aggiunge il client alla coda
- FileLogUser(Caddr,connection,TimeNULL,1); //aggiungo il client al FileLOG
- thread_sd=(int *)malloc(sizeof(int));
- *thread_sd=connection;
- printf("[+]Server: new connection from [%d]\n", connection);
- pthread_create(&tid,NULL,&HandleClient,(void*)thread_sd); //thread univoco per ogni client
- }
- close(sockfd);
- }
- /* TCP Socket configuration */
- void SocketTCP(int PORT){
- int sockfd, bind_var, connection;
- struct sockaddr_in Saddr;
- pthread_t tidm;
- system("clear");
- printf(ANSI_COLOR_YELLOW "\n\n\t\t\t* * *S E R V E R* * *\n\n" ANSI_COLOR_RESET);
- if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
- printf("[-]Error socket.\n");
- exit(1);
- }
- else printf("[+]ServerSocket created.\n");
- Saddr.sin_family=AF_INET;
- Saddr.sin_port=htons(PORT);
- Saddr.sin_addr.s_addr=htonl(INADDR_ANY);
- if((setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&(int){1},sizeof(int))<0)){
- printf("[-]Error sockopt.\n");
- exit(1);
- }
- if((bind_var=bind(sockfd,(struct sockaddr*)&Saddr, sizeof(Saddr)))<0){
- printf("[-]Error binding.\n");
- exit(1);
- }
- else printf("[+]Bind to port_number[%d]\n", PORT);
- if(listen(sockfd,10)==0) printf("[+]Listening...\n\n");
- else printf("[-]Error Listening...\n");
- pthread_create(&tidm,NULL,&HandleMatrix,NULL); //thread che valuta lo stato dei giocatori per creare una nuova sessione
- MainThread(sockfd);
- close(sockfd);
- }
- /* Check that number of argument inserted by user on command line is correct */
- int CheckNumberArguments(int argc){
- if(argc==2) return 1;
- else return 0;
- }
- /* Main process */
- int main(int argc, char **argv){
- signal(SIGPIPE,SIG_IGN);
- if(CheckNumberArguments(argc)) SocketTCP(atoi(argv[1]));
- else printf("[!]Please enter the correct number of arguments.\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement