Jelajahi Sumber

save player stats to API on game end

jblanked 1 tahun lalu
induk
melakukan
49077b49e5
4 mengubah file dengan 197 tambahan dan 5 penghapusan
  1. 4 4
      flipper_http/flipper_http.c
  2. 1 1
      game/game.c
  3. 191 0
      game/storage.c
  4. 1 0
      game/storage.h

+ 4 - 4
flipper_http/flipper_http.c

@@ -602,14 +602,14 @@ bool flipper_http_send_data(FlipperHTTP *fhttp, const char *data)
 
     // Create a buffer with data + '\n'
     size_t send_length = data_length + 1; // +1 for '\n'
-    if (send_length > 256)
+    if (send_length > 512)
     { // Ensure buffer size is sufficient
         FURI_LOG_E("FlipperHTTP", "Data too long to send over FHTTP->");
         return false;
     }
 
-    char send_buffer[257]; // 256 + 1 for safety
-    strncpy(send_buffer, data, 256);
+    char send_buffer[513]; // 512 + 1 for safety
+    strncpy(send_buffer, data, 512);
     send_buffer[data_length] = '\n';     // Append newline
     send_buffer[data_length + 1] = '\0'; // Null-terminate
 
@@ -1142,7 +1142,7 @@ bool flipper_http_post_request_with_headers(
     }
 
     // Prepare POST request command with headers and data
-    char command[256];
+    char command[512];
     int ret = snprintf(
         command,
         sizeof(command),

+ 1 - 1
game/game.c

@@ -81,7 +81,7 @@ static void game_stop(void *ctx)
             easy_flipper_dialog("Game Over", "Ran out of memory so the\ngame ended early.\nHit BACK to exit.");
         }
         FURI_LOG_I("Game", "Saving player context");
-        save_player_context(game_context->player_context);
+        save_player_context_api(game_context->player_context);
         FURI_LOG_I("Game", "Player context saved");
         easy_flipper_dialog("Game Saved", "Hit BACK to exit.");
     }

+ 191 - 0
game/storage.c

@@ -201,6 +201,197 @@ bool save_player_context(PlayerContext *player_context)
     return true;
 }
 
