callback.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. #include <callback/callback.h>
  2. #include <callback/loader.h>
  3. #include <callback/free.h>
  4. #include <callback/alloc.h>
  5. #include <callback/game.h>
  6. #include "alloc/alloc.h"
  7. #include <flip_storage/storage.h>
  8. bool callback_message_input(InputEvent* event, void* context) {
  9. FlipWorldApp* app = (FlipWorldApp*)context;
  10. furi_check(app);
  11. if(event->key == InputKeyBack) {
  12. FURI_LOG_I(TAG, "Message view - BACK pressed");
  13. user_hit_back = true;
  14. }
  15. return true;
  16. }
  17. void callback_message_draw(Canvas* canvas, void* model) {
  18. MessageModel* message_model = model;
  19. canvas_clear(canvas);
  20. if(message_model->message_state == MessageStateAbout) {
  21. canvas_draw_str(canvas, 0, 10, VERSION_TAG);
  22. canvas_set_font_custom(canvas, FONT_SIZE_SMALL);
  23. canvas_draw_str(canvas, 0, 20, "Dev: JBlanked, codeallnight");
  24. canvas_draw_str(canvas, 0, 30, "GFX: the1anonlypr3");
  25. canvas_draw_str(canvas, 0, 40, "github.com/jblanked/FlipWorld");
  26. canvas_draw_str_multi(
  27. canvas, 0, 55, "The first open world multiplayer\ngame on the Flipper Zero.");
  28. } else if(message_model->message_state == MessageStateLoading) {
  29. canvas_set_font(canvas, FontPrimary);
  30. if(game_mode_index != 1) {
  31. canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, "Starting FlipWorld");
  32. canvas_set_font(canvas, FontSecondary);
  33. canvas_draw_str(canvas, 0, 50, "Please wait while your");
  34. canvas_draw_str(canvas, 0, 60, "game is started.");
  35. } else {
  36. canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, "Loading Lobbies");
  37. canvas_set_font(canvas, FontSecondary);
  38. canvas_draw_str(canvas, 0, 60, "Please wait....");
  39. }
  40. }
  41. // well this is only called once so let's make a while loop
  42. else if(message_model->message_state == MessageStateWaitingLobby) {
  43. canvas_draw_str(canvas, 0, 10, "Waiting for more players...");
  44. // time elapsed based on timer_iteration and timer_refresh
  45. // char str[32];
  46. // snprintf(str, sizeof(str), "Time elapsed: %d seconds", timer_iteration * timer_refresh);
  47. // canvas_draw_str(canvas, 0, 50, str);
  48. canvas_draw_str(canvas, 0, 60, "Press BACK to cancel.");
  49. canvas_commit(canvas); // make sure message is drawn
  50. } else {
  51. canvas_draw_str(canvas, 0, 10, "Unknown message state");
  52. }
  53. }
  54. void callback_submenu_choices(void* context, uint32_t index) {
  55. FlipWorldApp* app = (FlipWorldApp*)context;
  56. furi_check(app);
  57. switch(index) {
  58. case FlipWorldSubmenuIndexGameSubmenu:
  59. free_all_views(app, true, true, true);
  60. if(!alloc_game_submenu(app)) {
  61. FURI_LOG_E(TAG, "Failed to allocate game submenu");
  62. return;
  63. }
  64. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewGameSubmenu);
  65. break;
  66. case FlipWorldSubmenuIndexStory:
  67. game_mode_index = 2; // GAME_MODE_STORY
  68. game_run(app);
  69. break;
  70. case FlipWorldSubmenuIndexPvP:
  71. game_mode_index = 1; // GAME_MODE_PVP
  72. game_run(app);
  73. break;
  74. case FlipWorldSubmenuIndexPvE:
  75. game_mode_index = 0; // GAME_MODE_PVE
  76. game_run(app);
  77. break;
  78. case FlipWorldSubmenuIndexMessage:
  79. // About menu.
  80. free_all_views(app, true, true, true);
  81. if(!alloc_message_view(app, MessageStateAbout)) {
  82. FURI_LOG_E(TAG, "Failed to allocate message view");
  83. return;
  84. }
  85. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewMessage);
  86. break;
  87. case FlipWorldSubmenuIndexSettings:
  88. free_all_views(app, true, true, true);
  89. if(!alloc_submenu_other(app, FlipWorldViewSettings)) {
  90. FURI_LOG_E(TAG, "Failed to allocate settings view");
  91. return;
  92. }
  93. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewSubmenuOther);
  94. break;
  95. case FlipWorldSubmenuIndexWiFiSettings:
  96. free_all_views(app, true, false, true);
  97. if(!alloc_variable_item_list(app, FlipWorldSubmenuIndexWiFiSettings)) {
  98. FURI_LOG_E(TAG, "Failed to allocate variable item list");
  99. return;
  100. }
  101. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewVariableItemList);
  102. break;
  103. case FlipWorldSubmenuIndexGameSettings:
  104. free_all_views(app, true, false, true);
  105. if(!alloc_variable_item_list(app, FlipWorldSubmenuIndexGameSettings)) {
  106. FURI_LOG_E(TAG, "Failed to allocate variable item list");
  107. return;
  108. }
  109. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewVariableItemList);
  110. break;
  111. case FlipWorldSubmenuIndexUserSettings:
  112. free_all_views(app, true, false, true);
  113. if(!alloc_variable_item_list(app, FlipWorldSubmenuIndexUserSettings)) {
  114. FURI_LOG_E(TAG, "Failed to allocate variable item list");
  115. return;
  116. }
  117. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewVariableItemList);
  118. break;
  119. default:
  120. break;
  121. }
  122. }
  123. void callback_updated_wifi_ssid(void* context) {
  124. FlipWorldApp* app = (FlipWorldApp*)context;
  125. furi_check(app, "FlipWorldApp is NULL");
  126. // store the entered text
  127. strncpy(app->text_input_buffer, app->text_input_temp_buffer, app->text_input_buffer_size);
  128. // Ensure null-termination
  129. app->text_input_buffer[app->text_input_buffer_size - 1] = '\0';
  130. // save the setting
  131. save_char("WiFi-SSID", app->text_input_buffer);
  132. // update the variable item text
  133. if(app->variable_item_wifi_ssid) {
  134. variable_item_set_current_value_text(app->variable_item_wifi_ssid, app->text_input_buffer);
  135. // get value of password
  136. char pass[64];
  137. char username[64];
  138. char password[64];
  139. if(load_char("WiFi-Password", pass, sizeof(pass))) {
  140. if(strlen(pass) > 0 && strlen(app->text_input_buffer) > 0) {
  141. // save the settings
  142. load_char("Flip-Social-Username", username, sizeof(username));
  143. load_char("Flip-Social-Password", password, sizeof(password));
  144. save_settings(app->text_input_buffer, pass, username, password);
  145. // initialize the http
  146. FlipperHTTP* fhttp = flipper_http_alloc();
  147. if(fhttp) {
  148. // save the wifi if the device is connected
  149. if(!flipper_http_save_wifi(fhttp, app->text_input_buffer, pass)) {
  150. easy_flipper_dialog(
  151. "FlipperHTTP Error",
  152. "Ensure your WiFi Developer\nBoard or Pico W is connected\nand the latest FlipperHTTP\nfirmware is installed.");
  153. }
  154. // free the resources
  155. flipper_http_free(fhttp);
  156. } else {
  157. easy_flipper_dialog(
  158. "FlipperHTTP Error",
  159. "The UART is likely busy.\nEnsure you have the correct\nflash for your board then\nrestart your Flipper Zero.");
  160. }
  161. }
  162. }
  163. }
  164. // switch to the settings view
  165. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewVariableItemList);
  166. }
  167. void callback_updated_wifi_pass(void* context) {
  168. FlipWorldApp* app = (FlipWorldApp*)context;
  169. furi_check(app, "FlipWorldApp is NULL");
  170. // store the entered text
  171. strncpy(app->text_input_buffer, app->text_input_temp_buffer, app->text_input_buffer_size);
  172. // Ensure null-termination
  173. app->text_input_buffer[app->text_input_buffer_size - 1] = '\0';
  174. // save the setting
  175. save_char("WiFi-Password", app->text_input_buffer);
  176. // update the variable item text
  177. if(app->variable_item_wifi_pass) {
  178. // variable_item_set_current_value_text(app->variable_item_wifi_pass, app->text_input_buffer);
  179. }
  180. // get value of ssid
  181. char ssid[64];
  182. char username[64];
  183. char password[64];
  184. if(load_char("WiFi-SSID", ssid, sizeof(ssid))) {
  185. if(strlen(ssid) > 0 && strlen(app->text_input_buffer) > 0) {
  186. // save the settings
  187. load_char("Flip-Social-Username", username, sizeof(username));
  188. load_char("Flip-Social-Password", password, sizeof(password));
  189. save_settings(ssid, app->text_input_buffer, username, password);
  190. // initialize the http
  191. FlipperHTTP* fhttp = flipper_http_alloc();
  192. if(fhttp) {
  193. // save the wifi if the device is connected
  194. if(!flipper_http_save_wifi(fhttp, ssid, app->text_input_buffer)) {
  195. easy_flipper_dialog(
  196. "FlipperHTTP Error",
  197. "Ensure your WiFi Developer\nBoard or Pico W is connected\nand the latest FlipperHTTP\nfirmware is installed.");
  198. }
  199. // free the resources
  200. flipper_http_free(fhttp);
  201. } else {
  202. easy_flipper_dialog(
  203. "FlipperHTTP Error",
  204. "The UART is likely busy.\nEnsure you have the correct\nflash for your board then\nrestart your Flipper Zero.");
  205. }
  206. }
  207. }
  208. // switch to the settings view
  209. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewVariableItemList);
  210. }
  211. void callback_updated_username(void* context) {
  212. FlipWorldApp* app = (FlipWorldApp*)context;
  213. furi_check(app, "FlipWorldApp is NULL");
  214. // store the entered text
  215. strncpy(app->text_input_buffer, app->text_input_temp_buffer, app->text_input_buffer_size);
  216. // Ensure null-termination
  217. app->text_input_buffer[app->text_input_buffer_size - 1] = '\0';
  218. // save the setting
  219. save_char("Flip-Social-Username", app->text_input_buffer);
  220. // update the variable item text
  221. if(app->variable_item_user_username) {
  222. variable_item_set_current_value_text(
  223. app->variable_item_user_username, app->text_input_buffer);
  224. }
  225. view_dispatcher_switch_to_view(
  226. app->view_dispatcher, FlipWorldViewVariableItemList); // back to user settings
  227. }
  228. void callback_updated_password(void* context) {
  229. FlipWorldApp* app = (FlipWorldApp*)context;
  230. furi_check(app, "FlipWorldApp is NULL");
  231. // store the entered text
  232. strncpy(app->text_input_buffer, app->text_input_temp_buffer, app->text_input_buffer_size);
  233. // Ensure null-termination
  234. app->text_input_buffer[app->text_input_buffer_size - 1] = '\0';
  235. // save the setting
  236. save_char("Flip-Social-Password", app->text_input_buffer);
  237. // update the variable item text
  238. if(app->variable_item_user_password) {
  239. variable_item_set_current_value_text(
  240. app->variable_item_user_password, app->text_input_buffer);
  241. }
  242. // get value of username
  243. char username[64];
  244. char ssid[64];
  245. char pass[64];
  246. if(load_char("Flip-Social-Username", username, sizeof(username))) {
  247. if(strlen(username) > 0 && strlen(app->text_input_buffer) > 0) {
  248. // save the settings
  249. load_char("WiFi-SSID", ssid, sizeof(ssid));
  250. load_char("WiFi-Password", pass, sizeof(pass));
  251. save_settings(ssid, pass, username, app->text_input_buffer);
  252. }
  253. }
  254. view_dispatcher_switch_to_view(
  255. app->view_dispatcher, FlipWorldViewVariableItemList); // back to user settings
  256. }
  257. void callback_wifi_settings_select(void* context, uint32_t index) {
  258. FlipWorldApp* app = (FlipWorldApp*)context;
  259. furi_check(app, "FlipWorldApp is NULL");
  260. char ssid[64];
  261. char pass[64];
  262. char username[64];
  263. char password[64];
  264. switch(index) {
  265. case 0: // Input SSID
  266. free_all_views(app, false, false, true);
  267. if(!alloc_text_input_view(app, "SSID")) {
  268. FURI_LOG_E(TAG, "Failed to allocate text input view");
  269. return;
  270. }
  271. // load SSID
  272. if(load_settings(
  273. ssid,
  274. sizeof(ssid),
  275. pass,
  276. sizeof(pass),
  277. username,
  278. sizeof(username),
  279. password,
  280. sizeof(password))) {
  281. strncpy(app->text_input_temp_buffer, ssid, app->text_input_buffer_size - 1);
  282. app->text_input_temp_buffer[app->text_input_buffer_size - 1] = '\0';
  283. }
  284. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewTextInput);
  285. break;
  286. case 1: // Input Password
  287. free_all_views(app, false, false, true);
  288. if(!alloc_text_input_view(app, "Password")) {
  289. FURI_LOG_E(TAG, "Failed to allocate text input view");
  290. return;
  291. }
  292. // load password
  293. if(load_settings(
  294. ssid,
  295. sizeof(ssid),
  296. pass,
  297. sizeof(pass),
  298. username,
  299. sizeof(username),
  300. password,
  301. sizeof(password))) {
  302. strncpy(app->text_input_temp_buffer, pass, app->text_input_buffer_size - 1);
  303. app->text_input_temp_buffer[app->text_input_buffer_size - 1] = '\0';
  304. }
  305. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewTextInput);
  306. break;
  307. default:
  308. FURI_LOG_E(TAG, "Unknown configuration item index");
  309. break;
  310. }
  311. }
  312. void callback_fps_change(VariableItem* item) {
  313. uint8_t index = variable_item_get_current_value_index(item);
  314. fps_index = index;
  315. variable_item_set_current_value_text(item, fps_choices_str[index]);
  316. variable_item_set_current_value_index(item, index);
  317. save_char("Game-FPS", fps_choices_str[index]);
  318. }
  319. void callback_screen_on_change(VariableItem* item) {
  320. uint8_t index = variable_item_get_current_value_index(item);
  321. screen_always_on_index = index;
  322. variable_item_set_current_value_text(item, yes_or_no_choices[index]);
  323. variable_item_set_current_value_index(item, index);
  324. save_char("Game-Screen-Always-On", yes_or_no_choices[index]);
  325. }
  326. void callback_sound_on_change(VariableItem* item) {
  327. uint8_t index = variable_item_get_current_value_index(item);
  328. sound_on_index = index;
  329. variable_item_set_current_value_text(item, yes_or_no_choices[index]);
  330. variable_item_set_current_value_index(item, index);
  331. save_char("Game-Sound-On", yes_or_no_choices[index]);
  332. }
  333. void callback_vibration_on_change(VariableItem* item) {
  334. uint8_t index = variable_item_get_current_value_index(item);
  335. vibration_on_index = index;
  336. variable_item_set_current_value_text(item, yes_or_no_choices[index]);
  337. variable_item_set_current_value_index(item, index);
  338. save_char("Game-Vibration-On", yes_or_no_choices[index]);
  339. }
  340. void callback_player_on_change(VariableItem* item) {
  341. uint8_t index = variable_item_get_current_value_index(item);
  342. player_sprite_index = index;
  343. variable_item_set_current_value_text(
  344. item,
  345. is_str(player_sprite_choices[index], "naked") ? "None" : player_sprite_choices[index]);
  346. variable_item_set_current_value_index(item, index);
  347. save_char("Game-Player-Sprite", player_sprite_choices[index]);
  348. }
  349. void callback_vgm_x_change(VariableItem* item) {
  350. uint8_t index = variable_item_get_current_value_index(item);
  351. vgm_x_index = index;
  352. variable_item_set_current_value_text(item, vgm_levels[index]);
  353. variable_item_set_current_value_index(item, index);
  354. save_char("Game-VGM-X", vgm_levels[index]);
  355. }
  356. void callback_vgm_y_change(VariableItem* item) {
  357. uint8_t index = variable_item_get_current_value_index(item);
  358. vgm_y_index = index;
  359. variable_item_set_current_value_text(item, vgm_levels[index]);
  360. variable_item_set_current_value_index(item, index);
  361. save_char("Game-VGM-Y", vgm_levels[index]);
  362. }
  363. static bool _fetch_worlds(DataLoaderModel* model) {
  364. if(!model || !model->fhttp) {
  365. FURI_LOG_E(TAG, "model or fhttp is NULL");
  366. return false;
  367. }
  368. char directory_path[128];
  369. snprintf(
  370. directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world");
  371. Storage* storage = furi_record_open(RECORD_STORAGE);
  372. storage_common_mkdir(storage, directory_path);
  373. snprintf(
  374. directory_path,
  375. sizeof(directory_path),
  376. STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds");
  377. storage_common_mkdir(storage, directory_path);
  378. furi_record_close(RECORD_STORAGE);
  379. snprintf(
  380. model->fhttp->file_path,
  381. sizeof(model->fhttp->file_path),
  382. STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/world_list_full.json");
  383. model->fhttp->save_received_data = true;
  384. return flipper_http_request(
  385. model->fhttp,
  386. GET,
  387. "https://www.jblanked.com/flipper/api/world/v5/get/10/",
  388. "{\"Content-Type\":\"application/json\"}",
  389. NULL);
  390. }
  391. static char* _parse_worlds(DataLoaderModel* model) {
  392. UNUSED(model);
  393. return "World Pack Installed";
  394. }
  395. static void switch_to_view_get_worlds(FlipWorldApp* app) {
  396. if(!loader_view_alloc(app)) {
  397. FURI_LOG_E(TAG, "Failed to allocate view loader");
  398. return;
  399. }
  400. loader_switch_to_view(
  401. app,
  402. "Fetching World Pack..",
  403. _fetch_worlds,
  404. _parse_worlds,
  405. 1,
  406. callback_to_submenu,
  407. FlipWorldViewLoader);
  408. }
  409. void callback_game_settings_select(void* context, uint32_t index) {
  410. FlipWorldApp* app = (FlipWorldApp*)context;
  411. furi_check(app, "FlipWorldApp is NULL");
  412. switch(index) {
  413. case 0: // Download all world data as one huge json
  414. switch_to_view_get_worlds(app);
  415. case 1: // Player Sprite
  416. break;
  417. case 2: // Change FPS
  418. break;
  419. case 3: // VGM X
  420. break;
  421. case 4: // VGM Y
  422. break;
  423. case 5: // Screen Always On
  424. break;
  425. case 6: // Sound On
  426. break;
  427. case 7: // Vibration On
  428. break;
  429. }
  430. }
  431. void callback_user_settings_select(void* context, uint32_t index) {
  432. FlipWorldApp* app = (FlipWorldApp*)context;
  433. furi_check(app, "FlipWorldApp is NULL");
  434. switch(index) {
  435. case 0: // Username
  436. free_all_views(app, false, false, true);
  437. if(!alloc_text_input_view(app, "Username-Login")) {
  438. FURI_LOG_E(TAG, "Failed to allocate text input view");
  439. return;
  440. }
  441. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewTextInput);
  442. break;
  443. case 1: // Password
  444. free_all_views(app, false, false, true);
  445. if(!alloc_text_input_view(app, "Password-Login")) {
  446. FURI_LOG_E(TAG, "Failed to allocate text input view");
  447. return;
  448. }
  449. view_dispatcher_switch_to_view(app->view_dispatcher, FlipWorldViewTextInput);
  450. break;
  451. }
  452. }
  453. void callback_submenu_lobby_choices(void* context, uint32_t index) {
  454. /* Handle other game lobbies
  455. 1. when clicked on, send request to fetch the selected game lobby details
  456. 2. start the websocket session
  457. 3. start the game thread (the rest will be handled by game_start and player_update)
  458. */
  459. FlipWorldApp* app = (FlipWorldApp*)context;
  460. furi_check(app, "FlipWorldApp is NULL");
  461. if(index >= FlipWorldSubmenuIndexLobby && index < FlipWorldSubmenuIndexLobby + 10) {
  462. lobby_index = index - FlipWorldSubmenuIndexLobby;
  463. FlipperHTTP* fhttp = flipper_http_alloc();
  464. if(!fhttp) {
  465. FURI_LOG_E(TAG, "Failed to allocate FlipperHTTP");
  466. easy_flipper_dialog("Error", "Failed to allocate FlipperHTTP. Press BACK to return.");
  467. return;
  468. }
  469. // fetch the lobby details
  470. if(!game_fetch_lobby(fhttp, lobby_list[lobby_index])) {
  471. FURI_LOG_E(TAG, "Failed to fetch lobby details");
  472. easy_flipper_dialog("Error", "Failed to fetch lobby details. Press BACK to return.");
  473. flipper_http_free(fhttp);
  474. return;
  475. }
  476. // load the lobby details
  477. FuriString* lobby = flipper_http_load_from_file(fhttp->file_path);
  478. if(!lobby) {
  479. FURI_LOG_E(TAG, "Failed to load lobby details");
  480. flipper_http_free(fhttp);
  481. return;
  482. }
  483. // if there are no players, add the user to the lobby and make the user wait until another player joins
  484. // if there is one player and it's the user, make the user wait until another player joins
  485. // if there is one player and it's not the user, parse_lobby and start websocket
  486. // if there are 2 players (which there shouldn't be at this point), show an error message saying the lobby is full
  487. switch(game_lobby_count(fhttp, lobby)) {
  488. case -1:
  489. FURI_LOG_E(TAG, "Failed to get player count");
  490. easy_flipper_dialog("Error", "Failed to get player count. Press BACK to return.");
  491. flipper_http_free(fhttp);
  492. furi_string_free(lobby);
  493. return;
  494. case 0:
  495. // add the user to the lobby
  496. if(!game_join_lobby(fhttp, lobby_list[lobby_index])) {
  497. FURI_LOG_E(TAG, "Failed to join lobby");
  498. easy_flipper_dialog("Error", "Failed to join lobby. Press BACK to return.");
  499. flipper_http_free(fhttp);
  500. furi_string_free(lobby);
  501. return;
  502. }
  503. // send the user to the waiting screen
  504. game_waiting_lobby(app);
  505. return;
  506. case 1:
  507. // check if the user is in the lobby
  508. if(game_in_lobby(fhttp, lobby)) {
  509. // send the user to the waiting screen
  510. FURI_LOG_I(TAG, "User is in the lobby");
  511. flipper_http_free(fhttp);
  512. furi_string_free(lobby);
  513. game_waiting_lobby(app);
  514. return;
  515. }
  516. // add the user to the lobby
  517. if(!game_join_lobby(fhttp, lobby_list[lobby_index])) {
  518. FURI_LOG_E(TAG, "Failed to join lobby");
  519. easy_flipper_dialog("Error", "Failed to join lobby. Press BACK to return.");
  520. flipper_http_free(fhttp);
  521. furi_string_free(lobby);
  522. return;
  523. }
  524. break;
  525. case 2:
  526. // show an error message saying the lobby is full
  527. FURI_LOG_E(TAG, "Lobby is full");
  528. easy_flipper_dialog("Error", "Lobby is full. Press BACK to return.");
  529. flipper_http_free(fhttp);
  530. furi_string_free(lobby);
  531. return;
  532. };
  533. game_start_pvp(
  534. fhttp, lobby, app); // this will free both the fhttp and lobby, and start the game
  535. }
  536. }