|
@@ -17,8 +17,11 @@
|
|
|
/* --- Extern --- */
|
|
|
Game game[MAXGAME];
|
|
|
int nbGame = 0;
|
|
|
+pthread_mutex_t gameMutex[MAXGAME];
|
|
|
+pthread_mutex_t playerMutex[MAXGAME * MAXPLAYER];
|
|
|
|
|
|
/* --- Fonctions privées --- */
|
|
|
+
|
|
|
/**
|
|
|
* Transforme le fichier map en un tableau 2D
|
|
|
* @param char* Le contenu du fichier map
|
|
@@ -26,15 +29,15 @@ int nbGame = 0;
|
|
|
* @param int Hauteur de la map
|
|
|
* @return char** La map parser
|
|
|
*/
|
|
|
-char** parse_map(char* mapContent, int width, int height){
|
|
|
- char** map = malloc(sizeof(char*) * width);
|
|
|
+char** parse_map(char* mapContent, int width, int height) {
|
|
|
+ char** map = malloc(sizeof (char*) * width);
|
|
|
//Creation des colonnes
|
|
|
- for(int i = 0; i < width; i++){
|
|
|
- map[i] = malloc(sizeof(char) * height);
|
|
|
+ for (int i = 0; i < width; i++) {
|
|
|
+ map[i] = malloc(sizeof (char) * height);
|
|
|
}
|
|
|
//Remplissage
|
|
|
- for(int i = 0; i < height; i++){
|
|
|
- for(int j = 0; j < width; j++){
|
|
|
+ for (int i = 0; i < height; i++) {
|
|
|
+ for (int j = 0; j < width; j++) {
|
|
|
map[j][i] = *mapContent;
|
|
|
mapContent++;
|
|
|
}
|
|
@@ -44,36 +47,55 @@ char** parse_map(char* mapContent, int width, int height){
|
|
|
}
|
|
|
|
|
|
/* --- Fonctions publiques --- */
|
|
|
-void ini_games(){
|
|
|
- for(int i = 0; i < MAXGAME; i++){
|
|
|
+boolean ini_games() {
|
|
|
+ //Ini les games
|
|
|
+ for (int i = 0; i < MAXGAME; i++) {
|
|
|
game[i].active = false;
|
|
|
+ game[i].index = i;
|
|
|
+ }
|
|
|
+ //Ini les mutex des games
|
|
|
+ for (int i = 0; i < MAXGAME; i++) {
|
|
|
+ if (pthread_mutex_init(&gameMutex[i], NULL) != 0) {
|
|
|
+ adderror("Impossible d'initialiser les mutex des games");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
+ //Ini les mutex des joueurs des games
|
|
|
+ for (int i = 0; i < MAXGAME * MAXPLAYER; i++) {
|
|
|
+ if (pthread_mutex_init(&playerMutex[i], NULL) != 0) {
|
|
|
+ adderror("Impossible d'initialiser les mutex des joueurs");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
-void list_map(JsonArray* res){
|
|
|
+void list_map(JsonArray* res) {
|
|
|
char** result;
|
|
|
int nbResult;
|
|
|
//Regarde les fichiers dans le dossier
|
|
|
result = file_list(MAPDIR, &nbResult);
|
|
|
- for(int i = 0; i < nbResult; i++){
|
|
|
+ for (int i = 0; i < nbResult; i++) {
|
|
|
add_array_string(res, result[i]);
|
|
|
free(result[i]);
|
|
|
}
|
|
|
free(result);
|
|
|
}
|
|
|
|
|
|
-int list_game(JsonArray* res){
|
|
|
+int list_game(JsonArray* res) {
|
|
|
JsonEncoder gameJson;
|
|
|
int compteur = 0, i = 0;
|
|
|
//Si il n' y a aucune game
|
|
|
- if(nbGame == 0){
|
|
|
+ if (nbGame == 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
//Initialisation json
|
|
|
ini_encoder(&gameJson);
|
|
|
//Ajoute chaque game
|
|
|
- while(compteur < nbGame && i < MAXGAME){
|
|
|
- if(!game[i].active){
|
|
|
+ while (compteur < nbGame && i < MAXGAME) {
|
|
|
+ pthread_mutex_lock(&gameMutex[i]);
|
|
|
+ if (!game[i].active) {
|
|
|
+ pthread_mutex_unlock(&gameMutex[i]);
|
|
|
i++;
|
|
|
continue;
|
|
|
}
|
|
@@ -86,29 +108,30 @@ int list_game(JsonArray* res){
|
|
|
//Nettoyage encoder objet
|
|
|
clean_json_encoder(&gameJson);
|
|
|
//Incremente
|
|
|
+ pthread_mutex_unlock(&gameMutex[i]);
|
|
|
i++;
|
|
|
compteur++;
|
|
|
}
|
|
|
return nbGame;
|
|
|
}
|
|
|
|
|
|
-int* map_size(char* map){
|
|
|
+int* map_size(char* map) {
|
|
|
int* res;
|
|
|
- res = malloc(sizeof(int) * 2);
|
|
|
+ res = malloc(sizeof (int) * 2);
|
|
|
res[WIDTH] = 0;
|
|
|
res[HEIGHT] = 1;
|
|
|
//Parcours la 1er ligne pour compter le nombre de caractère
|
|
|
- while(*map != '\n' && *map != '\0'){
|
|
|
+ while (*map != '\n' && *map != '\0') {
|
|
|
res[WIDTH]++;
|
|
|
map++;
|
|
|
}
|
|
|
- if(*map == '\0'){
|
|
|
+ if (*map == '\0') {
|
|
|
return res;
|
|
|
}
|
|
|
//Compte les lignes
|
|
|
map++;
|
|
|
- while(*map != '\0'){
|
|
|
- if(*map == '\n'){
|
|
|
+ while (*map != '\0') {
|
|
|
+ if (*map == '\n') {
|
|
|
res[HEIGHT]++;
|
|
|
}
|
|
|
map++;
|
|
@@ -116,19 +139,21 @@ int* map_size(char* map){
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-int create_game(char* name, char* map){
|
|
|
+int create_game(char* name, char* map) {
|
|
|
int length, index = 0;
|
|
|
char* path;
|
|
|
int* size;
|
|
|
//Regarde si il reste une game de disponnible
|
|
|
- if(nbGame == MAXGAME){
|
|
|
+ if (nbGame == MAXGAME) {
|
|
|
return ERR;
|
|
|
}
|
|
|
//Cherche une game libre
|
|
|
- while(index < MAXGAME){
|
|
|
- if(game[index].active == false){
|
|
|
+ while (index < MAXGAME) {
|
|
|
+ pthread_mutex_lock(&gameMutex[index]);
|
|
|
+ if (game[index].active == false) {
|
|
|
break;
|
|
|
}
|
|
|
+ pthread_mutex_unlock(&gameMutex[index]);
|
|
|
index++;
|
|
|
}
|
|
|
//Recup la map
|
|
@@ -146,10 +171,11 @@ int create_game(char* name, char* map){
|
|
|
game[index].width = size[WIDTH];
|
|
|
game[index].height = size[HEIGHT];
|
|
|
game[index].map = parse_map(game[index].mapContent, size[WIDTH], size[HEIGHT]);
|
|
|
- for(int i = 0; i < MAXPLAYER; i++){
|
|
|
- game[index].player[i] = malloc(sizeof(Player));
|
|
|
+ for (int i = 0; i < MAXPLAYER; i++) {
|
|
|
+ game[index].player[i] = malloc(sizeof (Player));
|
|
|
game[index].player[i]->ini = false;
|
|
|
}
|
|
|
+ pthread_mutex_unlock(&gameMutex[index]);
|
|
|
//Retourne la position de la partie dans le tableau
|
|
|
nbGame++;
|
|
|
free(path);
|
|
@@ -157,32 +183,40 @@ int create_game(char* name, char* map){
|
|
|
return index;
|
|
|
}
|
|
|
|
|
|
-int add_player(Game* g, int cliId){
|
|
|
+int add_player(Game* g, int cliId) {
|
|
|
int index = 0;
|
|
|
Client* cli;
|
|
|
//Verif que la game n'est pas deja pleine
|
|
|
- if(g->nbPlayer >= MAXPLAYER){
|
|
|
+ pthread_mutex_lock(&gameMutex[g->index]);
|
|
|
+ if (g->nbPlayer >= MAXPLAYER) {
|
|
|
+ pthread_mutex_unlock(&gameMutex[g->index]);
|
|
|
return ERR;
|
|
|
}
|
|
|
//Cherche un joueur non initialisé
|
|
|
- while(index < MAXPLAYER){
|
|
|
- if(!g->player[index]->ini){
|
|
|
+ while (index < MAXPLAYER) {
|
|
|
+ pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
|
|
|
+ if (!g->player[index]->ini) {
|
|
|
break;
|
|
|
}
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
|
|
|
index++;
|
|
|
}
|
|
|
//Recup du client
|
|
|
cli = get_client(cliId);
|
|
|
- if(cli == NULL){
|
|
|
+ if (cli == NULL) {
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
|
|
|
+ pthread_mutex_unlock(&gameMutex[g->index]);
|
|
|
return ERR;
|
|
|
}
|
|
|
//Creation du joueur
|
|
|
create_player(g->player[index], cli);
|
|
|
g->nbPlayer++;
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
|
|
|
+ pthread_mutex_unlock(&gameMutex[g->index]);
|
|
|
return index;
|
|
|
}
|
|
|
|
|
|
-void describe_game(Game* g, int playerIndex, JsonEncoder* desc){
|
|
|
+void describe_game(Game* g, int playerIndex, JsonEncoder* desc) {
|
|
|
JsonEncoder player;
|
|
|
JsonEncoder map;
|
|
|
JsonArray players;
|
|
@@ -192,6 +226,7 @@ void describe_game(Game* g, int playerIndex, JsonEncoder* desc){
|
|
|
ini_encoder(&map);
|
|
|
ini_array_encoder(&players);
|
|
|
//Info map
|
|
|
+ pthread_mutex_lock(&gameMutex[g->index]);
|
|
|
content = remove_char(g->mapContent, '\n'); //La map sans \n car interdit en JSON
|
|
|
add_integer(&map, "width", g->width);
|
|
|
add_integer(&map, "height", g->height);
|
|
@@ -202,82 +237,105 @@ void describe_game(Game* g, int playerIndex, JsonEncoder* desc){
|
|
|
add_object(desc, "map", &map);
|
|
|
//Ajout info courte joueur
|
|
|
//printf("Add players\n");
|
|
|
- for(int i = 0; i < MAXPLAYER; i++){
|
|
|
- if(g->player[i]->ini){
|
|
|
+ for (int i = 0; i < MAXPLAYER; i++) {
|
|
|
+ pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
+ if (g->player[i]->ini) {
|
|
|
describe_short_player(g->player[i], &player);
|
|
|
add_array_object(&players, &player);
|
|
|
- clean_json_encoder(&player);
|
|
|
+ clean_json_encoder(&player);
|
|
|
}
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
}
|
|
|
//printf("Fin Add players\n");
|
|
|
add_array(desc, "players", &players);
|
|
|
//Si besoins ajout un joueur
|
|
|
- if(playerIndex >= 0 && playerIndex < MAXPLAYER && g->player[playerIndex]->ini){
|
|
|
- describe_player(g->player[playerIndex], &player);
|
|
|
- add_object(desc, "player", &player);
|
|
|
- clean_json_encoder(&player);
|
|
|
+ if (playerIndex >= 0 && playerIndex < MAXPLAYER) {
|
|
|
+ pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
|
|
|
+ if (g->player[playerIndex]->ini) {
|
|
|
+ describe_player(g->player[playerIndex], &player);
|
|
|
+ add_object(desc, "player", &player);
|
|
|
+ clean_json_encoder(&player);
|
|
|
+ }
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
|
|
|
}
|
|
|
//Nettoyage
|
|
|
+ pthread_mutex_unlock(&gameMutex[g->index]);
|
|
|
clean_json_encoder(&map);
|
|
|
clean_json_array(&players);
|
|
|
}
|
|
|
|
|
|
-boolean notify_player(Game* g, char* method, char* ressource, JsonEncoder* param, int excludePlayerId){
|
|
|
+boolean notify_player(Game* g, char* method, char* ressource, JsonEncoder* param, int excludePlayerId) {
|
|
|
boolean res = true;
|
|
|
+ pthread_mutex_lock(&gameMutex[g->index]);
|
|
|
//Regarde si la game est active
|
|
|
- if(!g->active){
|
|
|
+ if (!g->active) {
|
|
|
+ pthread_mutex_unlock(&gameMutex[g->index]);
|
|
|
return false;
|
|
|
}
|
|
|
//Parcours les joeurs de la game
|
|
|
- for(int i = 0; i < MAXPLAYER; i++){
|
|
|
+ for (int i = 0; i < MAXPLAYER; i++) {
|
|
|
//Si joueur actif
|
|
|
- if(g->player[i]->ini && g->player[i]->id != excludePlayerId){
|
|
|
+ pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
+ if (g->player[i]->ini && g->player[i]->id != excludePlayerId) {
|
|
|
res = res && notify_client(g->player[i]->cli, method, ressource, param);
|
|
|
}
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
}
|
|
|
+ pthread_mutex_unlock(&gameMutex[g->index]);
|
|
|
return res;
|
|
|
}
|
|
|
|
|
|
-boolean player_collision(Game* g, int x, int y){
|
|
|
- for(int i = 0; i < MAXPLAYER; i++){
|
|
|
- if(g->player[i]->ini){
|
|
|
- if(g->player[i]->x == x && g->player[i]->y == y){
|
|
|
+boolean player_collision(Game* g, int x, int y) {
|
|
|
+ for (int i = 0; i < MAXPLAYER; i++) {
|
|
|
+ pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
+ if (g->player[i]->ini) {
|
|
|
+ if (g->player[i]->x == x && g->player[i]->y == y) {
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
}
|
|
|
- return false;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
-void remove_player(Game* g, int playerIndex){
|
|
|
+void remove_player(Game* g, int playerIndex) {
|
|
|
+ pthread_mutex_lock(&gameMutex[g->index]);
|
|
|
+ pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
|
|
|
g->nbPlayer--;
|
|
|
delete_player(g->player[playerIndex]);
|
|
|
+ pthread_mutex_unlock(&gameMutex[g->index]);
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
|
|
|
}
|
|
|
|
|
|
-void stop_game(Game* g){
|
|
|
+void stop_game(Game* g) {
|
|
|
+ pthread_mutex_lock(&gameMutex[g->index]);
|
|
|
//Indique comme inactive
|
|
|
g->active = false;
|
|
|
//Suppr les joueurs
|
|
|
- for(int i = 0; i < MAXPLAYER; i++){
|
|
|
- if(g->player[i]->ini){
|
|
|
+ for (int i = 0; i < MAXPLAYER; i++) {
|
|
|
+ pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
+ if (g->player[i]->ini) {
|
|
|
delete_player(g->player[i]);
|
|
|
}
|
|
|
free(g->player[i]);
|
|
|
+ pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + i]);
|
|
|
}
|
|
|
//Libere la memoire
|
|
|
- for(int i = 0; i < g->width; i++){
|
|
|
+ for (int i = 0; i < g->width; i++) {
|
|
|
free(g->map[i]);
|
|
|
}
|
|
|
free(g->map);
|
|
|
free(g->mapName);
|
|
|
free(g->mapContent);
|
|
|
+ pthread_mutex_unlock(&gameMutex[g->index]);
|
|
|
//Retire une game
|
|
|
nbGame--;
|
|
|
}
|
|
|
|
|
|
-void clean_games(){
|
|
|
- for(int i = 0; i < MAXGAME; i++){
|
|
|
- if(game[i].active){
|
|
|
+void clean_games() {
|
|
|
+ for (int i = 0; i < MAXGAME; i++) {
|
|
|
+ if (game[i].active) {
|
|
|
stop_game(&game[i]);
|
|
|
}
|
|
|
}
|