2023-05-14 18:03:50 +02:00
# include <sys/types.h>
# include <sys/ipc.h>
2023-05-14 21:44:03 +02:00
# include <sys/shm.h>
2023-05-16 14:55:12 +02:00
# include <sys/stat.h>
2023-05-15 16:50:48 +02:00
# include <signal.h>
# include <stdlib.h>
# include <stdio.h>
2023-05-16 15:55:05 +02:00
# include <sys/msg.h>
2023-05-16 16:32:24 +02:00
# include <sys/sem.h>
2023-05-17 14:24:46 +02:00
# include <string.h>
2023-05-14 18:03:50 +02:00
2023-05-14 18:10:44 +02:00
# include <server.h>
# include <structures.h>
2023-05-15 10:31:50 +02:00
# include <custom_sem.h>
2023-05-15 10:43:25 +02:00
# include <custom_shm.h>
2023-05-15 16:50:48 +02:00
# include <errExit.h>
2023-05-16 16:53:23 +02:00
# include <forza4.h>
2023-05-16 23:27:27 +02:00
# include <nonsodovemetterle.h>
2023-05-19 15:21:15 +02:00
# include <custom_msgq.h>
2023-05-15 16:50:48 +02:00
2023-05-16 18:43:56 +02:00
int semid = 0 ;
2023-05-18 12:45:32 +02:00
int _MSGQID = 0 ;
2023-05-16 18:43:56 +02:00
int shmid = 0 ;
2023-05-16 16:29:49 +02:00
2023-05-16 18:43:56 +02:00
tile_t * board = NULL ;
2023-05-16 16:29:49 +02:00
2023-05-17 15:46:51 +02:00
pid_t pids [ 2 ] ;
2023-05-16 16:10:43 +02:00
void sigHandlerServer ( int sig ) {
if ( sig = = SIGINT ) {
2023-05-17 15:46:51 +02:00
//TODO:sigdelset(&mySet, SIGTERM);
2023-05-16 16:27:20 +02:00
2023-05-16 18:43:56 +02:00
sig = SIGTERM ; // per il secondo SIGINT basta modificare il sig in SIGTERM
2023-05-16 15:26:58 +02:00
}
2023-05-17 15:46:51 +02:00
if ( sig = = SIGTERM | | sig = = SIGHUP ) {
2023-05-17 15:57:10 +02:00
if ( pids [ 0 ] > 0 ) {
2023-05-19 15:21:15 +02:00
printf ( " \n " ) ;
printfServer ( " Terminating player one " ) ;
2023-05-17 15:57:10 +02:00
kill ( pids [ 0 ] , SIGTERM ) ;
}
if ( pids [ 1 ] > 0 ) {
2023-05-19 15:21:15 +02:00
printf ( " \n " ) ;
printfServer ( " Terminating player two " ) ;
2023-05-17 15:57:10 +02:00
kill ( pids [ 1 ] , SIGTERM ) ;
}
2023-05-16 16:27:20 +02:00
// msgq
2023-05-18 12:45:32 +02:00
if ( _MSGQID ) {
2023-05-16 23:27:27 +02:00
printf ( " \n " ) ;
2023-05-17 15:46:51 +02:00
printfServer ( " Deleting msg " ) ;
2023-05-19 15:21:15 +02:00
if ( msgctl ( _MSGQID , IPC_RMID , NULL ) = = - 1 ) { //TODO: funzione
2023-05-16 18:43:56 +02:00
errExit ( " msgctl " , " sigHandlerServer " ) ;
}
2023-05-16 16:27:20 +02:00
}
// sem
2023-05-16 18:43:56 +02:00
if ( semid ) {
2023-05-16 23:27:27 +02:00
printf ( " \n " ) ;
printfServer ( " Deleting sem " ) ;
2023-05-16 18:43:56 +02:00
if ( semctl ( semid , 0 , IPC_RMID , 0 ) = = - 1 ) {
errExit ( " semctl " , " sigHandlerServer " ) ;
}
2023-05-16 16:27:20 +02:00
}
// shm
2023-05-16 18:43:56 +02:00
if ( board ) {
2023-05-16 23:27:27 +02:00
printf ( " \n " ) ;
printfServer ( " Detathing shm " ) ;
2023-05-16 18:43:56 +02:00
if ( shmdt ( board ) = = - 1 ) {
errExit ( " shmdt " , " sigHandlerServer " ) ;
}
}
if ( shmid ) {
2023-05-16 23:27:27 +02:00
printf ( " \n " ) ;
printfServer ( " Deleting shm " ) ;
2023-05-16 18:43:56 +02:00
if ( shmctl ( shmid , IPC_RMID , NULL ) = = - 1 ) {
errExit ( " shmctl " , " SigHandlerSever " ) ;
}
2023-05-16 16:27:20 +02:00
}
2023-05-16 23:27:27 +02:00
2023-05-17 15:46:51 +02:00
2023-05-16 23:27:27 +02:00
printf ( " \n " ) ;
2023-05-16 15:26:58 +02:00
}
2023-05-15 16:50:48 +02:00
exit ( 0 ) ;
}
2023-05-14 17:07:34 +02:00
2023-05-14 18:03:50 +02:00
2023-05-14 17:07:34 +02:00
int main ( int argc , char * argv [ ] ) {
2023-05-14 18:08:10 +02:00
input_server_t input = check_input ( argc , argv ) ;
2023-05-14 18:03:50 +02:00
2023-05-16 14:55:12 +02:00
// SIGNAL
2023-05-16 18:43:56 +02:00
printfServer ( " Setting up signals \n " ) ;
2023-05-15 16:50:48 +02:00
sigset_t mySet ;
sigfillset ( & mySet ) ;
sigdelset ( & mySet , SIGINT ) ;
2023-05-16 15:26:58 +02:00
sigdelset ( & mySet , SIGTERM ) ;
2023-05-17 15:46:51 +02:00
sigdelset ( & mySet , SIGHUP ) ;
2023-05-15 16:50:48 +02:00
sigprocmask ( SIG_SETMASK , & mySet , NULL ) ;
2023-05-16 16:10:43 +02:00
if ( signal ( SIGINT , sigHandlerServer ) = = SIG_ERR ) {
2023-05-16 15:26:58 +02:00
errExit ( " signal SIGINT " , " f4Server " ) ;
2023-05-16 15:55:05 +02:00
}
2023-05-16 16:10:43 +02:00
if ( signal ( SIGTERM , sigHandlerServer ) = = SIG_ERR ) {
2023-05-16 15:26:58 +02:00
errExit ( " signal SIGTERM " , " f4Server " ) ;
2023-05-16 15:55:05 +02:00
}
2023-05-16 14:55:12 +02:00
//
2023-05-16 16:10:43 +02:00
2023-05-16 14:55:12 +02:00
// MSGQ
2023-05-16 18:43:56 +02:00
printfServer ( " Setting up msgq \n " ) ;
2023-05-16 17:07:35 +02:00
//TODO: forse bisogna fare il reset della shm, perche in teoria mette a 0 quando crea
2023-05-16 18:43:56 +02:00
//ma nel caso in cui il campo non si fosse chiuso per qualche motivo forse quando lo riapre non lo azzera
2023-05-16 14:55:12 +02:00
key_t msgKey = ftok ( KEYFILE , ' M ' ) ;
2023-05-18 12:45:32 +02:00
_MSGQID = msgget ( msgKey , IPC_CREAT | S_IRUSR | S_IWUSR ) ;
if ( _MSGQID = = - 1 ) {
2023-05-16 16:10:43 +02:00
errExit ( " msgget " , " F4Server " ) ;
2023-05-16 15:55:05 +02:00
}
2023-05-16 16:10:43 +02:00
// msg
2023-05-16 15:55:05 +02:00
msg_t msg = {
. mtype = 1 ,
2023-05-16 17:07:35 +02:00
. server_in = input ,
. player_id = 0
2023-05-16 15:55:05 +02:00
} ;
// msgsnd
2023-05-19 15:21:15 +02:00
sndMsg ( & msg ) ;
2023-05-16 17:07:35 +02:00
msg . player_id = 1 ;
2023-05-19 15:21:15 +02:00
sndMsg ( & msg ) ;
2023-05-16 14:55:12 +02:00
//
2023-05-15 16:50:48 +02:00
2023-05-16 16:10:43 +02:00
// SHM
2023-05-16 18:43:56 +02:00
printfServer ( " Setting up shm \n " ) ;
2023-05-16 16:27:20 +02:00
shmid = getShmid ( input . rows , input . collums ) ;
board = shmServerAt ( shmid ) ;
2023-05-16 16:10:43 +02:00
//
2023-05-16 18:43:56 +02:00
//
printfServer ( " Setting up sem \n " ) ;
2023-05-16 16:10:43 +02:00
key_t semKey = ftok ( KEYFILE , ' S ' ) ;
2023-05-16 23:27:27 +02:00
semid = semget ( semKey , 3 , IPC_CREAT | S_IRUSR | S_IWUSR ) ;
2023-05-16 16:32:24 +02:00
if ( semid = = - 1 ) {
2023-05-16 16:10:43 +02:00
errExit ( " getsem " , " F4Server " ) ;
}
resetServerSem ( semid ) ;
//
2023-05-15 16:50:48 +02:00
2023-05-16 23:27:27 +02:00
// aperurta semaforo per connessione dei due client
2023-05-16 18:43:56 +02:00
printfServer ( " Waiting for players... \n " ) ;
2023-05-16 23:27:27 +02:00
semOp ( semid , 0 , 1 ) ;
semOp ( semid , 1 , 1 ) ;
2023-05-14 22:13:42 +02:00
2023-05-16 23:27:27 +02:00
// aspetto che si connettano i due client
//FIXME: forse non serve perche tanto deve aspettare che i player gli mandono un messaggio con il loro nome (a cose servono i semafori se ci sono i messaggi che fanno l'attesa non in polling aaaaaaaaa)
semOp ( semid , 2 , - 1 ) ;
2023-05-14 17:07:34 +02:00
2023-05-17 15:57:10 +02:00
player_ds player ;
2023-05-17 14:24:46 +02:00
char name [ 2 ] [ MAX_NAME ] ;
2023-05-17 15:46:51 +02:00
pids [ 2 ] ;
2023-05-16 23:27:27 +02:00
// ricevuta nome primo client
2023-05-19 15:21:15 +02:00
rcvPlayer ( & player ) ;
2023-05-16 23:27:27 +02:00
2023-05-17 15:57:10 +02:00
strcpy ( name [ player . id ] , player . name_player ) ;
pids [ player . id ] = player . pid ;
2023-05-17 10:45:16 +02:00
2023-05-16 23:27:27 +02:00
printfServer ( " Player " ) ;
2023-05-17 15:57:10 +02:00
printf ( " %s connected \n " , name [ player . id ] ) ;
2023-05-16 23:27:27 +02:00
// aspetto secondo client
semOp ( semid , 2 , - 1 ) ;
// ricevuta nome secondo client
2023-05-19 15:21:15 +02:00
rcvPlayer ( & player ) ;
2023-05-17 15:57:10 +02:00
strcpy ( name [ player . id ] , player . name_player ) ;
pids [ player . id ] = player . pid ;
2023-05-16 23:27:27 +02:00
printfServer ( " Player " ) ;
2023-05-17 15:57:10 +02:00
printf ( " %s connected \n " , name [ player . id ] ) ;
2023-05-16 23:27:27 +02:00
2023-05-17 15:57:10 +02:00
semOp ( semid , 0 , 1 ) ;
semOp ( semid , 1 , 1 ) ;
2023-05-16 23:27:27 +02:00
// PARTITA
printfServer ( " Starting game \n " ) ;
2023-05-17 10:42:16 +02:00
setCollums ( input . collums ) ;
setRows ( input . rows ) ;
2023-05-15 11:57:30 +02:00
2023-05-16 16:53:23 +02:00
int turns_left = input . rows * input . collums ;
2023-05-16 17:07:35 +02:00
int turn = 0 ;
2023-05-17 15:46:51 +02:00
tile_t result ;
2023-05-16 16:53:23 +02:00
move_t move ;
do {
2023-05-16 17:07:35 +02:00
semOp ( semid , turn , 1 ) ;
2023-05-18 10:50:06 +02:00
turn ^ = 1 ;
2023-05-16 16:53:23 +02:00
2023-05-16 23:27:27 +02:00
printfServer ( " " ) ;
printf ( " %s's turn \n " , name [ turn ] ) ;
2023-05-16 18:43:56 +02:00
2023-05-19 15:21:15 +02:00
rcvMove ( & move ) ;
2023-05-16 16:53:23 +02:00
2023-05-16 23:27:27 +02:00
//TMP
printf ( " move: %d \n " , move . move ) ;
printf ( " turns left: %d \n " , turns_left - 1 ) ;
2023-05-16 16:53:23 +02:00
2023-05-17 15:46:51 +02:00
} while ( - - turns_left & & ! ( result = checkWin ( board , move . move ) ) ) ;
2023-05-16 16:53:23 +02:00
2023-05-15 11:57:30 +02:00
2023-05-18 13:57:41 +02:00
if ( ! result ) { //FIXME: change printf
printfServer ( " Game ended in a draw \n " ) ;
2023-05-16 17:07:35 +02:00
} else {
2023-05-18 13:57:41 +02:00
printfServer ( " Game ended \n " ) ;
2023-05-16 17:07:35 +02:00
}
2023-05-19 15:21:15 +02:00
game_end_t game_end = { . mtype = 4 , . winner = result } ;
sndGame_end ( & game_end ) ;
sndGame_end ( & game_end ) ;
2023-05-18 13:57:41 +02:00
kill ( pids [ 0 ] , SIGUSR1 ) ;
kill ( pids [ 1 ] , SIGUSR1 ) ;
2023-05-16 17:07:35 +02:00
2023-05-15 11:57:30 +02:00
2023-05-16 17:07:35 +02:00
//TODO: end of game
2023-05-15 11:57:30 +02:00
2023-05-14 17:07:34 +02:00
return 0 ;
2023-05-16 18:43:56 +02:00
}