jblanked 1 год назад
Родитель
Сommit
5799a12de7
8 измененных файлов с 109 добавлено и 31 удалено
  1. 22 23
      callback/callback.c
  2. 5 0
      game/game.c
  3. 29 3
      game/level.c
  4. 2 1
      game/level.h
  5. 43 1
      game/world.c
  6. 2 1
      game/world.h
  7. 3 1
      jsmn/jsmn.c
  8. 3 1
      jsmn/jsmn_furi.c

+ 22 - 23
callback/callback.c

@@ -525,14 +525,34 @@ static bool flip_world_fetch_world_list(DataLoaderModel *model)
     }
     }
     else if (model->request_index == 1)
     else if (model->request_index == 1)
     {
     {
+        FuriString *world_list = flipper_http_load_from_file(fhttp.file_path);
+        if (!world_list)
+        {
+            FURI_LOG_E(TAG, "Failed to load world list");
+            return "Failed to load world list";
+        }
+        FuriString *first_world = get_json_array_value_furi("worlds", 0, world_list);
+        if (!first_world)
+        {
+            FURI_LOG_E(TAG, "Failed to get first world");
+            return "Failed to get first world";
+        }
+        // if (world_exists(furi_string_get_cstr(first_world)))
+        // {
+        //     furi_string_free(world_list);
+        //     furi_string_free(first_world);
+        //     FURI_LOG_I(TAG, "World already exists");
+        //     fhttp.state = IDLE;
+        //     return true;
+        // }
         snprintf(
         snprintf(
             fhttp.file_path,
             fhttp.file_path,
             sizeof(fhttp.file_path),
             sizeof(fhttp.file_path),
-            STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/%p.json", model->parser_context);
+            STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/%s.json", furi_string_get_cstr(first_world));
 
 
         fhttp.save_received_data = true;
         fhttp.save_received_data = true;
         char url[128];
         char url[128];
-        snprintf(url, sizeof(url), "https://www.flipsocial.net/api/world/get/world/%p/", model->parser_context);
+        snprintf(url, sizeof(url), "https://www.flipsocial.net/api/world/get/world/%s/", furi_string_get_cstr(first_world));
         return flipper_http_get_request_with_headers(url, "{\"Content-Type\":\"application/json\"}");
         return flipper_http_get_request_with_headers(url, "{\"Content-Type\":\"application/json\"}");
     }
     }
     return false;
     return false;
@@ -541,32 +561,11 @@ static char *flip_world_parse_world_list(DataLoaderModel *model)
 {
 {
     if (model->request_index == 0)
     if (model->request_index == 0)
     {
     {
-        FuriString *world_list = flipper_http_load_from_file(fhttp.file_path);
-        if (!world_list)
-        {
-            FURI_LOG_E(TAG, "Failed to load world list");
-            return "Failed to load world list";
-        }
-        FuriString *first_world = get_json_array_value_furi("worlds", 0, world_list);
-        if (!first_world)
-        {
-            FURI_LOG_E(TAG, "Failed to get first world");
-            return "Failed to get first world";
-        }
-        model->parser_context = malloc(furi_string_size(first_world) + 1);
-        if (!model->parser_context)
-        {
-            FURI_LOG_E(TAG, "Failed to allocate parser context");
-            return "Failed to allocate parser context";
-        }
-        snprintf(model->parser_context, furi_string_size(first_world) + 1, "%s", furi_string_get_cstr(first_world));
         return "World List Fetched";
         return "World List Fetched";
     }
     }
     else if (model->request_index == 1)
     else if (model->request_index == 1)
     {
     {
         flipper_http_deinit();
         flipper_http_deinit();
-        free(model->parser_context);
-        model->parser_context = NULL;
         // free game thread
         // free game thread
         if (game_thread_running)
         if (game_thread_running)
         {
         {

+ 5 - 0
game/game.c

@@ -151,6 +151,9 @@ static void game_start(GameManager *game_manager, void *ctx)
     {
     {
         FURI_LOG_E("Game", "Failed to load world list");
         FURI_LOG_E("Game", "Failed to load world list");
         levels[0] = game_manager_add_level(game_manager, generic_level("town_world", 0));
         levels[0] = game_manager_add_level(game_manager, generic_level("town_world", 0));
+        levels[1] = game_manager_add_level(game_manager, generic_level("tree_world", 1));
+        levels[2] = game_manager_add_level(game_manager, generic_level("generic_world", 2));
+        return;
     }
     }
     for (int i = 0; i < 10; i++)
     for (int i = 0; i < 10; i++)
     {
     {
@@ -160,7 +163,9 @@ static void game_start(GameManager *game_manager, void *ctx)
             break;
             break;
         }
         }
         levels[i] = game_manager_add_level(game_manager, generic_level(furi_string_get_cstr(world_name), i));
         levels[i] = game_manager_add_level(game_manager, generic_level(furi_string_get_cstr(world_name), i));
+        furi_string_free(world_name);
     }
     }
+    furi_string_free(world_list);
 }
 }
 
 
 /*
 /*

+ 29 - 3
game/level.c

@@ -7,9 +7,33 @@ static void level_start(Level *level, GameManager *manager, void *context)
     // check if the world exists
     // check if the world exists
     if (!world_exists(level_context->id))
     if (!world_exists(level_context->id))
     {
     {
-        FURI_LOG_E("Game", "World does not exist");
-        easy_flipper_dialog("[WORLD ERROR]", "No world data installed.\n\n\nSettings -> Game ->\nInstall Official World Pack");
-        draw_town_world(level);
+        FURI_LOG_E("Game", "World does not exist.. downloading now");
+        if (!level_context->app)
+        {
+            level_context->app = (FlipWorldApp *)malloc(sizeof(FlipWorldApp));
+            if (!level_context->app)
+            {
+                FURI_LOG_E("Game", "Failed to allocate FlipWorldApp");
+                return;
+            }
+        }
+        FuriString *world_data = fetch_world(level_context->id, level_context->app);
+        if (!world_data)
+        {
+            FURI_LOG_E("Game", "Failed to fetch world data");
+            draw_town_world(level);
+            free(level_context->app);
+            level_context->app = NULL;
+            return;
+        }
+        if (!draw_json_world(level, furi_string_get_cstr(world_data)))
+        {
+            FURI_LOG_E("Game", "Failed to draw world");
+            draw_town_world(level);
+        }
+        free(level_context->app);
+        level_context->app = NULL;
+        furi_string_free(world_data);
         return;
         return;
     }
     }
     // get the world data
     // get the world data
@@ -38,6 +62,7 @@ static LevelContext *level_generic_alloc(const char *id, int index)
     }
     }
     snprintf(level_context_generic->id, sizeof(level_context_generic->id), "%s", id);
     snprintf(level_context_generic->id, sizeof(level_context_generic->id), "%s", id);
     level_context_generic->index = index;
     level_context_generic->index = index;
+    level_context_generic->app = NULL;
     return level_context_generic;
     return level_context_generic;
 }
 }
 static void level_generic_free()
 static void level_generic_free()
@@ -59,6 +84,7 @@ static void level_alloc_generic_world(Level *level, GameManager *manager, void *
     LevelContext *level_context = context;
     LevelContext *level_context = context;
     snprintf(level_context->id, sizeof(level_context->id), "%s", level_context_generic->id);
     snprintf(level_context->id, sizeof(level_context->id), "%s", level_context_generic->id);
     level_context->index = level_context_generic->index;
     level_context->index = level_context_generic->index;
+    level_context->app = level_context_generic->app;
     player_spawn(level, manager);
     player_spawn(level, manager);
 }
 }
 
 

+ 2 - 1
game/level.h

@@ -1,10 +1,11 @@
 #pragma once
 #pragma once
 #include "game.h"
 #include "game.h"
-
+#include "flip_world.h"
 typedef struct
 typedef struct
 {
 {
     char id[64];
     char id[64];
     int index;
     int index;
+    FlipWorldApp *app;
 } LevelContext;
 } LevelContext;
 
 
 const LevelBehaviour *generic_level(const char *id, int index);
 const LevelBehaviour *generic_level(const char *id, int index);

+ 43 - 1
game/world.c

@@ -300,4 +300,46 @@ void draw_town_world(Level *level)
         { "icon": "tree", "x": 362, "y": 50,  "width": 16, "height": 16, "amount": 8,  "horizontal": false }
         { "icon": "tree", "x": 362, "y": 50,  "width": 16, "height": 16, "amount": 8,  "horizontal": false }
     ]
     ]
 }
 }
-*/
+*/
+
+FuriString *fetch_world(char *name, void *app)
+{
+    if (!app || !name)
+    {
+        FURI_LOG_E("Game", "App or name is NULL");
+        return NULL;
+    }
+    if (!flipper_http_init(flipper_http_rx_callback, app))
+    {
+        FURI_LOG_E("Game", "Failed to initialize HTTP");
+        return NULL;
+    }
+    char url[256];
+    snprintf(url, sizeof(url), "https://www.flipsocial.net/api/world/get/world/%s/", name);
+    snprintf(fhttp.file_path, sizeof(fhttp.file_path), STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/%s.json", name);
+    fhttp.save_received_data = true;
+    if (!flipper_http_get_request_with_headers(url, "{\"Content-Type\": \"application/json\"}"))
+    {
+        FURI_LOG_E("Game", "Failed to send HTTP request");
+        return NULL;
+    }
+    furi_timer_start(fhttp.get_timeout_timer, TIMEOUT_DURATION_TICKS);
+    while (fhttp.state == RECEIVING && furi_timer_is_running(fhttp.get_timeout_timer) > 0)
+    {
+        // Wait for the request to be received
+        furi_delay_ms(100);
+    }
+    furi_timer_stop(fhttp.get_timeout_timer);
+    if (fhttp.state != IDLE)
+    {
+        FURI_LOG_E("Game", "Failed to receive world data");
+        return NULL;
+    }
+    FuriString *returned_data = flipper_http_load_from_file(fhttp.file_path);
+    if (!returned_data)
+    {
+        FURI_LOG_E("Game", "Failed to load world data from file");
+        return NULL;
+    }
+    return returned_data;
+}

+ 2 - 1
game/world.h

@@ -16,4 +16,5 @@ void draw_example_world(Level *level);
 void draw_tree_world(Level *level);
 void draw_tree_world(Level *level);
 void draw_town_world(Level *level);
 void draw_town_world(Level *level);
 bool draw_json_world(Level *level, const char *json_data);
 bool draw_json_world(Level *level, const char *json_data);
-bool draw_json_world_furi(Level *level, FuriString *json_data);
+bool draw_json_world_furi(Level *level, FuriString *json_data);
+FuriString *fetch_world(char *name, void *app);

+ 3 - 1
jsmn/jsmn.c

@@ -508,7 +508,9 @@ char *get_json_value(char *key, const char *json_data)
     {
     {
         FURI_LOG_E("JSMM.H", "JSON data is NULL");
         FURI_LOG_E("JSMM.H", "JSON data is NULL");
     }
     }
-    FURI_LOG_E("JSMM.H", "Failed to find the key in the JSON.");
+    char warning[128];
+    snprintf(warning, sizeof(warning), "Failed to find the key \"%s\" in the JSON.", key);
+    FURI_LOG_E("JSMM.H", warning);
     return NULL; // Return NULL if something goes wrong
     return NULL; // Return NULL if something goes wrong
 }
 }
 
 

+ 3 - 1
jsmn/jsmn_furi.c

@@ -531,7 +531,9 @@ FuriString *get_json_value_furi(const char *key, const FuriString *json_data)
 
 
     free(tokens);
     free(tokens);
     furi_string_free(key_str);
     furi_string_free(key_str);
-    FURI_LOG_E("JSMM.H", "Failed to find the key in the JSON.");
+    char warning[128];
+    snprintf(warning, sizeof(warning), "Failed to find the key \"%s\" in the JSON.", key);
+    FURI_LOG_E("JSMM.H", warning);
     return NULL;
     return NULL;
 }
 }