handler.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  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. mine = true;
  373. x = p->x;
  374. y = p->y;
  375. }
  376. }
  377. } else if (strncmp(move, "down", 4) == 0) {
  378. 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*/)) {
  379. ok = true;
  380. //Bouge le joueur sur la carte
  381. p->y++;
  382. //Si marche sur une mine
  383. if (game[index].map[p->x][p->y] == '2') {
  384. mine = true;
  385. x = p->x;
  386. y = p->y;
  387. }
  388. }
  389. } else if (strncmp(move, "left", 4) == 0) {
  390. 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*/)) {
  391. ok = true;
  392. //Bouge le joueur sur la carte
  393. p->x--;
  394. //Si marche sur une mine
  395. if (game[index].map[p->x][p->y] == '2') {
  396. mine = true;
  397. x = p->x;
  398. y = p->y;
  399. }
  400. }
  401. } else if (strncmp(move, "right", 4) == 0) {
  402. 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*/)) {
  403. ok = true;
  404. //Bouge le joueur sur la carte
  405. p->x++;
  406. //Si marche sur une mine
  407. if (game[index].map[p->x][p->y] == '2') {
  408. mine = true;
  409. x = p->x;
  410. y = p->y;
  411. }
  412. }
  413. } else {
  414. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  415. pthread_mutex_unlock(&gameMutex[index]);
  416. free(move);
  417. adderror("Le json du client est incorrect");
  418. return FAIL;
  419. }
  420. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  421. pthread_mutex_unlock(&gameMutex[index]);
  422. //Notifie les joueurs si mouvement ok
  423. if (ok) {
  424. ini_encoder(&reponse);
  425. add_integer(&reponse, "player", cliId);
  426. add_string(&reponse, "move", move);
  427. notify_player(&game[index], "POST", "player/position/update", &reponse, -1);
  428. //Si marche sur une mine
  429. if (mine) {
  430. JsonEncoder notif;
  431. ini_encoder(&notif);
  432. if(bomb_explode(&game[index], -1, x, y, &notif)){
  433. //Notification joueurs
  434. if(!notify_player(&game[index], "POST", "attack/explose", &notif, -1)){
  435. clean_json_encoder(&notif);
  436. }
  437. }
  438. clean_json_encoder(&notif);
  439. }
  440. }
  441. //Nettoyage
  442. clean_json_encoder(&reponse);
  443. free(move);
  444. return SUCCESS;
  445. }
  446. int handler_object_new(int cliId, JsonParser* json) {
  447. char* class;
  448. int index, type, length, playerIndex = 0;
  449. Player* p = NULL;
  450. obj_node* objn;
  451. JsonEncoder reponse;
  452. //Verification arguments
  453. if (get_pos(json, "class") == JSON_ERROR) {
  454. send_err_client(cliId, EREQUEST);
  455. adderror("Le json du client est incorrect");
  456. return FAIL;
  457. }
  458. //Recup valeur
  459. class = get_string(json, "class");
  460. //Verif valeur class
  461. length = strlen(class);
  462. if (strncmp(class, "classic", length) == 0) {
  463. type = OBJ_BCLASSIC;
  464. } else if (strncmp(class, "mine", length) == 0) {
  465. type = OBJ_BMINE;
  466. } else if (strncmp(class, "remote", length) == 0) {
  467. type = OBJ_BREMOTE;
  468. } else if (strncmp(class, "bomb_up", length) == 0) {
  469. type = OBJ_BOMBUP;
  470. } else if (strncmp(class, "bomb_down", length) == 0) {
  471. type = OBJ_BOMBDOWN;
  472. } else if (strncmp(class, "fire_power", length) == 0) {
  473. type = OBJ_FIREPOWER;
  474. } else if (strncmp(class, "scooter", length) == 0) {
  475. type = OBJ_SCOOTER;
  476. } else if (strncmp(class, "broken_legs", length) == 0) {
  477. type = OBJ_BROKENLEG;
  478. } else if (strncmp(class, "life_up", length) == 0) {
  479. type = OBJ_LIFEUP;
  480. } else if (strncmp(class, "life_max", length) == 0) {
  481. type = OBJ_LIFEMAX;
  482. } else if (strncmp(class, "major", length) == 0) {
  483. type = OBJ_MAJOR;
  484. } else {
  485. free(class);
  486. send_err_client(cliId, EREQUEST);
  487. adderror("Le json du client est incorrect");
  488. return FAIL;
  489. }
  490. //Verif game existe
  491. index = search_client_game(cliId);
  492. if (index == ERR) {
  493. free(class);
  494. send_err_client(cliId, EREQUEST);
  495. adderror("La game du client n'existe pas");
  496. return FAIL;
  497. }
  498. //Recup le joueur
  499. pthread_mutex_lock(&gameMutex[index]);
  500. for (int i = 0; i < MAXPLAYER; i++) {
  501. pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + i]);
  502. if (game[index].player[i]->ini && game[index].player[i]->id == cliId) {
  503. playerIndex = i;
  504. p = game[index].player[i];
  505. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
  506. break;
  507. }
  508. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
  509. }
  510. if (p == NULL) {
  511. pthread_mutex_unlock(&gameMutex[index]);
  512. free(class);
  513. send_err_client(cliId, EREQUEST);
  514. adderror("Aucun joueur associé au client");
  515. return FAIL;
  516. }
  517. //Initialisation json
  518. ini_encoder(&reponse);
  519. add_string(&reponse, "action", "object/new");
  520. //Regarde si un objet correspond
  521. objn = object_search(game[index].object, type, p->x, p->y);
  522. if (objn == NULL) {
  523. add_integer(&reponse, "status", 501);
  524. add_string(&reponse, "message", "No object");
  525. //Envoi
  526. if (!send_client(cliId, &reponse)) {
  527. adderror("Impossible de répondre au client");
  528. clean_json_encoder(&reponse);
  529. free(class);
  530. return FAIL;
  531. }
  532. } else {
  533. //Ajoute l'objet au joueur
  534. pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  535. add_player_object(p, type);
  536. //Creation reponse
  537. add_integer(&reponse, "status", 201);
  538. describe_player(p, &reponse);
  539. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  540. //Envoi
  541. if (!send_client(cliId, &reponse)) {
  542. adderror("Impossible de répondre au client");
  543. clean_json_encoder(&reponse);
  544. free(class);
  545. return FAIL;
  546. }
  547. //Si major lance le timer pour avertir de la fin
  548. if (type == OBJ_MAJOR) {
  549. delay(TIMEMAJOR, index, playerIndex, callback_major_end);
  550. }
  551. }
  552. //Nettoyage
  553. pthread_mutex_unlock(&gameMutex[index]);
  554. free(class);
  555. clean_json_encoder(&reponse);
  556. return SUCCESS;
  557. }
  558. int handler_attack_bomb(int cliId, JsonParser* json) {
  559. char* pos, * class;
  560. int x, y, length, index, playerIndex = 0;
  561. Player* p = NULL;
  562. boolean ok = false;
  563. JsonEncoder reponse;
  564. //Verification arguments
  565. if (get_pos(json, "class") == JSON_ERROR) {
  566. send_err_client(cliId, EREQUEST);
  567. adderror("Le json du client est incorrect");
  568. return FAIL;
  569. }
  570. if (get_pos(json, "pos") == JSON_ERROR) {
  571. send_err_client(cliId, EREQUEST);
  572. adderror("Le json du client est incorrect");
  573. return FAIL;
  574. }
  575. //Recup valeur
  576. class = get_string(json, "class");
  577. pos = get_string(json, "pos");
  578. //Parse les valeurs de pos
  579. if (!parse_pos(pos, &x, &y)) {
  580. free(class);
  581. free(pos);
  582. send_err_client(cliId, EREQUEST);
  583. adderror("Le json du client est incorrect");
  584. return FAIL;
  585. }
  586. //Verif game existe
  587. index = search_client_game(cliId);
  588. if (index == ERR) {
  589. free(class);
  590. free(pos);
  591. send_err_client(cliId, EREQUEST);
  592. adderror("La game du client n'existe pas");
  593. return FAIL;
  594. }
  595. //Recup le joueur
  596. pthread_mutex_lock(&gameMutex[index]);
  597. for (int i = 0; i < MAXPLAYER; i++) {
  598. pthread_mutex_lock(&playerMutex[(index * MAXPLAYER) + i]);
  599. if (game[index].player[i]->ini && game[index].player[i]->id == cliId) {
  600. playerIndex = i;
  601. p = game[index].player[i];
  602. break;
  603. }
  604. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + i]);
  605. }
  606. if (p == NULL) {
  607. pthread_mutex_unlock(&gameMutex[index]);
  608. free(class);
  609. free(pos);
  610. send_err_client(cliId, EREQUEST);
  611. adderror("Aucun joueur associé au client");
  612. return FAIL;
  613. }
  614. //Verif si la bombe peut être posé et pose
  615. length = strlen(class);
  616. if (strncmp(class, "classic", length) == 0) {
  617. ok = p->classicBomb > 0 && p->nbBomb < p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
  618. if (ok) {
  619. p->nbBomb++;
  620. p->classicBomb--;
  621. game[index].map[x][y] = '1';
  622. //Lance timer
  623. printf("Ici\n");
  624. int* tab = malloc(sizeof(int) * 2);
  625. tab[0] = x;
  626. tab[1] = y;
  627. //Timer
  628. printf("Delay\n");
  629. delay_data(TIMEBOMB, index, playerIndex, (void*) tab, callback_bomb_explode);
  630. }
  631. } else if (strncmp(class, "mine", length) == 0) {
  632. ok = p->mine > 0 && p->nbBomb < p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
  633. if (ok) {
  634. p->nbBomb++;
  635. p->mine--;
  636. game[index].map[x][y] = '2';
  637. }
  638. } else if (strncmp(class, "remote", length) == 0) {
  639. ok = p->remoteBomb > 0 && p->nbBomb < p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
  640. if (ok) {
  641. p->nbBomb++;
  642. p->remoteBomb--;
  643. game[index].map[x][y] = '3';
  644. //Ajoute la bombe dans la liste du joueur
  645. }
  646. } else {
  647. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  648. pthread_mutex_unlock(&gameMutex[index]);
  649. free(pos);
  650. free(class);
  651. send_err_client(cliId, EREQUEST);
  652. adderror("Le json du client est incorrect");
  653. return FAIL;
  654. }
  655. //Initialisation json
  656. ini_encoder(&reponse);
  657. add_string(&reponse, "action", "attack/bomb");
  658. //Reponse
  659. if (ok) {
  660. add_integer(&reponse, "status", 201);
  661. describe_player(p, &reponse);
  662. //Envoi
  663. if (!send_client(cliId, &reponse)) {
  664. adderror("Impossible de répondre au client");
  665. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  666. pthread_mutex_unlock(&gameMutex[index]);
  667. clean_json_encoder(&reponse);
  668. free(pos);
  669. free(class);
  670. return FAIL;
  671. }
  672. //Notification des autre joeurs
  673. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  674. pthread_mutex_unlock(&gameMutex[index]);
  675. clean_json_encoder(&reponse);
  676. add_string(&reponse, "pos", pos);
  677. add_string(&reponse, "class", class);
  678. notify_player(&game[index], "POST", "attack/newbomb", &reponse, cliId);
  679. } else {
  680. add_integer(&reponse, "status", 403);
  681. add_string(&reponse, "message", "Forbidden action");
  682. //Envoi
  683. if (!send_client(cliId, &reponse)) {
  684. adderror("Impossible de répondre au client");
  685. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  686. pthread_mutex_unlock(&gameMutex[index]);
  687. clean_json_encoder(&reponse);
  688. free(pos);
  689. free(class);
  690. return FAIL;
  691. }
  692. pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);
  693. pthread_mutex_unlock(&gameMutex[index]);
  694. }
  695. //Nettoyage
  696. clean_json_encoder(&reponse);
  697. free(pos);
  698. free(class);
  699. return SUCCESS;
  700. }