added upgrading player UUID on score server for old UUID versions 4.3.0.3
authorHolger Schemel <info@artsoft.org>
Fri, 7 Jan 2022 00:54:50 +0000 (01:54 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 8 Jan 2022 15:54:20 +0000 (16:54 +0100)
src/files.c
src/libgame/system.h
src/screens.c
src/screens.h

index fa5b9e45de312059aed05884faf00b2da6e12c91..16fe01ed2534d0dfa10951c4499101eea65537fc 100644 (file)
@@ -10085,6 +10085,10 @@ static struct TokenInfo server_setup_tokens[] =
     TYPE_STRING,
     &setup.player_uuid,                                "player_uuid"
   },
+  {
+    TYPE_INTEGER,
+    &setup.player_version,                     "player_version"
+  },
   {
     TYPE_SWITCH,
     &setup.use_api_server,          TEST_PREFIX        "use_api_server"
@@ -10913,6 +10917,7 @@ static void setSetupInfoToDefaults_AutoSetup(struct SetupInfo *si)
 static void setSetupInfoToDefaults_ServerSetup(struct SetupInfo *si)
 {
   si->player_uuid = NULL;      // (will be set later)
+  si->player_version = 1;      // (will be set later)
 
   si->use_api_server = TRUE;
   si->api_server_hostname = getStringCopy(API_SERVER_HOSTNAME);
@@ -11275,6 +11280,7 @@ void LoadSetup_ServerSetup(void)
   {
     // player UUID does not yet exist in setup file
     setup.player_uuid = getStringCopy(getUUID());
+    setup.player_version = 2;
 
     SaveSetup_ServerSetup();
   }
index 8ad5c08f8387b2cdc8e49f0187dfb9d46958ec8c..306757a6d6ad8d92248c2ace4692fcf52b41a9fe 100644 (file)
 #define API_SERVER_URI_ADD             "/api/scores/add"
 #define API_SERVER_URI_GET             "/api/scores/get"
 #define API_SERVER_URI_RENAME          "/api/players/rename"
+#define API_SERVER_URI_RESETUUID       "/api/players/resetuuid"
 
 #if defined(TESTING)
 #undef API_SERVER_HOSTNAME
@@ -1448,6 +1449,7 @@ struct SetupInfo
 {
   char *player_name;
   char *player_uuid;
+  int player_version;
 
   boolean multiple_users;
 
index e34a9df5cad6ab396cd922fad08bc0f8c24e7297..5400958815c89125710267d08644d2093215f24e 100644 (file)
@@ -1758,8 +1758,8 @@ void DrawMainMenu(void)
 
   SyncEmscriptenFilesystem();
 
-  // needed once to upload tapes (after program start or after user change)
-  CheckUploadTapes();
+  // needed once after program start or after user change
+  CheckApiServerTasks();
 }
 
 static void gotoTopLevelDir(void)
@@ -4060,7 +4060,7 @@ void HandleInfoScreen(int mx, int my, int dx, int dy, int button)
 
 
 // ============================================================================
-// change name functions
+// rename player API functions
 // ============================================================================
 
 struct ApiRenamePlayerThreadData
@@ -4255,6 +4255,216 @@ static void ApiRenamePlayerAsThread(void)
 }
 
 
+// ============================================================================
+// reset player UUID API functions
+// ============================================================================
+
+struct ApiResetUUIDThreadData
+{
+  char *player_name;
+  char *player_uuid_old;
+  char *player_uuid_new;
+};
+
+static void *CreateThreadData_ApiResetUUID(char *uuid_new)
+{
+  struct ApiResetUUIDThreadData *data =
+    checked_malloc(sizeof(struct ApiResetUUIDThreadData));
+
+  data->player_name     = getStringCopy(setup.player_name);
+  data->player_uuid_old = getStringCopy(setup.player_uuid);
+  data->player_uuid_new = getStringCopy(uuid_new);
+
+  return data;
+}
+
+static void FreeThreadData_ApiResetUUID(void *data_raw)
+{
+  struct ApiResetUUIDThreadData *data = data_raw;
+
+  checked_free(data->player_name);
+  checked_free(data->player_uuid_old);
+  checked_free(data->player_uuid_new);
+  checked_free(data);
+}
+
+static boolean SetRequest_ApiResetUUID(struct HttpRequest *request,
+                                      void *data_raw)
+{
+  struct ApiResetUUIDThreadData *data = data_raw;
+  char *player_name_raw = data->player_name;
+  char *player_uuid_old_raw = data->player_uuid_old;
+  char *player_uuid_new_raw = data->player_uuid_new;
+
+  request->hostname = setup.api_server_hostname;
+  request->port     = API_SERVER_PORT;
+  request->method   = API_SERVER_METHOD;
+  request->uri      = API_SERVER_URI_RESETUUID;
+
+  char *player_name = getEscapedJSON(player_name_raw);
+  char *player_uuid_old = getEscapedJSON(player_uuid_old_raw);
+  char *player_uuid_new = getEscapedJSON(player_uuid_new_raw);
+
+  snprintf(request->body, MAX_HTTP_BODY_SIZE,
+          "{\n"
+          "%s"
+          "  \"game_version\":         \"%s\",\n"
+          "  \"game_platform\":        \"%s\",\n"
+          "  \"name\":                 \"%s\",\n"
+          "  \"uuid_old\":             \"%s\",\n"
+          "  \"uuid_new\":             \"%s\"\n"
+          "}\n",
+          getPasswordJSON(setup.api_server_password),
+          getProgramRealVersionString(),
+          getProgramPlatformString(),
+          player_name,
+          player_uuid_old,
+          player_uuid_new);
+
+  checked_free(player_name);
+  checked_free(player_uuid_old);
+  checked_free(player_uuid_new);
+
+  ConvertHttpRequestBodyToServerEncoding(request);
+
+  return TRUE;
+}
+
+static void HandleResponse_ApiResetUUID(struct HttpResponse *response,
+                                       void *data_raw)
+{
+  struct ApiResetUUIDThreadData *data = data_raw;
+
+  // upgrade player UUID in server setup file
+  setup.player_uuid = getStringCopy(data->player_uuid_new);
+  setup.player_version = 2;
+
+  SaveSetup_ServerSetup();
+}
+
+#if defined(PLATFORM_EMSCRIPTEN)
+static void Emscripten_ApiResetUUID_Loaded(unsigned handle, void *data_raw,
+                                          void *buffer, unsigned int size)
+{
+  struct HttpResponse *response = GetHttpResponseFromBuffer(buffer, size);
+
+  if (response != NULL)
+  {
+    HandleResponse_ApiResetUUID(response, data_raw);
+
+    checked_free(response);
+  }
+  else
+  {
+    Error("server response too large to handle (%d bytes)", size);
+  }
+
+  FreeThreadData_ApiResetUUID(data_raw);
+}
+
+static void Emscripten_ApiResetUUID_Failed(unsigned handle, void *data_raw,
+                                          int code, const char *status)
+{
+  Error("server failed to handle request: %d %s", code, status);
+
+  FreeThreadData_ApiResetUUID(data_raw);
+}
+
+static void Emscripten_ApiResetUUID_Progress(unsigned handle, void *data_raw,
+                                            int bytes, int size)
+{
+  // nothing to do here
+}
+
+static void Emscripten_ApiResetUUID_HttpRequest(struct HttpRequest *request,
+                                               void *data_raw)
+{
+  if (!SetRequest_ApiResetUUID(request, data_raw))
+  {
+    FreeThreadData_ApiResetUUID(data_raw);
+
+    return;
+  }
+
+  emscripten_async_wget2_data(request->uri,
+                             request->method,
+                             request->body,
+                             data_raw,
+                             TRUE,
+                             Emscripten_ApiResetUUID_Loaded,
+                             Emscripten_ApiResetUUID_Failed,
+                             Emscripten_ApiResetUUID_Progress);
+}
+
+#else
+
+static void ApiResetUUID_HttpRequestExt(struct HttpRequest *request,
+                                       struct HttpResponse *response,
+                                       void *data_raw)
+{
+  if (!SetRequest_ApiResetUUID(request, data_raw))
+    return;
+
+  if (!DoHttpRequest(request, response))
+  {
+    Error("HTTP request failed: %s", GetHttpError());
+
+    return;
+  }
+
+  if (!HTTP_SUCCESS(response->status_code))
+  {
+    Error("server failed to handle request: %d %s",
+         response->status_code,
+         response->status_text);
+
+    return;
+  }
+
+  HandleResponse_ApiResetUUID(response, data_raw);
+}
+
+static void ApiResetUUID_HttpRequest(struct HttpRequest *request,
+                                    struct HttpResponse *response,
+                                    void *data_raw)
+{
+  ApiResetUUID_HttpRequestExt(request, response, data_raw);
+
+  FreeThreadData_ApiResetUUID(data_raw);
+}
+#endif
+
+static int ApiResetUUIDThread(void *data_raw)
+{
+  struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest));
+  struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse));
+
+  program.api_thread_count++;
+
+#if defined(PLATFORM_EMSCRIPTEN)
+  Emscripten_ApiResetUUID_HttpRequest(request, data_raw);
+#else
+  ApiResetUUID_HttpRequest(request, response, data_raw);
+#endif
+
+  program.api_thread_count--;
+
+  checked_free(request);
+  checked_free(response);
+
+  return 0;
+}
+
+static void ApiResetUUIDAsThread(char *uuid_new)
+{
+  struct ApiResetUUIDThreadData *data = CreateThreadData_ApiResetUUID(uuid_new);
+
+  ExecuteAsThread(ApiResetUUIDThread,
+                 "ApiResetUUID", data,
+                 "reset UUID on server");
+}
+
+
 // ============================================================================
 // type name functions
 // ============================================================================
