handler.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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 "handler.h"
  15. /* --- Extern --- */
  16. extern Game game[MAXGAME];
  17. extern int nbGame;
  18. /* --- Fonctions privées --- */
  19. /**
  20. * Cherche dans quel partie est un client
  21. * @param int L'id du client
  22. * @return int L'index de la partie
  23. */
  24. int search_client_game(int cliId) {
  25. int index = ERR;
  26. for (int i = 0; i < MAXGAME; i++) {
  27. //Regarde si la game est active et avec des joueurs
  28. if (game[i].active && game[i].nbPlayer > 0) {
  29. //Parcours les joueurs
  30. for (int j = 0; j < MAXPLAYER; j++) {
  31. //Si le joueur est actif
  32. if (game[i].player[j]->ini) {
  33. //Si l'id est le bon
  34. if (game[i].player[j]->id == cliId) {
  35. index = i;
  36. break;
  37. }
  38. }
  39. }
  40. }
  41. //Si on a un resultat
  42. if (index != ERR) {
  43. break;
  44. }
  45. }
  46. //Retour
  47. return index;
  48. }
  49. /**
  50. * Cherche une partie par son nom
  51. * @param char* Le nom de la partie
  52. * @return int L'index dans le tableau
  53. */
  54. int search_game(char* name) {
  55. int index = ERR;
  56. for (int i = 0; i < MAXGAME; i++) {
  57. //Regarde si la game est active et le nom
  58. if (game[i].active && strncmp(game[i].name, name, strlen(game[i].name)) == 0) {
  59. index = i;
  60. break;
  61. }
  62. }
  63. return index;
  64. }
  65. /* --- Fonctions publiques --- */
  66. void ini_handler() {
  67. //Get
  68. add_handler("GET", "client/end", handler_client_end);
  69. add_handler("GET", "game/list", handler_game_list);
  70. //Post
  71. add_handler("POST", "game/create", handler_game_create);
  72. add_handler("POST", "game/join", handler_game_join);
  73. add_handler("POST", "player/move", handler_player_move);
  74. }
  75. int handler_client_end(int cliId, JsonParser* json) {
  76. boolean find = false;
  77. JsonEncoder* notif;
  78. printf("Deconnexion du client %d\n", cliId);
  79. //Cherche le client dans les parties
  80. for (int i = 0; i < MAXGAME; i++) {
  81. if (game[i].active) {
  82. for (int j = 0; j < MAXPLAYER; j++) {
  83. if (game[i].player[j]->ini && game[i].player[j]->id == cliId) {
  84. find = true;
  85. remove_player(&game[i], j);
  86. //Avertit les autres joueurs
  87. notif = malloc(sizeof (JsonEncoder));
  88. ini_encoder(notif);
  89. add_integer(notif, "player", cliId);
  90. notify_player(&game[i], "POST", "game/quit", notif, cliId);
  91. clean_json_encoder(notif);
  92. free(notif);
  93. break;
  94. }
  95. }
  96. if (find) {
  97. break;
  98. }
  99. }
  100. }
  101. remove_client(cliId);
  102. return SUCCESS;
  103. }
  104. int handler_game_list(int cliId, JsonParser* json) {
  105. JsonEncoder reponse;
  106. JsonArray game;
  107. JsonArray map;
  108. int nb;
  109. //Recup la liste des parties et des cartes
  110. ini_array_encoder(&game);
  111. ini_array_encoder(&map);
  112. nb = list_game(&game);
  113. list_map(&map);
  114. //Creation reponse
  115. ini_encoder(&reponse);
  116. add_string(&reponse, "action", "game/list");
  117. add_string(&reponse, "status", "200");
  118. add_string(&reponse, "message", "ok");
  119. if (nb == 0) {
  120. add_integer(&reponse, "numberGameList", 0);
  121. } else {
  122. add_integer(&reponse, "numberGameList", nb);
  123. add_array(&reponse, "games", &game);
  124. }
  125. add_array(&reponse, "maps", &map);
  126. //Envoi reponse au client
  127. if (!send_client(cliId, &reponse)) {
  128. adderror("Impossible de répondre au client");
  129. return FAIL;
  130. }
  131. //Nettoyage
  132. clean_json_encoder(&reponse);
  133. clean_json_array(&map);
  134. clean_json_array(&game);
  135. return SUCCESS;
  136. }
  137. int handler_game_create(int cliId, JsonParser* json) {
  138. char* map, * name, * msg;
  139. int index, joueur;
  140. JsonEncoder reponse;
  141. //Verification arguments
  142. if (get_pos(json, "name") == JSON_ERROR) {
  143. send_err_client(cliId, EREQUEST);
  144. adderror("Le json du client est incorrect");
  145. return FAIL;
  146. }
  147. if (get_pos(json, "map") == JSON_ERROR) {
  148. send_err_client(cliId, EREQUEST);
  149. adderror("Le json du client est incorrect");
  150. return FAIL;
  151. }
  152. //Recup valeur
  153. map = get_string(json, "map");
  154. name = get_string(json, "name");
  155. //Initialisation reponse JSON
  156. ini_encoder(&reponse);
  157. add_string(&reponse, "action", "game/create");
  158. //Verif nom non existant
  159. if (search_game(name) != ERR) {
  160. add_string(&reponse, "status", "501");
  161. add_string(&reponse, "message", "Cannot create game");
  162. if (!send_client(cliId, &reponse)) {
  163. adderror("Impossible de répondre au client");
  164. }
  165. clean_json_encoder(&reponse);
  166. return FAIL;
  167. }
  168. //Creation
  169. index = create_game(name, map);
  170. if (index == ERR) {
  171. add_string(&reponse, "status", "501");
  172. add_string(&reponse, "message", "Cannot create game");
  173. if (!send_client(cliId, &reponse)) {
  174. adderror("Impossible de répondre au client");
  175. }
  176. clean_json_encoder(&reponse);
  177. return FAIL;
  178. }
  179. //Ajout du joueur dans la partie
  180. joueur = add_player(&game[index], cliId);
  181. if (joueur == ERR) {
  182. stop_game(&game[index]);
  183. add_string(&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. //Recup info
  192. describe_game(&game[index], joueur, &reponse);
  193. //Ajout infos
  194. msg = new_string(25 + strlen(map));
  195. sprintf(msg, "Game created with %s", map);
  196. add_string(&reponse, "status", "201");
  197. add_string(&reponse, "message", msg);
  198. add_string(&reponse, "startPos", "0,0");
  199. free(msg);
  200. //Envoi
  201. if (!send_client(cliId, &reponse)) {
  202. adderror("Impossible de répondre au client");
  203. clean_json_encoder(&reponse);
  204. return FAIL;
  205. }
  206. //Nettoyage
  207. clean_json_encoder(&reponse);
  208. free(map);
  209. free(name);
  210. return SUCCESS;
  211. }
  212. int handler_game_join(int cliId, JsonParser* json) {
  213. char* name;
  214. int index, joueur;
  215. JsonEncoder reponse;
  216. //Verification arguments
  217. if (get_pos(json, "name") == JSON_ERROR) {
  218. send_err_client(cliId, EREQUEST);
  219. adderror("Le json du client est incorrect");
  220. return FAIL;
  221. }
  222. //Recup valeur
  223. name = get_string(json, "name");
  224. //Initialisation json reponse
  225. ini_encoder(&reponse);
  226. add_string(&reponse, "action", "game/join");
  227. //Verif game existe
  228. index = search_game(name);
  229. if (index == ERR) {
  230. add_string(&reponse, "status", "501");
  231. add_string(&reponse, "message", "Cannot join the game");
  232. if (!send_client(cliId, &reponse)) {
  233. adderror("Impossible de répondre au client");
  234. }
  235. clean_json_encoder(&reponse);
  236. return FAIL;
  237. }
  238. //Ajout du joueur dans la partie
  239. joueur = add_player(&game[index], cliId);
  240. if (joueur == ERR) {
  241. add_string(&reponse, "status", "501");
  242. add_string(&reponse, "message", "Cannot join the game");
  243. if (!send_client(cliId, &reponse)) {
  244. adderror("Impossible de répondre au client");
  245. }
  246. clean_json_encoder(&reponse);
  247. return FAIL;
  248. }
  249. //Recup info
  250. describe_game(&game[index], joueur, &reponse);
  251. //Ajout infos
  252. add_string(&reponse, "status", "201");
  253. add_string(&reponse, "startPos", "0,0");
  254. //Envoi
  255. if (!send_client(cliId, &reponse)) {
  256. adderror("Impossible de répondre au client");
  257. clean_json_encoder(&reponse);
  258. return FAIL;
  259. }
  260. //Nettoyage
  261. clean_json_encoder(&reponse);
  262. free(name);
  263. //Avertit les autres joueurs
  264. add_integer(&reponse, "id", cliId);
  265. add_string(&reponse, "pos", "0,0");
  266. notify_player(&game[index], "POST", "game/newplayer", &reponse, cliId);
  267. //Nettoyage
  268. clean_json_encoder(&reponse);
  269. return SUCCESS;
  270. }
  271. int handler_player_move(int cliId, JsonParser* json) {
  272. printf("Player Move\n");
  273. char* move;
  274. int index, x = 0, y = 0;
  275. Player* p = NULL;
  276. boolean mine = false;
  277. JsonEncoder reponse;
  278. //Verification arguments
  279. if (get_pos(json, "move") == JSON_ERROR) {
  280. return FAIL;
  281. }
  282. //Recup valeur
  283. move = get_string(json, "move");
  284. //Verif game existe
  285. index = search_client_game(cliId);
  286. if (index == ERR) {
  287. free(move);
  288. clean_json_encoder(&reponse);
  289. return FAIL;
  290. }
  291. //Recup le joueur
  292. for(int i = 0; i < MAXPLAYER; i++){
  293. if(game[index].player[i]->ini && game[index].player[i]->id == cliId){
  294. p = game[index].player[i];
  295. break;
  296. }
  297. }
  298. if(p == NULL){
  299. free(move);
  300. return FAIL;
  301. }
  302. //Regarde si le joueur peut bouger
  303. if (strncmp(move, "up", 2) == 0) {
  304. 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*/ )){
  305. //Bouge le joueur sur la carte
  306. p->y--;
  307. //Si marche sur une mine
  308. if(game[index].map[p->x][p->y] == '2'){
  309. game[index].map[p->x][p->y] = '_';
  310. mine = true;
  311. x = p->x;
  312. y = p->y;
  313. }
  314. }
  315. } else if (strncmp(move, "down", 4) == 0) {
  316. 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*/ )){
  317. //Bouge le joueur sur la carte
  318. p->y++;
  319. //Si marche sur une mine
  320. if(game[index].map[p->x][p->y] == '2'){
  321. game[index].map[p->x][p->y] = '_';
  322. mine = true;
  323. x = p->x;
  324. y = p->y;
  325. }
  326. }
  327. } else if (strncmp(move, "left", 4) == 4) {
  328. 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*/ )){
  329. //Bouge le joueur sur la carte
  330. p->x--;
  331. //Si marche sur une mine
  332. if(game[index].map[p->x][p->y] == '2'){
  333. game[index].map[p->x][p->y] = '_';
  334. mine = true;
  335. x = p->x;
  336. y = p->y;
  337. }
  338. }
  339. } else if(strncmp(move, "right", 4) == 0){
  340. 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*/ )){
  341. //Bouge le joueur sur la carte
  342. p->x++;
  343. //Si marche sur une mine
  344. if(game[index].map[p->x][p->y] == '2'){
  345. game[index].map[p->x][p->y] = '_';
  346. mine = true;
  347. x = p->x;
  348. y = p->y;
  349. }
  350. }
  351. } else {
  352. free(move);
  353. send_err_client(cliId, EREQUEST);
  354. adderror("Le json du client est incorrect");
  355. return FAIL;
  356. }
  357. //Notifie les joueurs
  358. ini_encoder(&reponse);
  359. add_integer(&reponse, "player", cliId);
  360. add_string(&reponse, "move", move);
  361. notify_player(&game[index], "POST", "player/position/update", &reponse, -1);
  362. //Si marche sur une mine
  363. if(mine){
  364. printf("Mine %d %d", x, y);
  365. }
  366. //Nettoyage
  367. clean_json_encoder(&reponse);
  368. free(move);
  369. return SUCCESS;
  370. }