| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- /*
- * File: handler.c
- * Author: Arthur Brandao
- *
- * Created on 23 novembre 2018
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- #include "error.h"
- #include "bomberstudent_server.h"
- #include "client.h"
- #include "player.h"
- #include "handler.h"
- /* --- Extern --- */
- extern Game game[MAXGAME];
- extern int nbGame;
- /* --- Fonctions privées --- */
- /**
- * Thread d'attente de la fonction timer
- * @param void* La structure timer_data cast en void*
- * @return NULL
- */
- void* timer_thread(void* data){
- timer_data* t;
- //Recup données
- t = (timer_data*) data;
- //Detache le thread
- if (pthread_detach(pthread_self()) != 0) {
- adderror("Impossible de détacher le thread Timer");
- return NULL;
- }
- //Attend le temps indiqué
- sleep(t->second);
- //Appel callback
- if(t->callback(&game[t->game], t->player) != SUCCESS){
- adderror("Erreur callback Timer");
- }
- return NULL;
- }
- /**
- * Attend X second (sans bloquer l'execution) avant d'executer le callback
- * @param int Nombre de second en attente
- * @param int Index de la game
- * @param int Index du joueur dans la game
- * @param int(*)(Game*, int) Le callback
- */
- void timer(int second, int game, int player, int(*callback)(Game*, int)){
- pthread_t thread;
- timer_data* t = malloc(sizeof(timer_t));
- t->second = second;
- t->game = game;
- t->player = player;
- t->callback = callback;
- //Creation thread
- if (pthread_create(&thread, NULL, timer_thread, t) != 0) {
- adderror("Impossible de créer le thread Timer");
- }
- }
- /**
- * Cherche dans quel partie est un client
- * @param int L'id du client
- * @return int L'index de la partie
- */
- int search_client_game(int cliId){
- int index = ERR;
- for(int i = 0; i < MAXGAME; i++){
- //Regarde si la game est active et avec des joueurs
- if(game[i].active && game[i].nbPlayer > 0){
- //Parcours les joueurs
- for(int j = 0; j < MAXPLAYER; j++){
- //Si le joueur est actif
- if(game[i].player[j]->ini){
- //Si l'id est le bon
- if(game[i].player[j]->id == cliId){
- index = i;
- break;
- }
- }
- }
- }
- //Si on a un resultat
- if(index != ERR){
- break;
- }
- }
- //Retour
- return index;
- }
- /**
- * Cherche une partie par son nom
- * @param char* Le nom de la partie
- * @return int L'index dans le tableau
- */
- int search_game(char* name){
- int index = ERR;
- for(int i = 0; i < MAXGAME; i++){
- //Regarde si la game est active et le nom
- if(game[i].active && strncmp(game[i].name, name, strlen(game[i].name)) == 0){
- index = i;
- break;
- }
- }
- return index;
- }
- /* --- Fonctions publiques --- */
- void ini_handler(){
- //Get
- add_handler("GET", "client/end", handler_client_end);
- add_handler("GET", "game/list", handler_game_list);
- //Post
- add_handler("POST", "game/create", handler_game_create);
- }
- int handler_client_end(int cliId, JsonParser* json){
- printf("Deconnexion du client %d\n", cliId);
- remove_client(cliId);
- return SUCCESS;
- }
- int handler_game_list(int cliId, JsonParser* json){
- JsonEncoder reponse;
- JsonArray* game;
- JsonArray* map;
- //Recup la liste des parties et des cartes
- game = list_game();
- map = list_map();
- //Creation reponse
- ini_encoder(&reponse);
- add_string(&reponse, "action", "game/list");
- add_string(&reponse, "status", "200");
- add_string(&reponse, "message", "ok");
- if(game == NULL){
- add_integer(&reponse, "numberGameList", 0);
- } else {
- add_integer(&reponse, "numberGameList", nbGame);
- add_array(&reponse, "games", game);
- clean_json_array(game);
- free(game);
- }
- add_array(&reponse, "maps", map);
- //Envoi reponse au client
- if(!send_client(cliId, &reponse)){
- adderror("Impossible de répondre au client");
- return FAIL;
- }
- //Nettoyage
- clean_json_encoder(&reponse);
- clean_json_array(map);
- free(map);
- return SUCCESS;
- }
- int handler_game_create(int cliId, JsonParser* json){
- char* map, * name, * msg;
- int index, joueur;
- JsonEncoder* reponse;
- //Verification arguments
- if(get_pos(json, "name") == JSON_ERROR){
- send_err_client(cliId, EREQUEST);
- adderror("Le json du client est incorrect");
- return FAIL;
- }
- if(get_pos(json, "map") == JSON_ERROR){
- send_err_client(cliId, EREQUEST);
- adderror("Le json du client est incorrect");
- return FAIL;
- }
- //Recup valeur
- map = get_string(json, "map");
- name = get_string(json, "name");
- //Verif nom non existant
- if(search_game(name) != ERR){
- reponse = malloc(sizeof(JsonEncoder));
- ini_encoder(reponse);
- add_string(reponse, "status", "501");
- add_string(reponse, "message", "Cannot create game");
- if(!send_client(cliId, reponse)){
- adderror("Impossible de répondre au client");
- }
- clean_json_encoder(reponse);
- free(reponse);
- return FAIL;
- }
- //Creation
- index = create_game(name, map);
- if(index == ERR){
- reponse = malloc(sizeof(JsonEncoder));
- ini_encoder(reponse);
- add_string(reponse, "status", "501");
- add_string(reponse, "message", "Cannot create game");
- if(!send_client(cliId, reponse)){
- adderror("Impossible de répondre au client");
- }
- clean_json_encoder(reponse);
- free(reponse);
- return FAIL;
- }
- //Ajout du joueur dans la partie
- joueur = add_player(&game[index], cliId);
- if(joueur == ERR){
- stop_game(&game[index]);
- reponse = malloc(sizeof(JsonEncoder));
- ini_encoder(reponse);
- add_string(reponse, "action", "game/create");
- add_string(reponse, "status", "501");
- add_string(reponse, "message", "Cannot create game");
- if(!send_client(cliId, reponse)){
- adderror("Impossible de répondre au client");
- }
- clean_json_encoder(reponse);
- free(reponse);
- return FAIL;
- }
- //Recup info
- reponse = describe_game(&game[index], joueur);
- //Ajout infos
- msg = new_string(25 + strlen(map));
- sprintf(msg, "Game created with %s", map);
- add_string(reponse, "action", "game/create");
- add_string(reponse, "status", "201");
- add_string(reponse, "message", msg);
- add_string(reponse, "startPos", "0,0");
- free(msg);
- //Envoi
- if(!send_client(cliId, reponse)){
- adderror("Impossible de répondre au client");
- clean_json_encoder(reponse);
- free(reponse);
- return FAIL;
- }
- //Nettoyage
- clean_json_encoder(reponse);
- free(reponse);
- free(map);
- free(name);
- return SUCCESS;
- }
|