@@ -6911,6 +7121,17 @@ static void ToggleGameSpeedsListIfNeeded(void)
   DrawSetupScreen();
 }
 
+static void ToggleUseApiServerIfNeeded(void)
+{
+  if (runtime.use_api_server == setup.use_api_server)
+    return;
+
+  runtime.use_api_server = setup.use_api_server;
+
+  if (runtime.use_api_server)
+    CheckApiServerTasks();
+}
+
 static void ModifyGameSpeedIfNeeded(void)
 {
   if (strEqual(setup.vsync_mode, STR_VSYNC_MODE_OFF) ||
@@ -7681,7 +7902,7 @@ static void changeSetupValue(int screen_pos, int setup_info_pos_raw, int dx)
 
   // API server mode may have changed at this point
   if (si->value == &setup.use_api_server)
-    runtime.use_api_server = setup.use_api_server;
+    ToggleUseApiServerIfNeeded();
 
   // game speed list may have changed at this point
   if (si->value == &setup.game_speed_extended)
@@ -10124,7 +10345,7 @@ static boolean OfferUploadTapes(void)
   return TRUE;
 }
 
-void CheckUploadTapes(void)
+static void CheckUploadTapes(void)
 {
   if (!setup.ask_for_uploading_tapes)
     return;
@@ -10153,3 +10374,25 @@ void CheckUploadTapes(void)
 
   SaveSetup_ServerSetup();
 }
+
+static void UpgradePlayerUUID(void)
+{
+  ApiResetUUIDAsThread(getUUID());
+}
+
+static void CheckUpgradePlayerUUID(void)
+{
+  if (setup.player_version > 1)
+    return;
+
+  UpgradePlayerUUID();
+}
+
+void CheckApiServerTasks(void)
+{
+  // check if the player's UUID has to be upgraded
+  CheckUpgradePlayerUUID();
+
+  // check if there are any tapes to be uploaded
+  CheckUploadTapes();
+}
index 3d5a1316b1ed78c4580b6272571c2b8f034f274a..0694a59af84119aa5832e88bca48000466956ccd 100644 (file)
@@ -47,6 +47,6 @@ void setHideRelatedSetupEntries(void);
 void DumpScreenIdentifiers(void);
 boolean DoScreenAction(int);
 
-void CheckUploadTapes(void);
+void CheckApiServerTasks(void);
 
 #endif // SCREENS_H