handler.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. }
  74. int handler_client_end(int cliId, JsonParser* json){
  75. boolean find = false;
  76. JsonEncoder* notif;
  77. printf("Deconnexion du client %d\n", cliId);
  78. //Cherche le client dans les parties
  79. for(int i = 0; i < MAXGAME; i++){
  80. if(game[i].active){
  81. for(int j = 0; j < MAXPLAYER; j++){
  82. if(game[i].player[j]->ini && game[i].player[j]->id == cliId){
  83. find = true;
  84. remove_player(&game[i], j);
  85. //Avertit les autres joueurs
  86. notif = malloc(sizeof(JsonEncoder));
  87. ini_encoder(notif);
  88. add_integer(notif, "player", cliId);
  89. notify_player(&game[i], "POST", "game/quit", notif, cliId);
  90. clean_json_encoder(notif);
  91. free(notif);
  92. break;
  93. }
  94. }
  95. if(find){
  96. break;
  97. }
  98. }
  99. }
  100. remove_client(cliId);
  101. return SUCCESS;
  102. }
  103. int handler_game_list(int cliId, JsonParser* json){
  104. JsonEncoder reponse;
  105. JsonArray* game;
  106. JsonArray* map;
  107. //Recup la liste des parties et des cartes
  108. game = list_game();
  109. map = list_map();
  110. //Creation reponse
  111. ini_encoder(&reponse);
  112. add_string(&reponse, "action", "game/list");
  113. add_string(&reponse, "status", "200");
  114. add_string(&reponse, "message", "ok");
  115. if(game == NULL){
  116. add_integer(&reponse, "numberGameList", 0);
  117. } else {
  118. add_integer(&reponse, "numberGameList", nbGame);
  119. add_array(&reponse, "games", game);
  120. clean_json_array(game);
  121. free(game);
  122. }
  123. add_array(&reponse, "maps", map);
  124. //Envoi reponse au client
  125. if(!send_client(cliId, &reponse)){
  126. adderror("Impossible de répondre au client");
  127. return FAIL;
  128. }
  129. //Nettoyage
  130. clean_json_encoder(&reponse);
  131. clean_json_array(map);
  132. free(map);
  133. return SUCCESS;
  134. }
  135. int handler_game_create(int cliId, JsonParser* json){
  136. char* map, * name, * msg;
  137. int index, joueur;
  138. JsonEncoder* reponse;
  139. //Verification arguments
  140. if(get_pos(json, "name") == JSON_ERROR){
  141. send_err_client(cliId, EREQUEST);
  142. adderror("Le json du client est incorrect");
  143. return FAIL;
  144. }
  145. if(get_pos(json, "map") == JSON_ERROR){
  146. send_err_client(cliId, EREQUEST);
  147. adderror("Le json du client est incorrect");
  148. return FAIL;
  149. }
  150. //Recup valeur
  151. map = get_string(json, "map");
  152. name = get_string(json, "name");
  153. //Verif nom non existant
  154. if(search_game(name) != ERR){
  155. reponse = malloc(sizeof(JsonEncoder));
  156. ini_encoder(reponse);
  157. add_string(reponse, "action", "game/create");
  158. add_string(reponse, "status", "501");
  159. add_string(reponse, "message", "Cannot create game");
  160. if(!send_client(cliId, reponse)){
  161. adderror("Impossible de répondre au client");
  162. }
  163. clean_json_encoder(reponse);
  164. free(reponse);
  165. return FAIL;
  166. }
  167. //Creation
  168. index = create_game(name, map);
  169. if(index == ERR){
  170. reponse = malloc(sizeof(JsonEncoder));
  171. ini_encoder(reponse);
  172. add_string(reponse, "action", "game/create");
  173. add_string(reponse, "status", "501");
  174. add_string(reponse, "message", "Cannot create game");
  175. if(!send_client(cliId, reponse)){
  176. adderror("Impossible de répondre au client");
  177. }
  178. clean_json_encoder(reponse);
  179. free(reponse);
  180. return FAIL;
  181. }
  182. //Ajout du joueur dans la partie
  183. joueur = add_player(&game[index], cliId);
  184. if(joueur == ERR){
  185. stop_game(&game[index]);
  186. reponse = malloc(sizeof(JsonEncoder));
  187. ini_encoder(reponse);
  188. add_string(reponse, "action", "game/create");
  189. add_string(reponse, "status", "501");
  190. add_string(reponse, "message", "Cannot create game");
  191. if(!send_client(cliId, reponse)){
  192. adderror("Impossible de répondre au client");
  193. }
  194. clean_json_encoder(reponse);
  195. free(reponse);
  196. return FAIL;
  197. }
  198. //Recup info
  199. reponse = describe_game(&game[index], joueur);
  200. //Ajout infos
  201. msg = new_string(25 + strlen(map));
  202. sprintf(msg, "Game created with %s", map);
  203. add_string(reponse, "action", "game/create");
  204. add_string(reponse, "status", "201");
  205. add_string(reponse, "message", msg);
  206. add_string(reponse, "startPos", "0,0");
  207. free(msg);
  208. //Envoi
  209. if(!send_client(cliId, reponse)){
  210. adderror("Impossible de répondre au client");
  211. clean_json_encoder(reponse);
  212. free(reponse);
  213. return FAIL;
  214. }
  215. //Nettoyage
  216. clean_json_encoder(reponse);
  217. free(reponse);
  218. free(map);
  219. free(name);
  220. return SUCCESS;
  221. }
  222. int handler_game_join(int cliId, JsonParser* json){
  223. char* name;
  224. int index, joueur;
  225. JsonEncoder* reponse;
  226. //Verification arguments
  227. if(get_pos(json, "name") == JSON_ERROR){
  228. send_err_client(cliId, EREQUEST);
  229. adderror("Le json du client est incorrect");
  230. return FAIL;
  231. }
  232. //Recup valeur
  233. name = get_string(json, "name");
  234. //Verif nom non existant
  235. index = search_game(name);
  236. if(index == ERR){
  237. reponse = malloc(sizeof(JsonEncoder));
  238. ini_encoder(reponse);
  239. add_string(reponse, "action", "game/join");
  240. add_string(reponse, "status", "501");
  241. add_string(reponse, "message", "Cannot join the game game");
  242. if(!send_client(cliId, reponse)){
  243. adderror("Impossible de répondre au client");
  244. }
  245. clean_json_encoder(reponse);
  246. free(reponse);
  247. return FAIL;
  248. }
  249. //Ajout du joueur dans la partie
  250. joueur = add_player(&game[index], cliId);
  251. if(joueur == ERR){
  252. reponse = malloc(sizeof(JsonEncoder));
  253. ini_encoder(reponse);
  254. add_string(reponse, "action", "game/join");
  255. add_string(reponse, "status", "501");
  256. add_string(reponse, "message", "Cannot join the game");
  257. if(!send_client(cliId, reponse)){
  258. adderror("Impossible de répondre au client");
  259. }
  260. clean_json_encoder(reponse);
  261. free(reponse);
  262. return FAIL;
  263. }
  264. //Recup info
  265. reponse = describe_game(&game[index], joueur);
  266. //Ajout infos
  267. add_string(reponse, "action", "game/join");
  268. add_string(reponse, "status", "201");
  269. add_string(reponse, "startPos", "0,0");
  270. //Envoi
  271. if(!send_client(cliId, reponse)){
  272. adderror("Impossible de répondre au client");
  273. clean_json_encoder(reponse);
  274. free(reponse);
  275. return FAIL;
  276. }
  277. //Nettoyage
  278. clean_json_encoder(reponse);
  279. free(reponse);
  280. free(name);
  281. //Avertit les autres joueurs
  282. reponse = malloc(sizeof(JsonEncoder));
  283. ini_encoder(reponse);
  284. add_integer(reponse, "id", cliId);
  285. add_string(reponse, "pos", "0,0");
  286. notify_player(&game[index], "POST", "game/newplayer", reponse, cliId);
  287. //Nettoyage
  288. clean_json_encoder(reponse);
  289. free(reponse);
  290. return SUCCESS;
  291. }