|
@@ -1545,229 +1545,312 @@ void callback_submenu_choices(void *context, uint32_t index)
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-static void callback_submenu_lobby_choices(void *context, uint32_t index)
|
|
|
|
|
|
|
+static bool fetch_lobby(FlipperHTTP *fhttp, char *lobby_name)
|
|
|
{
|
|
{
|
|
|
- /* Handle other game lobbies
|
|
|
|
|
- 1. when clicked on, send request to fetch the selected game lobby details
|
|
|
|
|
- 2. start the websocket session
|
|
|
|
|
- 3. start the game thread (the rest will be handled by game_start and player_update)
|
|
|
|
|
- */
|
|
|
|
|
- FlipWorldApp *app = (FlipWorldApp *)context;
|
|
|
|
|
- if (!app)
|
|
|
|
|
|
|
+ if (!fhttp)
|
|
|
{
|
|
{
|
|
|
- FURI_LOG_E(TAG, "FlipWorldApp is NULL");
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ FURI_LOG_E(TAG, "FlipperHTTP is NULL");
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
- if (index >= FlipWorldSubmenuIndexLobby && index < FlipWorldSubmenuIndexLobby + 10)
|
|
|
|
|
|
|
+ if (!lobby_name || strlen(lobby_name) == 0)
|
|
|
{
|
|
{
|
|
|
- lobby_index = index - FlipWorldSubmenuIndexLobby;
|
|
|
|
|
-
|
|
|
|
|
- FlipperHTTP *fhttp = flipper_http_alloc();
|
|
|
|
|
- if (!fhttp)
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Failed to allocate FlipperHTTP");
|
|
|
|
|
- easy_flipper_dialog("Error", "Failed to allocate FlipperHTTP. Press BACK to return.");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ FURI_LOG_E(TAG, "Lobby name is NULL or empty");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ char username[64];
|
|
|
|
|
+ if (!load_char("Flip-Social-Username", username, sizeof(username)))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to load Flip-Social-Username");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ // send the request to fetch the lobby details, with player_username
|
|
|
|
|
+ char url[128];
|
|
|
|
|
+ snprintf(url, sizeof(url), "https://www.jblanked.com/flipper/api/world/pvp/lobby/get/%s/%s/", lobby_name, username);
|
|
|
|
|
+ snprintf(fhttp->file_path, sizeof(fhttp->file_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/pvp/lobbies/%s.json", lobby_name);
|
|
|
|
|
+ fhttp->save_received_data = true;
|
|
|
|
|
+ if (!flipper_http_request(fhttp, GET, url, "{\"Content-Type\":\"application/json\"}", NULL))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to fetch lobby details");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ fhttp->state = RECEIVING;
|
|
|
|
|
+ while (fhttp->state != IDLE)
|
|
|
|
|
+ {
|
|
|
|
|
+ furi_delay_ms(100);
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+static bool join_lobby(FlipperHTTP *fhttp, char *lobby_name)
|
|
|
|
|
+{
|
|
|
|
|
+ if (!fhttp)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "FlipperHTTP is NULL");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!lobby_name || strlen(lobby_name) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Lobby name is NULL or empty");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ char username[64];
|
|
|
|
|
+ if (!load_char("Flip-Social-Username", username, sizeof(username)))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to load Flip-Social-Username");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ char url[128];
|
|
|
|
|
+ char payload[128];
|
|
|
|
|
+ snprintf(payload, sizeof(payload), "{\"username\":\"%s\", \"game_id\":\"%s\"}", username, lobby_name);
|
|
|
|
|
+ save_char("pvp_lobby_name", lobby_name); // save the lobby name
|
|
|
|
|
+ snprintf(url, sizeof(url), "https://www.jblanked.com/flipper/api/world/pvp/lobby/join/");
|
|
|
|
|
+ if (!flipper_http_request(fhttp, POST, url, "{\"Content-Type\":\"application/json\"}", payload))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to join lobby");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ fhttp->state = RECEIVING;
|
|
|
|
|
+ while (fhttp->state != IDLE)
|
|
|
|
|
+ {
|
|
|
|
|
+ furi_delay_ms(100);
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+static bool create_pvp_enemy(FuriString *lobby_details)
|
|
|
|
|
+{
|
|
|
|
|
+ if (!lobby_details)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to load lobby details");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- char username[64];
|
|
|
|
|
- if (!load_char("Flip-Social-Username", username, sizeof(username)))
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Failed to load Flip-Social-Username");
|
|
|
|
|
- easy_flipper_dialog("Error", "Failed to load saved username. Go to settings to update.");
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // parse the lobby details
|
|
|
|
|
+ FuriString *player_stats = get_json_array_value_furi("player_stats", 0, lobby_details);
|
|
|
|
|
+ if (!player_stats)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to get player stats");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // send the request to fetch the lobby details, with player_username
|
|
|
|
|
- char url[128];
|
|
|
|
|
- snprintf(url, sizeof(url), "https://www.jblanked.com/flipper/api/world/pvp/lobby/get/%s/%s/", lobby_list[lobby_index], username);
|
|
|
|
|
- snprintf(fhttp->file_path, sizeof(fhttp->file_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/pvp/lobbies/%s.json", lobby_list[lobby_index]);
|
|
|
|
|
- fhttp->save_received_data = true;
|
|
|
|
|
|
|
+ // available keys from player_stats
|
|
|
|
|
+ FuriString *username = get_json_value_furi("username", player_stats);
|
|
|
|
|
+ FuriString *strength = get_json_value_furi("strength", player_stats);
|
|
|
|
|
+ FuriString *health = get_json_value_furi("health", player_stats);
|
|
|
|
|
+ FuriString *attack_timer = get_json_value_furi("attack_timer", player_stats);
|
|
|
|
|
|
|
|
- bool fetch_lobby()
|
|
|
|
|
- {
|
|
|
|
|
- if (!flipper_http_request(fhttp, GET, url, "{\"Content-Type\":\"application/json\"}", NULL))
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Failed to fetch lobby details");
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!username || !strength || !health || !attack_timer)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to get player stats");
|
|
|
|
|
+ furi_string_free(player_stats);
|
|
|
|
|
+ if (username)
|
|
|
|
|
+ furi_string_free(username);
|
|
|
|
|
+ if (strength)
|
|
|
|
|
+ furi_string_free(strength);
|
|
|
|
|
+ if (health)
|
|
|
|
|
+ furi_string_free(health);
|
|
|
|
|
+ if (attack_timer)
|
|
|
|
|
+ furi_string_free(attack_timer);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- bool parse_lobby()
|
|
|
|
|
- {
|
|
|
|
|
- char directory_path[128];
|
|
|
|
|
- snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world");
|
|
|
|
|
- Storage *storage = furi_record_open(RECORD_STORAGE);
|
|
|
|
|
- storage_common_mkdir(storage, directory_path);
|
|
|
|
|
- snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds");
|
|
|
|
|
- storage_common_mkdir(storage, directory_path);
|
|
|
|
|
- snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/pvp_world");
|
|
|
|
|
- storage_common_mkdir(storage, directory_path);
|
|
|
|
|
- furi_record_close(RECORD_STORAGE);
|
|
|
|
|
|
|
+ // create enemy data
|
|
|
|
|
+ FuriString *enemy_data = furi_string_alloc();
|
|
|
|
|
+ furi_string_printf(enemy_data, "{\"enemy_data\":[{\"id\":\"sword\",\"is_user\":\"true\",\"index\":0,\"start_position\":{\"x\":350,\"y\":210},\"end_position\":{\"x\":350,\"y\":210},\"move_timer\":1,\"speed\":1,\"attack_timer\":%s,\"strength\":%s,\"health\":%s}]}",
|
|
|
|
|
+ furi_string_get_cstr(attack_timer), furi_string_get_cstr(strength), furi_string_get_cstr(health));
|
|
|
|
|
|
|
|
- snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/pvp_world/pvp_world_enemy_data.json");
|
|
|
|
|
|
|
+ char directory_path[128];
|
|
|
|
|
+ snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world");
|
|
|
|
|
+ Storage *storage = furi_record_open(RECORD_STORAGE);
|
|
|
|
|
+ storage_common_mkdir(storage, directory_path);
|
|
|
|
|
+ snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds");
|
|
|
|
|
+ storage_common_mkdir(storage, directory_path);
|
|
|
|
|
+ snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/pvp_world");
|
|
|
|
|
+ storage_common_mkdir(storage, directory_path);
|
|
|
|
|
+ furi_record_close(RECORD_STORAGE);
|
|
|
|
|
|
|
|
- // remove the enemy_data file if it exists
|
|
|
|
|
- storage_simply_remove_recursive(storage, directory_path);
|
|
|
|
|
|
|
+ snprintf(directory_path, sizeof(directory_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/pvp_world/pvp_world_enemy_data.json");
|
|
|
|
|
|
|
|
- // load the lobby details
|
|
|
|
|
- FuriString *lobby = flipper_http_load_from_file(fhttp->file_path);
|
|
|
|
|
- if (!lobby)
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Failed to load lobby details");
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // remove the enemy_data file if it exists
|
|
|
|
|
+ storage_simply_remove_recursive(storage, directory_path);
|
|
|
|
|
|
|
|
- // check if the player is in the lobby
|
|
|
|
|
- FuriString *is_in_game = get_json_value_furi("is_in_game", lobby);
|
|
|
|
|
- FuriString *player_count = get_json_value_furi("player_count", lobby);
|
|
|
|
|
- if (!is_in_game || !player_count)
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Failed to get player count");
|
|
|
|
|
- furi_string_free(lobby);
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ File *file = storage_file_alloc(storage);
|
|
|
|
|
+ if (!storage_file_open(file, directory_path, FSAM_WRITE, FSOM_CREATE_ALWAYS))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E("Game", "Failed to open file for writing: %s", directory_path);
|
|
|
|
|
+ storage_file_free(file);
|
|
|
|
|
+ furi_record_close(RECORD_STORAGE);
|
|
|
|
|
+ furi_string_free(enemy_data);
|
|
|
|
|
+ furi_string_free(player_stats);
|
|
|
|
|
+ furi_string_free(username);
|
|
|
|
|
+ furi_string_free(strength);
|
|
|
|
|
+ furi_string_free(health);
|
|
|
|
|
+ furi_string_free(attack_timer);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (is_str(furi_string_get_cstr(is_in_game), "true"))
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Player is already in game");
|
|
|
|
|
- furi_string_free(lobby);
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ size_t data_size = furi_string_size(enemy_data);
|
|
|
|
|
+ if (storage_file_write(file, furi_string_get_cstr(enemy_data), data_size) != data_size)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E("Game", "Failed to write enemy_data");
|
|
|
|
|
+ }
|
|
|
|
|
+ storage_file_close(file);
|
|
|
|
|
|
|
|
- // add the user to the lobby
|
|
|
|
|
- bool join_lobby()
|
|
|
|
|
- {
|
|
|
|
|
- char url[128];
|
|
|
|
|
- char payload[128];
|
|
|
|
|
- snprintf(payload, sizeof(payload), "{\"username\":\"%s\", \"game_id\":\"%s\"}", username, lobby_list[lobby_index]);
|
|
|
|
|
- save_char("pvp_lobby_name", lobby_list[lobby_index]); // save the lobby name
|
|
|
|
|
- snprintf(url, sizeof(url), "https://www.jblanked.com/flipper/api/world/pvp/lobby/join/");
|
|
|
|
|
- return flipper_http_request(fhttp, POST, url, "{\"Content-Type\":\"application/json\"}", payload);
|
|
|
|
|
- }
|
|
|
|
|
- bool parse_join()
|
|
|
|
|
- {
|
|
|
|
|
- // true as long as the request was successful
|
|
|
|
|
- return fhttp->state != ISSUE;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ furi_string_free(enemy_data);
|
|
|
|
|
+ furi_string_free(player_stats);
|
|
|
|
|
+ furi_string_free(username);
|
|
|
|
|
+ furi_string_free(strength);
|
|
|
|
|
+ furi_string_free(health);
|
|
|
|
|
+ furi_string_free(attack_timer);
|
|
|
|
|
|
|
|
- // well.. we need to wait for the response to be received
|
|
|
|
|
- if (!flipper_http_process_response_async(fhttp, join_lobby, parse_join))
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Failed to join lobby");
|
|
|
|
|
- easy_flipper_dialog("Error", "Failed to join lobby. Press BACK to return.");
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+// since we aren't using FURI_LOG, we will use easy_flipper_dialog and the last_error_message
|
|
|
|
|
+// char last_error_message[64];
|
|
|
|
|
+static bool parse_lobby(FlipperHTTP *fhttp)
|
|
|
|
|
+{
|
|
|
|
|
+ if (!fhttp)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "FlipperHTTP is NULL");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (atoi(furi_string_get_cstr(player_count)) == 0)
|
|
|
|
|
- {
|
|
|
|
|
- // player is the only one in lobby so don't process any enemies yet
|
|
|
|
|
- FURI_LOG_I(TAG, "No enemies in lobby");
|
|
|
|
|
- furi_string_free(lobby);
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // load the lobby details
|
|
|
|
|
+ FuriString *lobby = flipper_http_load_from_file(fhttp->file_path);
|
|
|
|
|
+ if (!lobby)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to load lobby details");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // only an enemy is in the lobby
|
|
|
|
|
|
|
+ // check if the player is in the lobby
|
|
|
|
|
+ FuriString *is_in_game = get_json_value_furi("is_in_game", lobby);
|
|
|
|
|
+ FuriString *player_count = get_json_value_furi("player_count", lobby);
|
|
|
|
|
+ if (!is_in_game || !player_count)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to get player count");
|
|
|
|
|
+ furi_string_free(lobby);
|
|
|
|
|
+ if (is_in_game)
|
|
|
|
|
+ furi_string_free(is_in_game);
|
|
|
|
|
+ if (player_count)
|
|
|
|
|
+ furi_string_free(player_count);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // parse the lobby details
|
|
|
|
|
- FuriString *player_stats = get_json_array_value_furi("player_stats", 0, lobby);
|
|
|
|
|
- if (!player_stats)
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Failed to get player stats");
|
|
|
|
|
- furi_string_free(lobby);
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (is_str(furi_string_get_cstr(is_in_game), "true"))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Player is already in game");
|
|
|
|
|
+ furi_string_free(lobby);
|
|
|
|
|
+ furi_string_free(is_in_game);
|
|
|
|
|
+ furi_string_free(player_count);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // available keys from player_stats
|
|
|
|
|
- FuriString *fw_username = get_json_value_furi("username", player_stats);
|
|
|
|
|
- FuriString *strength = get_json_value_furi("strength", player_stats);
|
|
|
|
|
- FuriString *health = get_json_value_furi("health", player_stats);
|
|
|
|
|
- FuriString *attack_timer = get_json_value_furi("attack_timer", player_stats);
|
|
|
|
|
|
|
+ // add the user to the lobby
|
|
|
|
|
+ if (!join_lobby(fhttp, lobby_list[lobby_index]))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to join lobby");
|
|
|
|
|
+ furi_string_free(lobby);
|
|
|
|
|
+ furi_string_free(is_in_game);
|
|
|
|
|
+ furi_string_free(player_count);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (!fw_username || !strength || !health || !attack_timer)
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E(TAG, "Failed to get player stats");
|
|
|
|
|
- furi_string_free(player_stats);
|
|
|
|
|
- furi_string_free(lobby);
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (atoi(furi_string_get_cstr(player_count)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ // player is the only one in lobby so don't process any enemies yet
|
|
|
|
|
+ FURI_LOG_I(TAG, "No enemies in lobby");
|
|
|
|
|
+ furi_string_free(lobby);
|
|
|
|
|
+ furi_string_free(is_in_game);
|
|
|
|
|
+ furi_string_free(player_count);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // create enemy data
|
|
|
|
|
- FuriString *enemy_data = furi_string_alloc();
|
|
|
|
|
- furi_string_printf(enemy_data, "{\"enemy_data\":[{\"id\":\"sword\",\"is_user\":\"true\",\"index\":0,\"start_position\":{\"x\":350,\"y\":210},\"end_position\":{\"x\":350,\"y\":210},\"move_timer\":1,\"speed\":1,\"attack_timer\":%s,\"strength\":%s,\"health\":%s}]}",
|
|
|
|
|
- furi_string_get_cstr(attack_timer), furi_string_get_cstr(strength), furi_string_get_cstr(health));
|
|
|
|
|
|
|
+ // only an enemy is in the lobby
|
|
|
|
|
|
|
|
- File *file = storage_file_alloc(storage);
|
|
|
|
|
- if (!storage_file_open(file, directory_path, FSAM_WRITE, FSOM_CREATE_ALWAYS))
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E("Game", "Failed to open file for writing: %s", directory_path);
|
|
|
|
|
- storage_file_free(file);
|
|
|
|
|
- furi_record_close(RECORD_STORAGE);
|
|
|
|
|
- furi_string_free(enemy_data);
|
|
|
|
|
- furi_string_free(player_stats);
|
|
|
|
|
- furi_string_free(lobby);
|
|
|
|
|
- furi_string_free(fw_username);
|
|
|
|
|
- furi_string_free(strength);
|
|
|
|
|
- furi_string_free(health);
|
|
|
|
|
- furi_string_free(attack_timer);
|
|
|
|
|
- flipper_http_free(fhttp);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // parse the lobby details
|
|
|
|
|
+ if (!create_pvp_enemy(lobby))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_I(TAG, "Failed to create pvp enemy data");
|
|
|
|
|
+ furi_string_free(lobby);
|
|
|
|
|
+ furi_string_free(is_in_game);
|
|
|
|
|
+ furi_string_free(player_count);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- size_t data_size = furi_string_size(enemy_data);
|
|
|
|
|
- if (storage_file_write(file, furi_string_get_cstr(enemy_data), data_size) != data_size)
|
|
|
|
|
- {
|
|
|
|
|
- FURI_LOG_E("Game", "Failed to write enemy_data");
|
|
|
|
|
- }
|
|
|
|
|
- storage_file_close(file);
|
|
|
|
|
|
|
+ furi_string_free(lobby);
|
|
|
|
|
+ furi_string_free(is_in_game);
|
|
|
|
|
+ furi_string_free(player_count);
|
|
|
|
|
|
|
|
- furi_string_free(enemy_data);
|
|
|
|
|
- furi_string_free(player_stats);
|
|
|
|
|
- furi_string_free(lobby);
|
|
|
|
|
- furi_string_free(fw_username);
|
|
|
|
|
- furi_string_free(strength);
|
|
|
|
|
- furi_string_free(health);
|
|
|
|
|
- furi_string_free(attack_timer);
|
|
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+static bool start_ws(FlipperHTTP *fhttp, char *lobby_name)
|
|
|
|
|
+{
|
|
|
|
|
+ if (!fhttp)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "FlipperHTTP is NULL");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!lobby_name || strlen(lobby_name) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Lobby name is NULL or empty");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ fhttp->state = IDLE; // ensure it's set to IDLE for the next request
|
|
|
|
|
+ char websocket_url[128];
|
|
|
|
|
+ snprintf(websocket_url, sizeof(websocket_url), "ws://www.jblanked.com/ws/game/%s/", lobby_name);
|
|
|
|
|
+ if (!flipper_http_websocket_start(fhttp, websocket_url, 80, "{\"Content-Type\":\"application/json\"}"))
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to start websocket");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ fhttp->state = RECEIVING;
|
|
|
|
|
+ while (fhttp->state != IDLE)
|
|
|
|
|
+ {
|
|
|
|
|
+ furi_delay_ms(100);
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+static void callback_submenu_lobby_choices(void *context, uint32_t index)
|
|
|
|
|
+{
|
|
|
|
|
+ /* Handle other game lobbies
|
|
|
|
|
+ 1. when clicked on, send request to fetch the selected game lobby details
|
|
|
|
|
+ 2. start the websocket session
|
|
|
|
|
+ 3. start the game thread (the rest will be handled by game_start and player_update)
|
|
|
|
|
+ */
|
|
|
|
|
+ FlipWorldApp *app = (FlipWorldApp *)context;
|
|
|
|
|
+ if (!app)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "FlipWorldApp is NULL");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (index >= FlipWorldSubmenuIndexLobby && index < FlipWorldSubmenuIndexLobby + 10)
|
|
|
|
|
+ {
|
|
|
|
|
+ lobby_index = index - FlipWorldSubmenuIndexLobby;
|
|
|
|
|
|
|
|
- return true;
|
|
|
|
|
|
|
+ FlipperHTTP *fhttp = flipper_http_alloc();
|
|
|
|
|
+ if (!fhttp)
|
|
|
|
|
+ {
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to allocate FlipperHTTP");
|
|
|
|
|
+ easy_flipper_dialog("Error", "Failed to allocate FlipperHTTP. Press BACK to return.");
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // well.. we need to wait for the response to be received
|
|
|
|
|
- if (!flipper_http_process_response_async(fhttp, fetch_lobby, parse_lobby))
|
|
|
|
|
|
|
+ // fetch the lobby details
|
|
|
|
|
+ if (!fetch_lobby(fhttp, lobby_list[lobby_index]))
|
|
|
{
|
|
{
|
|
|
FURI_LOG_E(TAG, "Failed to fetch lobby details");
|
|
FURI_LOG_E(TAG, "Failed to fetch lobby details");
|
|
|
easy_flipper_dialog("Error", "Failed to fetch lobby details. Press BACK to return.");
|
|
easy_flipper_dialog("Error", "Failed to fetch lobby details. Press BACK to return.");
|
|
|
flipper_http_free(fhttp);
|
|
flipper_http_free(fhttp);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // start the websocket session
|
|
|
|
|
- bool start_ws()
|
|
|
|
|
|
|
+ if (!parse_lobby(fhttp))
|
|
|
{
|
|
{
|
|
|
- fhttp->state = IDLE; // ensure it's set to IDLE for the next request
|
|
|
|
|
- char websocket_url[128];
|
|
|
|
|
- snprintf(websocket_url, sizeof(websocket_url), "ws://www.jblanked.com/ws/game/%s/", lobby_list[lobby_index]);
|
|
|
|
|
- return flipper_http_websocket_start(fhttp, websocket_url, 80, "{\"Content-Type\":\"application/json\"}");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- bool parse_ws()
|
|
|
|
|
- {
|
|
|
|
|
- // for now just return true and the game will handle the rest
|
|
|
|
|
- return fhttp->state != ISSUE;
|
|
|
|
|
|
|
+ FURI_LOG_E(TAG, "Failed to parse lobby details, join the lobby, or create pvp enemy context.")
|
|
|
|
|
+ easy_flipper_dialog("Error", "Failed to parse lobby details, join the lobby, or create pvp enemy context. Press BACK to return.");
|
|
|
|
|
+ flipper_http_free(fhttp);
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// start the websocket session
|
|
// start the websocket session
|
|
|
- if (!flipper_http_process_response_async(fhttp, start_ws, parse_ws))
|
|
|
|
|
|
|
+ if (!start_ws(fhttp, lobby_list[lobby_index]))
|
|
|
{
|
|
{
|
|
|
FURI_LOG_E(TAG, "Failed to start websocket session");
|
|
FURI_LOG_E(TAG, "Failed to start websocket session");
|
|
|
easy_flipper_dialog("Error", "Failed to start websocket session. Press BACK to return.");
|
|
easy_flipper_dialog("Error", "Failed to start websocket session. Press BACK to return.");
|