+bool save_player_context_api(PlayerContext *player_context)
+{
+    if (!player_context)
+    {
+        FURI_LOG_E(TAG, "Invalid player context");
+        return false;
+    }
+
+    FlipperHTTP *fhttp = flipper_http_alloc();
+    if (!fhttp)
+    {
+        FURI_LOG_E(TAG, "Failed to allocate FlipperHTTP");
+        return false;
+    }
+
+    // create JSON for all the player context data
+    FuriString *json = furi_string_alloc();
+    if (!json)
+    {
+        FURI_LOG_E(TAG, "Failed to allocate JSON string");
+        return false;
+    }
+
+    // opening brace
+    furi_string_cat_str(json, "{");
+
+    // 1. Username (String)
+    furi_string_cat_str(json, "\"username\":\"");
+    furi_string_cat_str(json, player_context->username);
+    furi_string_cat_str(json, "\",");
+
+    // 2. Level (uint32_t)
+    furi_string_cat_str(json, "\"level\":");
+    char buffer[32];
+    snprintf(buffer, sizeof(buffer), "%lu", player_context->level);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 3. XP (uint32_t)
+    furi_string_cat_str(json, "\"xp\":");
+    snprintf(buffer, sizeof(buffer), "%lu", player_context->xp);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 4. Health (uint32_t)
+    furi_string_cat_str(json, "\"health\":");
+    snprintf(buffer, sizeof(buffer), "%lu", player_context->health);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 5. Strength (uint32_t)
+    furi_string_cat_str(json, "\"strength\":");
+    snprintf(buffer, sizeof(buffer), "%lu", player_context->strength);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 6. Max Health (uint32_t)
+    furi_string_cat_str(json, "\"max_health\":");
+    snprintf(buffer, sizeof(buffer), "%lu", player_context->max_health);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 7. Health Regen (uint32_t)
+    furi_string_cat_str(json, "\"health_regen\":");
+    snprintf(buffer, sizeof(buffer), "%lu", player_context->health_regen);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 8. Elapsed Health Regen (float)
+    furi_string_cat_str(json, "\"elapsed_health_regen\":");
+    snprintf(buffer, sizeof(buffer), "%.6f", (double)player_context->elapsed_health_regen);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 9. Attack Timer (float)
+    furi_string_cat_str(json, "\"attack_timer\":");
+    snprintf(buffer, sizeof(buffer), "%.6f", (double)player_context->attack_timer);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 10. Elapsed Attack Timer (float)
+    furi_string_cat_str(json, "\"elapsed_attack_timer\":");
+    snprintf(buffer, sizeof(buffer), "%.6f", (double)player_context->elapsed_attack_timer);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 11. Direction (enum PlayerDirection)
+    furi_string_cat_str(json, "\"direction\":");
+    switch (player_context->direction)
+    {
+    case PLAYER_UP:
+        furi_string_cat_str(json, "\"up\",");
+        break;
+    case PLAYER_DOWN:
+        furi_string_cat_str(json, "\"down\",");
+        break;
+    case PLAYER_LEFT:
+        furi_string_cat_str(json, "\"left\",");
+        break;
+    case PLAYER_RIGHT:
+    default:
+        furi_string_cat_str(json, "\"right\",");
+        break;
+    }
+
+    // 12. State (enum PlayerState)
+    furi_string_cat_str(json, "\"state\":");
+    switch (player_context->state)
+    {
+    case PLAYER_IDLE:
+        furi_string_cat_str(json, "\"idle\",");
+        break;
+    case PLAYER_MOVING:
+        furi_string_cat_str(json, "\"moving\",");
+        break;
+    case PLAYER_ATTACKING:
+        furi_string_cat_str(json, "\"attacking\",");
+        break;
+    case PLAYER_ATTACKED:
+        furi_string_cat_str(json, "\"attacked\",");
+        break;
+    case PLAYER_DEAD:
+        furi_string_cat_str(json, "\"dead\",");
+        break;
+    default:
+        furi_string_cat_str(json, "\"unknown\",");
+        break;
+    }
+
+    // 13. Start Position X (float)
+    furi_string_cat_str(json, "\"start_position_x\":");
+    snprintf(buffer, sizeof(buffer), "%.6f", (double)player_context->start_position.x);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 14. Start Position Y (float)
+    furi_string_cat_str(json, "\"start_position_y\":");
+    snprintf(buffer, sizeof(buffer), "%.6f", (double)player_context->start_position.y);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 15. dx (int8_t)
+    furi_string_cat_str(json, "\"dx\":");
+    snprintf(buffer, sizeof(buffer), "%d", player_context->dx);
+    furi_string_cat_str(json, buffer);
+    furi_string_cat_str(json, ",");
+
+    // 16. dy (int8_t)
+    furi_string_cat_str(json, "\"dy\":");
+    snprintf(buffer, sizeof(buffer), "%d", player_context->dy);
+    furi_string_cat_str(json, buffer);
+
+    // closing brace
+    furi_string_cat_str(json, "}");
+
+    // save the json to API
+
+    // create new JSON with username key (of just username), and game_stats key (of the all of the data)
+    FuriString *json_data = furi_string_alloc();
+    if (!json_data)
+    {
+        FURI_LOG_E(TAG, "Failed to allocate JSON string");
+        furi_string_free(json);
+        return false;
+    }
+
+    furi_string_cat_str(json_data, "{\"username\":\"");
+    furi_string_cat_str(json_data, player_context->username);
+    furi_string_cat_str(json_data, "\",\"game_stats\":");
+    furi_string_cat(json_data, json);
+    furi_string_cat_str(json_data, "}");
+
+    furi_string_free(json);
+
+    // save the json_data to the API
+    if (!flipper_http_post_request_with_headers(fhttp, "https://www.flipsocial.net/api/user/update-game-stats/", "{\"Content-Type\":\"application/json\"}", furi_string_get_cstr(json_data)))
+    {
+        FURI_LOG_E(TAG, "Failed to save player context to API");
+        furi_string_free(json_data);
+        return false;
+    }
+    fhttp->state = RECEIVING;
+    while (fhttp->state != IDLE)
+    {
+        furi_delay_ms(100);
+    }
+    furi_string_free(json_data);
+    flipper_http_free(fhttp);
+    return true;
+}
+
 // Helper function to load an integer
 static bool load_number(const char *path_name, int *value)
 {

+ 1 - 0
game/storage.h

@@ -5,6 +5,7 @@
 #include <flip_storage/storage.h>
 
 bool save_player_context(PlayerContext *player_context);
+bool save_player_context_api(PlayerContext *player_context);
 bool load_player_context(PlayerContext *player_context);
 bool set_player_context();