improved error handling when uploading tapes to server
[rocksndiamonds.git] / src / screens.c
index 54c03fde2eaf02edcd7df9b68fd47447c33f2c38..339b8b6c593cc3dfe4bef7c7c64affc9a91bcf5a 100644 (file)
@@ -2232,9 +2232,13 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
        SaveLevelSetup_LastSeries();
        SaveLevelSetup_SeriesInfo();
 
+#if defined(PLATFORM_EMSCRIPTEN)
+       Request("Close the browser window to quit!", REQ_CONFIRM);
+#else
        if (!setup.ask_on_quit_program ||
            Request("Do you really want to quit?", REQ_ASK | REQ_STAY_CLOSED))
          SetGameStatus(GAME_MODE_QUIT);
+#endif
       }
     }
   }
@@ -4042,11 +4046,39 @@ void HandleInfoScreen(int mx, int my, int dx, int dy, int button)
 // change name functions
 // ============================================================================
 
-static void RenamePlayerOnServerExt(struct HttpRequest *request,
-                                   struct HttpResponse *response,
-                                   char *player_name_raw,
-                                   char *player_uuid_raw)
+struct ApiRenamePlayerThreadData
+{
+  char *player_name;
+  char *player_uuid;
+};
+
+static void *CreateThreadData_ApiRenamePlayer(void)
+{
+  struct ApiRenamePlayerThreadData *data =
+    checked_malloc(sizeof(struct ApiRenamePlayerThreadData));
+
+  data->player_name = getStringCopy(setup.player_name);
+  data->player_uuid = getStringCopy(setup.player_uuid);
+
+  return data;
+}
+
+static void FreeThreadData_ApiRenamePlayer(void *data_raw)
+{
+  struct ApiRenamePlayerThreadData *data = data_raw;
+
+  checked_free(data->player_name);
+  checked_free(data->player_uuid);
+  checked_free(data);
+}
+
+static boolean SetRequest_ApiRenamePlayer(struct HttpRequest *request,
+                                         void *data_raw)
 {
+  struct ApiRenamePlayerThreadData *data = data_raw;
+  char *player_name_raw = data->player_name;
+  char *player_uuid_raw = data->player_uuid;
+
   request->hostname = setup.api_server_hostname;
   request->port     = API_SERVER_PORT;
   request->method   = API_SERVER_METHOD;
@@ -4059,11 +4091,13 @@ static void RenamePlayerOnServerExt(struct HttpRequest *request,
           "{\n"
           "%s"
           "  \"game_version\":         \"%s\",\n"
+          "  \"game_platform\":        \"%s\",\n"
           "  \"name\":                 \"%s\",\n"
           "  \"uuid\":                 \"%s\"\n"
           "}\n",
           getPasswordJSON(setup.api_server_password),
           getProgramRealVersionString(),
+          getProgramPlatformString(),
           player_name,
           player_uuid);
 
@@ -4072,6 +4106,78 @@ static void RenamePlayerOnServerExt(struct HttpRequest *request,
 
   ConvertHttpRequestBodyToServerEncoding(request);
 
+  return TRUE;
+}
+
+static void HandleResponse_ApiRenamePlayer(struct HttpResponse *response,
+                                          void *data_raw)
+{
+  // nothing to do here
+}
+
+#if defined(PLATFORM_EMSCRIPTEN)
+static void Emscripten_ApiRenamePlayer_Loaded(unsigned handle, void *data_raw,
+                                             void *buffer, unsigned int size)
+{
+  struct HttpResponse *response = GetHttpResponseFromBuffer(buffer, size);
+
+  if (response != NULL)
+  {
+    HandleResponse_ApiRenamePlayer(response, data_raw);
+
+    checked_free(response);
+  }
+  else
+  {
+    Error("server response too large to handle (%d bytes)", size);
+  }
+
+  FreeThreadData_ApiRenamePlayer(data_raw);
+}
+
+static void Emscripten_ApiRenamePlayer_Failed(unsigned handle, void *data_raw,
+                                             int code, const char *status)
+{
+  Error("server failed to handle request: %d %s", code, status);
+
+  FreeThreadData_ApiRenamePlayer(data_raw);
+}
+
+static void Emscripten_ApiRenamePlayer_Progress(unsigned handle, void *data_raw,
+                                               int bytes, int size)
+{
+  // nothing to do here
+}
+
+static void Emscripten_ApiRenamePlayer_HttpRequest(struct HttpRequest *request,
+                                                  void *data_raw)
+{
+  if (!SetRequest_ApiRenamePlayer(request, data_raw))
+  {
+    FreeThreadData_ApiRenamePlayer(data_raw);
+
+    return;
+  }
+
+  emscripten_async_wget2_data(request->uri,
+                             request->method,
+                             request->body,
+                             data_raw,
+                             TRUE,
+                             Emscripten_ApiRenamePlayer_Loaded,
+                             Emscripten_ApiRenamePlayer_Failed,
+                             Emscripten_ApiRenamePlayer_Progress);
+}
+
+#else
+
+static void ApiRenamePlayer_HttpRequestExt(struct HttpRequest *request,
+                                          struct HttpResponse *response,
+                                          void *data_raw)
+{
+  if (!SetRequest_ApiRenamePlayer(request, data_raw))
+    return;
+
   if (!DoHttpRequest(request, response))
   {
     Error("HTTP request failed: %s", GetHttpError());
@@ -4087,48 +4193,43 @@ static void RenamePlayerOnServerExt(struct HttpRequest *request,
 
     return;
   }
+
+  HandleResponse_ApiRenamePlayer(response, data_raw);
 }
 
-static void RenamePlayerOnServer(char *player_name, char *player_uuid)
+static void ApiRenamePlayer_HttpRequest(struct HttpRequest *request,
+                                   struct HttpResponse *response,
+                                   void *data_raw)
 {
-  struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest));
-  struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse));
+  ApiRenamePlayer_HttpRequestExt(request, response, data_raw);
 
