callback.c 22 KB

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