Arthur Brandao 6 жил өмнө
parent
commit
4597bf13fd

+ 1 - 0
Serveur/constante.h

@@ -35,6 +35,7 @@
 #define MAXGAME 5 //Nombre maximum de parti autorisé en simultané
 #define MAXPLAYER 4 //Nombre max de joueur par parti
 #define MAPDIR "map/" //Chemin vers le dossier des maps
+#define TIMEMAJOR 10 //Temps du major en seconde
 
 /* --- Reseaux --- */
 #define PORT_UDP 18624

+ 35 - 5
Serveur/delay.c

@@ -11,14 +11,22 @@
 #include <pthread.h>
 #include "error.h"
 #include "delay.h"
+#include "bomberstudent_server.h"
+
+/* --- Extern --- */
+extern Game game[MAXGAME];
+extern int nbGame;
+extern pthread_mutex_t gameMutex[MAXGAME];
+extern pthread_mutex_t playerMutex[MAXGAME * MAXPLAYER];
 
 /* --- Fonctions privées --- */
+
 /**
  * Thread d'attente de la fonction timer
  * @param void* La structure timer_data cast en void*
  * @return NULL
  */
-void* delay_thread(void* data){
+void* delay_thread(void* data) {
     delay_t* d;
     //Recup données
     d = (delay_t*) data;
@@ -30,16 +38,24 @@ void* delay_thread(void* data){
     //Attend le temps indiqué
     sleep(d->second);
     //Appel callback
-    if(d->callback(&game[d->game], d->player) != SUCCESS){
-        adderror("Erreur callback Delay");
+    pthread_mutex_lock(&gameMutex[d->game]);
+    if (game[d->game].active) {
+        pthread_mutex_lock(&playerMutex[(d->game * MAXPLAYER) + d->player]);
+        if (game[d->game].player[d->player]->ini) {
+            if (d->callback(&game[d->game], d->player) != SUCCESS) {
+                adderror("Erreur callback Delay");
+            }
+        }
+        pthread_mutex_unlock(&playerMutex[(d->game * MAXPLAYER) + d->player]);
     }
+    pthread_mutex_unlock(&gameMutex[d->game]);
     return NULL;
 }
 
 /* --- Fonctions publiques --- */
-void delay(int second, int game, int player, int(*callback)(Game*, int)){
+void delay(int second, int game, int player, int(*callback)(Game*, int)) {
     pthread_t thread;
-    delay_t* d = malloc(sizeof(timer_t));
+    delay_t* d = malloc(sizeof (timer_t));
     d->second = second;
     d->game = game;
     d->player = player;
@@ -48,4 +64,18 @@ void delay(int second, int game, int player, int(*callback)(Game*, int)){
     if (pthread_create(&thread, NULL, delay_thread, d) != 0) {
         adderror("Impossible de créer le thread Delay");
     }
+}
+
+int callback_major_end(Game* g, int playerIndex) {
+    JsonEncoder notif;
+    //Retire le bonus major
+    g->player[playerIndex]->major = 0;
+    //Creation json
+    ini_encoder(&notif);
+    describe_player(g->player[playerIndex], &notif);
+    //Envoi
+    if (!notify_client(g->player[playerIndex]->cli, "POST", "player/major/end", &notif)) {
+        return FAIL;
+    }
+    return SUCCESS;
 }

+ 3 - 0
Serveur/delay.h

@@ -20,6 +20,7 @@ typedef struct{
     int(*callback)(Game*, int);
 }delay_t;
 
+/* --- Fonctions --- */
 /**
  * Attend X secondes (sans bloquer l'execution) avant d'executer le callback
  * @param int Nombre de second en attente
@@ -29,5 +30,7 @@ typedef struct{
  */
 void delay(int, int, int, int(*)(Game*, int));
 
+int callback_major_end(Game*, int);
+
 #endif /* DELAY_H */
 

+ 1 - 0
Serveur/game.c

@@ -177,6 +177,7 @@ int create_game(char* name, char* map) {
     }
     game[index].object = malloc(sizeof(Object));
     object_ini(game[index].object);
+    //object_add(game[index].object, OBJ_MAJOR, 1, 1);
     pthread_mutex_unlock(&gameMutex[index]);
     //Retourne la position de la partie dans le tableau
     nbGame++;

+ 114 - 0
Serveur/handler.c

@@ -12,6 +12,7 @@
 #include "bomberstudent_server.h"
 #include "client.h"
 #include "player.h"
+#include "delay.h"
 #include "handler.h"
 
 /* --- Extern --- */
@@ -88,6 +89,7 @@ void ini_handler() {
     add_handler("POST", "game/join", handler_game_join);
     add_handler("POST", "game/quit", handler_game_quit);
     add_handler("POST", "player/move", handler_player_move);
+    add_handler("POST", "object/new", handler_object_new);
 }
 
 int handler_client_end(int cliId, JsonParser* json) {
@@ -417,3 +419,115 @@ int handler_player_move(int cliId, JsonParser* json) {
     free(move);
     return SUCCESS;
 }
+
+int handler_object_new(int cliId, JsonParser* json) {
+    char* class;
+    int index, type, length, playerIndex = 0;
+    Player* p = NULL;
+    obj_node* objn;
+    JsonEncoder reponse;
+    //Verification arguments
+    if (get_pos(json, "class") == JSON_ERROR) {
+        send_err_client(cliId, EREQUEST);
+        adderror("Le json du client est incorrect");
+        return FAIL;
+    }
+    //Recup valeur
+    class = get_string(json, "class");
+    //Verif valeur class
+    length = strlen(class);
+    if (strncmp(class, "classic", length) == 0) {
+        type = OBJ_BCLASSIC;
+    } else if (strncmp(class, "mine", length) == 0) {
+        type = OBJ_BMINE;
+    } else if (strncmp(class, "remote", length) == 0) {
+        type = OBJ_BREMOTE;
+    } else if (strncmp(class, "bomb_up", length) == 0) {
+        type = OBJ_BOMBUP;
+    } else if (strncmp(class, "bomb_down", length) == 0) {
+        type = OBJ_BOMBDOWN;
+    } else if (strncmp(class, "fire_power", length) == 0) {
+        type = OBJ_FIREPOWER;
+    } else if (strncmp(class, "scooter", length) == 0) {
+        type = OBJ_SCOOTER;
+    } else if (strncmp(class, "broken_legs", length) == 0) {
+        type = OBJ_BROKENLEG;
+    } else if (strncmp(class, "life_up", length) == 0) {
+        type = OBJ_LIFEUP;
+    } else if (strncmp(class, "life_max", length) == 0) {
+        type = OBJ_LIFEMAX;
+    } else if (strncmp(class, "major", length) == 0) {
+        type = OBJ_MAJOR;
+    } else {
+        free(class);
+        send_err_client(cliId, EREQUEST);
+        adderror("Le json du client est incorrect");
+        return FAIL;
+    }
+    //Verif game existe
+    index = search_client_game(cliId);
+    if (index == ERR) {
+        free(class);
+        send_err_client(cliId, EREQUEST);
+        adderror("La game du client n'existe pas");
+        return FAIL;
+    }
+    //Recup le joueur
+    pthread_mutex_lock(&gameMutex[index]);
+    for (int i = 0; i < MAXPLAYER; i++) {
+        pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + i]);
+        if (game[index].player[i]->ini && game[index].player[i]->id == cliId) {
+            playerIndex = i;
+            p = game[index].player[i];
+            pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
+            break;
+        }
+        pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
+    }
+    if (p == NULL) {
+        pthread_mutex_unlock(&gameMutex[index]);
+        free(class);
+        adderror("Aucun joueur associé au client");
+        return FAIL;
+    }
+    //Initialisation json
+    ini_encoder(&reponse);
+    add_string(&reponse, "action", "object/new");
+    //Regarde si un objet correspond
+    objn = object_search(game[index].object, type, p->x, p->y);
+    if (objn == NULL) {
+        add_integer(&reponse, "status", 501);
+        add_string(&reponse, "message", "No object");
+        //Envoi
+        if (!send_client(cliId, &reponse)) {
+            adderror("Impossible de répondre au client");
+            clean_json_encoder(&reponse);
+            free(class);
+            return FAIL;
+        }
+    } else {
+        //Ajoute l'objet au joueur
+        pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
+        add_player_object(p, type);
+        //Creation reponse
+        add_integer(&reponse, "status", 201);
+        describe_player(p, &reponse);
+        pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
+        //Envoi
+        if (!send_client(cliId, &reponse)) {
+            adderror("Impossible de répondre au client");
+            clean_json_encoder(&reponse);
+            free(class);
+            return FAIL;
+        }
+        //Si major lance le timer pour avertir de la fin
+        if(type == OBJ_MAJOR){
+            delay(TIMEMAJOR, index, playerIndex, callback_major_end);
+        }
+    }
+    //Nettoyage
+    pthread_mutex_unlock(&gameMutex[index]);
+    free(class);
+    clean_json_encoder(&reponse);
+    return SUCCESS;
+}

+ 51 - 2
Serveur/player.c

@@ -8,6 +8,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "player.h"
+#include "object.h"
 
 void create_player(Player* p, Client* c){
     //Initialisation valeurs
@@ -36,8 +37,6 @@ void create_player(Player* p, Client* c){
 void describe_player(Player* p, JsonEncoder* desc){
     JsonEncoder* bonus = malloc(sizeof(JsonEncoder));
     JsonArray* bm = malloc(sizeof(JsonArray));
-    /*JsonArray* bonus = malloc(sizeof(JsonArray));
-    char buffer[BUFFER_SIZE];*/
     //Initialisation
     ini_encoder(desc);
     ini_encoder(bonus);
@@ -117,6 +116,56 @@ void describe_short_player(Player* p, JsonEncoder* desc){
     add_string(desc, "pos", pos);
 }
 
+void add_player_object(Player* p, int type){
+    switch(type){
+        case OBJ_BCLASSIC:
+            p->classicBomb++;
+            break;
+        case OBJ_BMINE:
+            p->mine++;
+            break;
+        case OBJ_BREMOTE:
+            p->remoteBomb++;
+            break;
+        case OBJ_BOMBUP:
+            p->bombUp++;
+            p->maxBomb++;
+            break;
+        case OBJ_BOMBDOWN:
+            p->bombDown++;
+            if(p->maxBomb > 1){
+                p->maxBomb--;
+            }
+            break;
+        case OBJ_FIREPOWER:
+            p->firePower++;
+            break;
+        case OBJ_SCOOTER:
+            p->scooter++;
+            p->speed++;
+            break;
+        case OBJ_BROKENLEG:
+            p->brokenLeg++;
+            if(p->speed > 1){
+                p->speed--;
+            }
+            break;
+        case OBJ_LIFEUP:
+            p->lifeUp++;
+            p->maxLife = (int) p->maxLife * 1.1;
+            break;
+        case OBJ_LIFEMAX:
+            p->lifeMax++;
+            p->life = p->maxLife;
+            break;
+        case OBJ_MAJOR:
+            if(p->major == 0){
+                p->major = 1;
+            }
+            break;
+    }
+}
+
 void delete_player(Player* p){
     p->cli = NULL;
     p->ini = false;

+ 2 - 0
Serveur/player.h

@@ -51,6 +51,8 @@ void describe_player(Player*, JsonEncoder*);
 
 void describe_short_player(Player*, JsonEncoder*);
 
+void add_player_object(Player*, int);
+
 /**
  * Supprime un joueur
  * @param Player* La structure à supprimer