#include #include #include #include #include "server_code_etudiant.h" /* use an array of clients */ client_t *clients[MAX_CLIENTS]; #define WORD_LEN 7 static char mot_a_trouver[WORD_LEN+1]; struct joueur { client_t *client; int score; struct joueur *next; }; struct joueur* leaderboard = NULL; /* return 1 if c is uppercase */ int is_upper(const char c) { return c>='A' && c<='Z'; } /* return 1 if c is lowercase */ int is_lower(const char c) { return c>='a' && c<='z'; } /* converts a char to lower-case */ char lower(const char c) {return is_upper(c) ? c-('A'-'a') : c; } /* converts a char to upper-case */ char upper(const char c) { return is_lower(c) ? c+('A'-'a') : c; } /* Strip CRLF */ void strip_newline(char *s) { while(*s != '\0') { if(*s == '\r' || *s == '\n') *s = '\0'; s++; } } client_t *get_client_from_fd(int fd) { int i; for(i=0; ifd == fd) return clients[i]; } return NULL; } client_t *get_client_from_name(char* name) { int i; for(i=0; iname, name) == 0) { return clients[i]; } } } return NULL; } void server_init() { memset(clients, 0, sizeof(client_t*)*MAX_CLIENTS); struct sigaction s; s.sa_handler = server_finalize; sigaction(SIGINT, &s, NULL); sigaction(SIGTERM, &s, NULL); sigaction(SIGKILL, &s, NULL); } void server_finalize(int signo) { char buff_out[1024]; sprintf(buff_out, "* The server is about to stop.\n"); send_message_all(buff_out); exit(EXIT_SUCCESS); } /* Add client to queue */ void queue_add(client_t *cl){ int i; for(i=0;iuid == client->uid){ clients[i] = NULL; return; } } } } /* Send a message to a client */ void send_message(char *s, client_t *client){ fwrite(s, sizeof(char), strlen(s), client->client_conn); } /* Send message to all clients */ void send_message_all(char *s){ int i; for(i=0;iname, new_name, NAME_MAX_LENGTH); printf("new name: %s (num %d)\n", cli->name, selected_line); fclose(f); } /* Send list of active clients */ void send_active_clients(client_t *client){ char s[64]; int i; for(i=0;iuid, clients[i]->name); send_message(s, client); } } } static void get_random_word(char word[WORD_LEN+1]) { /* TODO */ } void process_cmd_classement(client_t* client, char*param) { /* TODO */ } void add_points(client_t* client, int nb_points) { /* TODO: - remove the client from the list - allocate/update a player score - insert a player in the list */ } void process_cmd_motus(client_t* client, char*param) { /* TODO */ } static int comparer_mots(char mot_propose[WORD_LEN+1], char mot_masque[WORD_LEN+1]) { int ncorrect = 0; /* TODO */ return ncorrect; } void process_cmd_unmot(client_t* client, char*param) { char mot_propose[WORD_LEN+1]; strncpy(mot_propose, param, WORD_LEN); mot_propose[WORD_LEN]='\0'; char mot_masque[WORD_LEN+1]; int ncorrect = comparer_mots(mot_propose, mot_masque); char buff_out[1024]; sprintf(buff_out, "* Motus: %s suggests %s\n", client->name, mot_propose); send_message_all(buff_out); if(ncorrect == WORD_LEN) { sprintf(buff_out, "* Motus: congratulations to %s who found '%s'\n", client->name, mot_masque); send_message_all(buff_out); add_points(client, 100); } else { sprintf(buff_out, "* Motus: -> %s\n", mot_masque); send_message_all(buff_out); } } void process_cmd_names(client_t* client, char*param) { if(! fork()) { char buff_out[1024]; sprintf(buff_out, "* There are %d clients\n", cli_count); send_message(buff_out, client); send_active_clients(client); exit(EXIT_SUCCESS); } } /* this function is called when a client connects to the server */ void say_hello(client_t *cli) { char buff_out[1024]; /* choose a default name */ assign_default_name(cli); sprintf(buff_out, "* %s joins the chatroom\n", cli->name); send_message_all(buff_out); } void process_cmd_msg(client_t*client, char*param) { char*dest = strsep(¶m, " "); if(!dest){ send_message("* to who ?\n", client); return; } char buffer[1024]; sprintf(buffer, "[PM][%s --> %s] %s\n", client->name, dest, param); client_t* to = get_client_from_name(dest); if(!to ){ send_message("* %s does not exist!\n", client); } else { send_message(buffer, to); send_message(buffer, client); } } void process_cmd_me(client_t*client, char*param) { char buff_out[1024]; sprintf(buff_out, " *%s %s\n", client->name, param); send_message_all(buff_out); } void process_cmd_help(client_t* client) { char buff_out[1024]; sprintf(buff_out, "/help Show help\n"); strcat(buff_out, "/me Send an action message\n"); strcat(buff_out, "/msg Send private message\n"); strcat(buff_out, "/names Show active clients\n"); strcat(buff_out, "/ping Server test\n"); strcat(buff_out, "/motus Start a Motus game\n"); strcat(buff_out, "/unmot Propose a word to the Motus game\n"); strcat(buff_out, "/quit Quit chatroom\n"); send_message(buff_out, client); } void process_cmd_ping(client_t* client, char* param) { send_message("* pong\n", client); } void handle_incoming_cmd(client_t *cli) { char buff_out[1024]; char buff_in[1024]; if(fgets(buff_in, 1024*sizeof(char), cli->client_conn) == 0) { if(!feof(cli->client_conn)) { perror("read failed"); abort(); } else { printf("Client %s disconnected\n", cli->name); queue_delete(cli); return; } } strip_newline(buff_in); /* Ignore empty buffer */ if(!strlen(buff_in)){ printf("Empty message\n"); } /* Special options */ char *cmd_line = buff_in; if(buff_in[0] == '/'){ char *command; command = strsep(&cmd_line," "); if(!strcmp(command, "/quit")){ return; } else if(!strcmp(command, "/ping")) { process_cmd_ping(cli, cmd_line); } else if(!strcmp(command, "/msg")) { process_cmd_msg(cli, cmd_line); } else if(!strcmp(command, "/me")) { process_cmd_me(cli, cmd_line); } else if(!strcmp(command, "/names")) { process_cmd_names(cli, cmd_line); } else if(!strcmp(command, "/motus")) { process_cmd_motus(cli, cmd_line); } else if(!strcmp(command, "/unmot")) { process_cmd_unmot(cli, cmd_line); } else if(!strcmp(command, "/classement")) { process_cmd_classement(cli, cmd_line); } else { /* /help or unknown command */ process_cmd_help(cli); } }else{ /* Send message */ sprintf(buff_out, "[%s] %s\n", cli->name, cmd_line); send_message_all(buff_out); } }