-  RenamePlayerOnServerExt(request, response, player_name, player_uuid);
-
-  checked_free(request);
-  checked_free(response);
+  FreeThreadData_ApiRenamePlayer(data_raw);
 }
+#endif
 
-struct RenamePlayerOnServerThreadData
-{
-  char *player_name;
-  char *player_uuid;
-};
-
-static int RenamePlayerOnServerThread(void *data_raw)
+static int ApiRenamePlayerThread(void *data_raw)
 {
-  struct RenamePlayerOnServerThreadData *data = data_raw;
+  struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest));
+  struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse));
 
-  RenamePlayerOnServer(data->player_name, data->player_uuid);
+#if defined(PLATFORM_EMSCRIPTEN)
+  Emscripten_ApiRenamePlayer_HttpRequest(request, data_raw);
+#else
+  ApiRenamePlayer_HttpRequest(request, response, data_raw);
+#endif
 
-  checked_free(data->player_name);
-  checked_free(data->player_uuid);
-  checked_free(data);
+  checked_free(request);
+  checked_free(response);
 
   return 0;
 }
 
-static void RenamePlayerOnServerAsThread(void)
+static void ApiRenamePlayerAsThread(void)
 {
-  struct RenamePlayerOnServerThreadData *data =
-    checked_malloc(sizeof(struct RenamePlayerOnServerThreadData));
-
-  data->player_name = getStringCopy(setup.player_name);
-  data->player_uuid = getStringCopy(setup.player_uuid);
+  struct ApiRenamePlayerThreadData *data = CreateThreadData_ApiRenamePlayer();
 
-  ExecuteAsThread(RenamePlayerOnServerThread,
-                 "RenamePlayerOnServer", data,
+  ExecuteAsThread(ApiRenamePlayerThread,
+                 "ApiRenamePlayer", data,
                  "rename player on server");
 }
 
@@ -4255,10 +4356,17 @@ static void setTypeNameValues(char *name, struct TextPosInfo *pos,
     // temporarily change active user to edited user
     user.nr = type_name_nr;
 
-    // load setup of edited user (unless creating user with current setup)
-    if (!create_user ||
-       !Request("Use current setup values for the new player?", REQ_ASK))
+    if (create_user &&
+        Request("Use current setup values for the new player?", REQ_ASK))
+    {
+      // use current setup values for new user, but create new player UUID
+      setup.player_uuid = getStringCopy(getUUID());
+    }
+    else
+    {
+      // load setup for existing user (or start with defaults for new user)
       LoadSetup();
+    }
   }
 
   char *setup_filename = getSetupFilename();
@@ -4271,7 +4379,7 @@ static void setTypeNameValues(char *name, struct TextPosInfo *pos,
   SaveSetup();
 
   // change name of edited user on score server
-  RenamePlayerOnServerAsThread();
+  ApiRenamePlayerAsThread();
 
   if (game_status == GAME_MODE_PSEUDO_TYPENAMES || reset_setup)
   {
@@ -9879,7 +9987,19 @@ static boolean OfferUploadTapes(void)
   int num_tapes_uploaded = UploadTapes();
   char message[100];
 
-  sprintf(message, "%d tapes uploaded!", num_tapes_uploaded);
+  if (num_tapes_uploaded < 0)
+  {
+    Request("Cannot upload tapes to score server!", REQ_CONFIRM);
+
+    return FALSE;
+  }
+
+  if (num_tapes_uploaded == 0)
+    sprintf(message, "No tapes uploaded!");
+  else if (num_tapes_uploaded == 1)
+    sprintf(message, "1 tape uploaded!");
+  else
+    sprintf(message, "%d tapes uploaded!", num_tapes_uploaded);
 
   Request(message, REQ_CONFIRM);
 
@@ -9888,7 +10008,7 @@ static boolean OfferUploadTapes(void)
 
   SaveSetup();
 
-  return (num_tapes_uploaded > 0);
+  return TRUE;
 }
 
 void CheckUploadTapes(void)