handler.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. /*
  2. * File: handler.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 23 novembre 2018
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include "error.h"
  11. #include "bomberstudent_server.h"
  12. #include "client.h"
  13. #include "player.h"
  14. #include "delay.h"
  15. #include "handler.h"
  16. /* --- Extern --- */
  17. extern Game game[MAXGAME];
  18. extern int nbGame;
  19. pthread_mutex_t gameMutex[MAXGAME];
  20. pthread_mutex_t playerMutex[MAXGAME * MAXPLAYER];
  21. /* --- Fonctions privées --- */
  22. /**
  23. * Cherche dans quel partie est un client
  24. * @param int L'id du client
  25. * @return int L'index de la partie
  26. */
  27. int search_client_game(int cliId) {
  28. int index = ERR;
  29. for (int i = 0; i < MAXGAME; i++) {
  30. pthread_mutex_lock(&gameMutex[i]);
  31. //Regarde si la game est active et avec des joueurs
  32. if (game[i].active && game[i].nbPlayer > 0) {
  33. //Parcours les joueurs
  34. for (int j = 0; j < MAXPLAYER; j++) {
  35. pthread_mutex_lock(&playerMutex[(i * MAXPLAYER) + j]);
  36. //Si le joueur est actif
  37. if (game[i].player[j]->ini) {
  38. //Si l'id est le bon
  39. if (game[i].player[j]->id == cliId) {
  40. index = i;
  41. pthread_mutex_unlock(&playerMutex[(i * MAXPLAYER) + j]);
  42. break;
  43. }
  44. }
  45. pthread_mutex_unlock(&playerMutex[(i * MAXPLAYER) + j]);
  46. }
  47. }
  48. pthread_mutex_unlock(&gameMutex[i]);
  49. //Si on a un resultat
  50. if (index != ERR) {
  51. break;
  52. }
  53. }
  54. //Retour
  55. return index;
  56. }
  57. /**
  58. * Cherche une partie par son nom
  59. * @param char* Le nom de la partie
  60. * @return int L'index dans le tableau
  61. */
  62. int search_game(char* name) {
  63. int index = ERR;
  64. for (int i = 0; i < MAXGAME; i++) {
  65. pthread_mutex_lock(&gameMutex[i]);
  66. //Regarde si la game est active et le nom
  67. if (game[i].active && strncmp(game[i].name, name, strlen(game[i].name)) == 0) {
  68. index = i;
  69. pthread_mutex_unlock(&gameMutex[i]);
  70. break;
  71. }
  72. pthread_mutex_unlock(&gameMutex[i]);
  73. }
  74. return index;
  75. }
  76. /**
  77. * Parse une postion en 2 entier X et Y
  78. * @param char* La position
  79. * @param int* Le resultat en X
  80. * @param int Le resultat en Y
  81. * @return Reussite
  82. */
  83. boolean parse_pos(char* pos, int* x, int* y) {
  84. int index = 0;
  85. char* cy, * cx;
  86. //Cherche la separation
  87. while (pos[index] != '\0' && pos[index] != ',') {
  88. index++;
  89. }
  90. if (pos[index] == '\0') {
  91. return false;
  92. }
  93. //Separation chaine
  94. cx = malloc(sizeof (char) * index + 1);
  95. memset(cx, 0, index + 1);
  96. strncpy(cx, pos, index);
  97. cy = pos + index + 1;
  98. //Parse
  99. *x = atoi(cx);
  100. *y = atoi(cy);
  101. //Nettoyage
  102. free(cx);
  103. return true;
  104. }
  105. /* --- Fonctions publiques --- */
  106. void ini_handler() {
  107. //Get
  108. add_handler("GET", "game/list", handler_game_list);
  109. //Post
  110. add_handler("POST", "client/end", handler_client_end);
  111. add_handler("POST", "game/create", handler_game_create);
  112. add_handler("POST", "game/join", handler_game_join);
  113. add_handler("POST", "game/quit", handler_game_quit);
  114. add_handler("POST", "player/move", handler_player_move);
  115. add_handler("POST", "object/new", handler_object_new);
  116. add_handler("POST", "attack/bomb", handler_attack_bomb);
  117. }
  118. int handler_client_end(int cliId, JsonParser* json) {
  119. //Verif que le client est toujours actif
  120. if (get_client(cliId) != NULL) {
  121. printf("Deconnexion du client %d\n", cliId);
  122. handler_game_quit(cliId, json);
  123. remove_client(cliId);
  124. }
  125. return SUCCESS;
  126. }
  127. int handler_game_list(int cliId, JsonParser* json) {
  128. JsonEncoder reponse;
  129. JsonArray game;
  130. JsonArray map;
  131. int nb;
  132. //Recup la liste des parties et des cartes
  133. ini_array_encoder(&game);
  134. ini_array_encoder(&map);
  135. nb = list_game(&game);
  136. list_map(&map);
  137. //Creation reponse
  138. ini_encoder(&reponse);
  139. add_string(&reponse, "action", "game/list");
  140. add_integer(&reponse, "status", 200);
  141. add_string(&reponse, "message", "ok");
  142. if (nb == 0) {
  143. add_integer(&reponse, "numberGameList", 0);
  144. } else {
  145. add_integer(&reponse, "numberGameList", nb);
  146. add_array(&reponse, "games", &game);
  147. }
  148. add_array(&reponse, "maps", &map);
  149. //Envoi reponse au client
  150. if (!send_client(cliId, &reponse)) {
  151. adderror("Impossible de répondre au client");
  152. return FAIL;
  153. }
  154. //Nettoyage
  155. clean_json_encoder(&reponse);
  156. clean_json_array(&map);
  157. clean_json_array(&game);
  158. return SUCCESS;
  159. }
  160. int handler_game_create(int cliId, JsonParser* json) {
  161. char* map, * name, * msg;
  162. int index, joueur;
  163. JsonEncoder reponse;
  164. //Verification arguments
  165. if (get_pos(json, "name") == JSON_ERROR) {
  166. send_err_client(cliId, EREQUEST);
  167. adderror("Le json du client est incorrect");
  168. return FAIL;
  169. }
  170. if (get_pos(json, "map") == JSON_ERROR) {
  171. send_err_client(cliId, EREQUEST);
  172. adderror("Le json du client est incorrect");
  173. return FAIL;
  174. }
  175. //Recup valeur
  176. map = get_string(json, "map");
  177. name = get_string(json, "name");
  178. //Initialisation reponse JSON
  179. ini_encoder(&reponse);
  180. add_string(&reponse, "action", "game/create");
  181. //Verif nom non existant
  182. if (search_game(name) != ERR) {
  183. add_integer(&reponse, "status", 501);
  184. add_string(&reponse, "message", "Cannot create game");
  185. if (!send_client(cliId, &reponse)) {
  186. adderror("Impossible de répondre au client");
  187. }
  188. clean_json_encoder(&reponse);
  189. return FAIL;
  190. }
  191. //Creation
  192. index = create_game(name, map);
  193. if (index == ERR) {
  194. add_integer(&reponse, "status", 501);
  195. add_string(&reponse, "message", "Cannot create game");
  196. if (!send_client(cliId, &reponse)) {
  197. adderror("Impossible de répondre au client");
  198. }
  199. clean_json_encoder(&reponse);
  200. return FAIL;
  201. }
  202. //Ajout du joueur dans la partie
  203. joueur = add_player(&game[index], cliId);
  204. if (joueur == ERR) {
  205. stop_game(&game[index]);
  206. add_integer(&reponse, "status", 501);
  207. add_string(&reponse, "message", "Cannot create game");
  208. if (!send_client(cliId, &reponse)) {
  209. adderror("Impossible de répondre au client");
  210. }
  211. clean_json_encoder(&reponse);
  212. return FAIL;
  213. }
  214. //Recup info
  215. describe_game(&game[index], joueur, &reponse);
  216. //Ajout infos
  217. msg = new_string(25 + strlen(map));
  218. sprintf(msg, "Game created with %s", map);
  219. add_integer(&reponse, "status", 201);
  220. add_string(&reponse, "message", msg);
  221. add_string(&reponse, "startPos", "1,1");
  222. free(msg);
  223. //Envoi
  224. if (!send_client(cliId, &reponse)) {
  225. adderror("Impossible de répondre au client");
  226. clean_json_encoder(&reponse);
  227. return FAIL;
  228. }
  229. //Nettoyage
  230. clean_json_encoder(&reponse);
  231. free(map);
  232. free(name);
  233. return SUCCESS;
  234. }
  235. int handler_game_join(int cliId, JsonParser* json) {
  236. char* name;
  237. int index, joueur;
  238. JsonEncoder reponse;
  239. //Verification arguments
  240. if (get_pos(json, "name") == JSON_ERROR) {
  241. send_err_client(cliId, EREQUEST);
  242. adderror("Le json du client est incorrect");
  243. return FAIL;
  244. }
  245. //Recup valeur
  246. name = get_string(json, "name");
  247. //Initialisation json reponse
  248. ini_encoder(&reponse);
  249. add_string(&reponse, "action", "game/join");
  250. //Verif game existe
  251. index = search_game(name);
  252. if (index == ERR) {
  253. add_integer(&reponse, "status", 501);
  254. add_string(&reponse, "message", "Cannot join the game");
  255. if (!send_client(cliId, &reponse)) {
  256. adderror("Impossible de répondre au client");
  257. }
  258. clean_json_encoder(&reponse);
  259. free(name);
  260. return FAIL;
  261. }
  262. //Ajout du joueur dans la partie
  263. joueur = add_player(&game[index], cliId);
  264. if (joueur == ERR) {
  265. add_integer(&reponse, "status", 501);
  266. add_string(&reponse, "message", "Cannot join the game");
  267. if (!send_client(cliId, &reponse)) {
  268. adderror("Impossible de répondre au client");
  269. }
  270. clean_json_encoder(&reponse);
  271. free(name);
  272. return FAIL;
  273. }
  274. //Recup info
  275. describe_game(&game[index], joueur, &reponse);
  276. //Ajout infos
  277. add_integer(&reponse, "status", 201);
  278. add_string(&reponse, "startPos", "1,1");
  279. //Envoi
  280. if (!send_client(cliId, &reponse)) {
  281. adderror("Impossible de répondre au client");
  282. clean_json_encoder(&reponse);
  283. free(name);
  284. return FAIL;
  285. }
  286. //Nettoyage
  287. clean_json_encoder(&reponse);
  288. free(name);
  289. //Avertit les autres joueurs
  290. add_integer(&reponse, "id", cliId);
  291. add_string(&reponse, "pos", "1,1");
  292. notify_player(&game[index], "POST", "game/newplayer", &reponse, cliId);
  293. //Nettoyage
  294. clean_json_encoder(&reponse);
  295. return SUCCESS;
  296. }
  297. int handler_game_quit(int cliId, JsonParser* json) {
  298. boolean find = false;
  299. JsonEncoder notif;
  300. //Cherche le client dans les parties
  301. for (int i = 0; i < MAXGAME; i++) {
  302. pthread_mutex_lock(&gameMutex[i]);
  303. if (game[i].active) {
  304. for (int j = 0; j < MAXPLAYER; j++) {
  305. pthread_mutex_lock(&playerMutex[(i * MAXPLAYER) + j]);
  306. if (game[i].player[j]->ini && game[i].player[j]->id == cliId) {
  307. pthread_mutex_unlock(&playerMutex[(i * MAXPLAYER) + j]);
  308. pthread_mutex_unlock(&gameMutex[i]);
  309. find = true;
  310. remove_player(&game[i], j);
  311. //Avertit les autres joueurs
  312. ini_encoder(&notif);
  313. add_integer(&notif, "player", cliId);
  314. notify_player(&game[i], "POST", "game/quit", &notif, cliId);
  315. clean_json_encoder(&notif);
  316. break;
  317. }
  318. pthread_mutex_unlock(&playerMutex[(i * MAXPLAYER) + j]);
  319. }
  320. if (find) {
  321. break;
  322. }
  323. }
  324. pthread_mutex_unlock(&gameMutex[i]);
  325. }
  326. return SUCCESS;
  327. }
  328. int handler_player_move(int cliId, JsonParser* json) {
  329. char* move;
  330. int index, playerIndex = 0, x = 0, y = 0;
  331. Player* p = NULL;
  332. boolean ok = false, mine = false;
  333. JsonEncoder reponse;
  334. //Verification arguments
  335. if (get_pos(json, "move") == JSON_ERROR) {
  336. return FAIL;
  337. }
  338. //Recup valeur
  339. move = get_string(json, "move");
  340. //Verif game existe
  341. index = search_client_game(cliId);
  342. if (index == ERR) {
  343. free(move);
  344. adderror("La game du client n'existe pas");
  345. return FAIL;
  346. }
  347. //Recup le joueur
  348. pthread_mutex_lock(&gameMutex[index]);
  349. for (int i = 0; i < MAXPLAYER; i++) {
  350. pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + i]);
  351. if (game[index].player[i]->ini && game[index].player[i]->id == cliId) {
  352. playerIndex = i;
  353. p = game[index].player[i];
  354. break;
  355. }
  356. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
  357. }
  358. if (p == NULL) {
  359. pthread_mutex_unlock(&gameMutex[index]);
  360. free(move);
  361. adderror("Aucun joueur associé au client");
  362. return FAIL;
  363. }
  364. //Regarde si le joueur peut bouger
  365. if (strncmp(move, "up", 2) == 0) {
  366. if (p->y > 0 && !player_collision(&game[index], p->x, p->y - 1) && (game[index].map[p->x][p->y - 1] == '_' /*Vide*/ || game[index].map[p->x][p->y - 1] == '2' /*Mine*/)) {
  367. ok = true;
  368. //Bouge le joueur sur la carte
  369. p->y--;
  370. //Si marche sur une mine
  371. if (game[index].map[p->x][p->y] == '2') {
  372. game[index].map[p->x][p->y] = '_';
  373. mine = true;
  374. x = p->x;
  375. y = p->y;
  376. }
  377. }
  378. } else if (strncmp(move, "down", 4) == 0) {
  379. if (p->y < game[index].height && !player_collision(&game[index], p->x, p->y + 1) && (game[index].map[p->x][p->y + 1] == '_' /*Vide*/ || game[index].map[p->x][p->y + 1] == '2' /*Mine*/)) {
  380. ok = true;
  381. //Bouge le joueur sur la carte
  382. p->y++;
  383. //Si marche sur une mine
  384. if (game[index].map[p->x][p->y] == '2') {
  385. game[index].map[p->x][p->y] = '_';
  386. mine = true;
  387. x = p->x;
  388. y = p->y;
  389. }
  390. }
  391. } else if (strncmp(move, "left", 4) == 0) {
  392. if (p->x > 0 && !player_collision(&game[index], p->x - 1, p->y) && (game[index].map[p->x - 1][p->y] == '_' /*Vide*/ || game[index].map[p->x - 1][p->y] == '2' /*Mine*/)) {
  393. ok = true;
  394. //Bouge le joueur sur la carte
  395. p->x--;
  396. //Si marche sur une mine
  397. if (game[index].map[p->x][p->y] == '2') {
  398. game[index].map[p->x][p->y] = '_';
  399. mine = true;
  400. x = p->x;
  401. y = p->y;
  402. }
  403. }
  404. } else if (strncmp(move, "right", 4) == 0) {
  405. if (p->x < game[index].width && !player_collision(&game[index], p->x + 1, p->y) && (game[index].map[p->x + 1][p->y] == '_' /*Vide*/ || game[index].map[p->x + 1][p->y] == '2' /*Mine*/)) {
  406. ok = true;
  407. //Bouge le joueur sur la carte
  408. p->x++;
  409. //Si marche sur une mine
  410. if (game[index].map[p->x][p->y] == '2') {
  411. game[index].map[p->x][p->y] = '_';
  412. mine = true;
  413. x = p->x;
  414. y = p->y;
  415. }
  416. }
  417. } else {
  418. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  419. pthread_mutex_unlock(&gameMutex[index]);
  420. free(move);
  421. adderror("Le json du client est incorrect");
  422. return FAIL;
  423. }
  424. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  425. pthread_mutex_unlock(&gameMutex[index]);
  426. //Notifie les joueurs si mouvement ok
  427. if (ok) {
  428. ini_encoder(&reponse);
  429. add_integer(&reponse, "player", cliId);
  430. add_string(&reponse, "move", move);
  431. notify_player(&game[index], "POST", "player/position/update", &reponse, -1);
  432. //Si marche sur une mine
  433. if (mine) {
  434. printf("Mine %d %d", x, y);
  435. }
  436. }
  437. //Nettoyage
  438. clean_json_encoder(&reponse);
  439. free(move);
  440. return SUCCESS;
  441. }
  442. int handler_object_new(int cliId, JsonParser* json) {
  443. char* class;
  444. int index, type, length, playerIndex = 0;
  445. Player* p = NULL;
  446. obj_node* objn;
  447. JsonEncoder reponse;
  448. //Verification arguments
  449. if (get_pos(json, "class") == JSON_ERROR) {
  450. send_err_client(cliId, EREQUEST);
  451. adderror("Le json du client est incorrect");
  452. return FAIL;
  453. }
  454. //Recup valeur
  455. class = get_string(json, "class");
  456. //Verif valeur class
  457. length = strlen(class);
  458. if (strncmp(class, "classic", length) == 0) {
  459. type = OBJ_BCLASSIC;
  460. } else if (strncmp(class, "mine", length) == 0) {
  461. type = OBJ_BMINE;
  462. } else if (strncmp(class, "remote", length) == 0) {
  463. type = OBJ_BREMOTE;
  464. } else if (strncmp(class, "bomb_up", length) == 0) {
  465. type = OBJ_BOMBUP;
  466. } else if (strncmp(class, "bomb_down", length) == 0) {
  467. type = OBJ_BOMBDOWN;
  468. } else if (strncmp(class, "fire_power", length) == 0) {
  469. type = OBJ_FIREPOWER;
  470. } else if (strncmp(class, "scooter", length) == 0) {
  471. type = OBJ_SCOOTER;
  472. } else if (strncmp(class, "broken_legs", length) == 0) {
  473. type = OBJ_BROKENLEG;
  474. } else if (strncmp(class, "life_up", length) == 0) {
  475. type = OBJ_LIFEUP;
  476. } else if (strncmp(class, "life_max", length) == 0) {
  477. type = OBJ_LIFEMAX;
  478. } else if (strncmp(class, "major", length) == 0) {
  479. type = OBJ_MAJOR;
  480. } else {
  481. free(class);
  482. send_err_client(cliId, EREQUEST);
  483. adderror("Le json du client est incorrect");
  484. return FAIL;
  485. }
  486. //Verif game existe
  487. index = search_client_game(cliId);
  488. if (index == ERR) {
  489. free(class);
  490. send_err_client(cliId, EREQUEST);
  491. adderror("La game du client n'existe pas");
  492. return FAIL;
  493. }
  494. //Recup le joueur
  495. pthread_mutex_lock(&gameMutex[index]);
  496. for (int i = 0; i < MAXPLAYER; i++) {
  497. pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + i]);
  498. if (game[index].player[i]->ini && game[index].player[i]->id == cliId) {
  499. playerIndex = i;
  500. p = game[index].player[i];
  501. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
  502. break;
  503. }
  504. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
  505. }
  506. if (p == NULL) {
  507. pthread_mutex_unlock(&gameMutex[index]);
  508. free(class);
  509. send_err_client(cliId, EREQUEST);
  510. adderror("Aucun joueur associé au client");
  511. return FAIL;
  512. }
  513. //Initialisation json
  514. ini_encoder(&reponse);
  515. add_string(&reponse, "action", "object/new");
  516. //Regarde si un objet correspond
  517. objn = object_search(game[index].object, type, p->x, p->y);
  518. if (objn == NULL) {
  519. add_integer(&reponse, "status", 501);
  520. add_string(&reponse, "message", "No object");
  521. //Envoi
  522. if (!send_client(cliId, &reponse)) {
  523. adderror("Impossible de répondre au client");
  524. clean_json_encoder(&reponse);
  525. free(class);
  526. return FAIL;
  527. }
  528. } else {
  529. //Ajoute l'objet au joueur
  530. pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  531. add_player_object(p, type);
  532. //Creation reponse
  533. add_integer(&reponse, "status", 201);
  534. describe_player(p, &reponse);
  535. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  536. //Envoi
  537. if (!send_client(cliId, &reponse)) {
  538. adderror("Impossible de répondre au client");
  539. clean_json_encoder(&reponse);
  540. free(class);
  541. return FAIL;
  542. }
  543. //Si major lance le timer pour avertir de la fin
  544. if (type == OBJ_MAJOR) {
  545. delay(TIMEMAJOR, index, playerIndex, callback_major_end);
  546. }
  547. }
  548. //Nettoyage
  549. pthread_mutex_unlock(&gameMutex[index]);
  550. free(class);
  551. clean_json_encoder(&reponse);
  552. return SUCCESS;
  553. }
  554. int handler_attack_bomb(int cliId, JsonParser* json) {
  555. char* pos, * class;
  556. int x, y, length, index, playerIndex = 0;
  557. Player* p = NULL;
  558. boolean ok = false;
  559. JsonEncoder reponse;
  560. //Verification arguments
  561. if (get_pos(json, "class") == JSON_ERROR) {
  562. send_err_client(cliId, EREQUEST);
  563. adderror("Le json du client est incorrect");
  564. return FAIL;
  565. }
  566. if (get_pos(json, "pos") == JSON_ERROR) {
  567. send_err_client(cliId, EREQUEST);
  568. adderror("Le json du client est incorrect");
  569. return FAIL;
  570. }
  571. //Recup valeur
  572. class = get_string(json, "class");
  573. pos = get_string(json, "pos");
  574. //Parse les valeurs de pos
  575. if (!parse_pos(pos, &x, &y)) {
  576. free(class);
  577. free(pos);
  578. send_err_client(cliId, EREQUEST);
  579. adderror("Le json du client est incorrect");
  580. return FAIL;
  581. }
  582. //Verif game existe
  583. index = search_client_game(cliId);
  584. if (index == ERR) {
  585. free(class);
  586. free(pos);
  587. send_err_client(cliId, EREQUEST);
  588. adderror("La game du client n'existe pas");
  589. return FAIL;
  590. }
  591. //Recup le joueur
  592. pthread_mutex_lock(&gameMutex[index]);
  593. for (int i = 0; i < MAXPLAYER; i++) {
  594. pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + i]);
  595. if (game[index].player[i]->ini && game[index].player[i]->id == cliId) {
  596. playerIndex = i;
  597. p = game[index].player[i];
  598. break;
  599. }
  600. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
  601. }
  602. if (p == NULL) {
  603. pthread_mutex_unlock(&gameMutex[index]);
  604. free(class);
  605. free(pos);
  606. send_err_client(cliId, EREQUEST);
  607. adderror("Aucun joueur associé au client");
  608. return FAIL;
  609. }
  610. //Verif si la bombe peut être posé et pose
  611. length = strlen(class);
  612. if (strncmp(class, "classic", length) == 0) {
  613. ok = p->classicBomb > 0 && p->nbBomb > p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
  614. if (ok) {
  615. p->nbBomb++;
  616. p->classicBomb--;
  617. game[index].map[x][y] = '1';
  618. }
  619. } else if (strncmp(class, "mine", length) == 0) {
  620. ok = p->mine > 0 && p->nbBomb > p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
  621. if (ok) {
  622. p->nbBomb++;
  623. p->mine--;
  624. game[index].map[x][y] = '2';
  625. }
  626. } else if (strncmp(class, "remote", length) == 0) {
  627. ok = p->remoteBomb > 0 && p->nbBomb > p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
  628. if (ok) {
  629. p->nbBomb++;
  630. p->remoteBomb--;
  631. game[index].map[x][y] = '3';
  632. }
  633. } else {
  634. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  635. pthread_mutex_unlock(&gameMutex[index]);
  636. free(pos);
  637. free(class);
  638. send_err_client(cliId, EREQUEST);
  639. adderror("Le json du client est incorrect");
  640. return FAIL;
  641. }
  642. //Initialisation json
  643. ini_encoder(&reponse);
  644. add_string(&reponse, "action", "attack/bomb");
  645. //Reponse
  646. if (ok) {
  647. add_integer(&reponse, "status", 201);
  648. describe_player(p, &reponse);
  649. //Envoi
  650. if (!send_client(cliId, &reponse)) {
  651. adderror("Impossible de répondre au client");
  652. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  653. pthread_mutex_unlock(&gameMutex[index]);
  654. clean_json_encoder(&reponse);
  655. free(pos);
  656. free(class);
  657. return FAIL;
  658. }
  659. //Notification des autre joeurs
  660. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  661. pthread_mutex_unlock(&gameMutex[index]);
  662. clean_json_encoder(&reponse);
  663. add_string(&reponse, "pos", pos);
  664. add_string(&reponse, "class", class);
  665. notify_player(&game[index], "POST", "attack/newbomb", &reponse, cliId);
  666. } else {
  667. add_integer(&reponse, "status", 403);
  668. add_string(&reponse, "message", "Forbidden action");
  669. //Envoi
  670. if (!send_client(cliId, &reponse)) {
  671. adderror("Impossible de répondre au client");
  672. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  673. pthread_mutex_unlock(&gameMutex[index]);
  674. clean_json_encoder(&reponse);
  675. free(pos);
  676. free(class);
  677. return FAIL;
  678. }
  679. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  680. pthread_mutex_unlock(&gameMutex[index]);
  681. }
  682. //Nettoyage
  683. clean_json_encoder(&reponse);
  684. free(pos);
  685. free(class);
  686. return SUCCESS;
  687. }