X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=fa5b9e45de312059aed05884faf00b2da6e12c91;hb=7a8e465114815815796c2ebbe5f2e018a9265a3f;hp=fab3df37653d139a61b68d0b52aa39e09c306e5a;hpb=60ec6872a4ccb39ba9df74a77826c3bccea69006;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index fab3df37..fa5b9e45 100644 --- a/src/files.c +++ b/src/files.c @@ -9114,20 +9114,28 @@ static boolean SetRequest_ApiGetScore(struct HttpRequest *request, request->method = API_SERVER_METHOD; request->uri = API_SERVER_URI_GET; + char *levelset_identifier = getEscapedJSON(leveldir_current->identifier); + char *levelset_name = getEscapedJSON(leveldir_current->name); + snprintf(request->body, MAX_HTTP_BODY_SIZE, "{\n" "%s" " \"game_version\": \"%s\",\n" " \"game_platform\": \"%s\",\n" " \"levelset_identifier\": \"%s\",\n" + " \"levelset_name\": \"%s\",\n" " \"level_nr\": \"%d\"\n" "}\n", getPasswordJSON(setup.api_server_password), getProgramRealVersionString(), getProgramPlatformString(), - levelset.identifier, + levelset_identifier, + levelset_name, level_nr); + checked_free(levelset_identifier); + checked_free(levelset_name); + ConvertHttpRequestBodyToServerEncoding(request); return TRUE; @@ -9243,6 +9251,10 @@ static void ApiGetScore_HttpRequestExt(struct HttpRequest *request, if (!HTTP_SUCCESS(response->status_code)) { + // do not show error message if no scores found for this level set + if (response->status_code == 404) + return; + Error("server failed to handle request: %d %s", response->status_code, response->status_text); @@ -9268,12 +9280,16 @@ static int ApiGetScoreThread(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_ApiGetScore_HttpRequest(request, data_raw); #else ApiGetScore_HttpRequest(request, response, data_raw); #endif + program.api_thread_count--; + checked_free(request); checked_free(response); @@ -9429,14 +9445,31 @@ static char *get_file_base64(char *filename) return buffer_encoded; } +static void PrepareScoreTapesForUpload(char *leveldir_subdir) +{ + MarkTapeDirectoryUploadsAsIncomplete(leveldir_subdir); + + // if score tape not uploaded, ask for uploading missing tapes later + if (!setup.has_remaining_tapes) + setup.ask_for_remaining_tapes = TRUE; + + setup.provide_uploading_tapes = TRUE; + setup.has_remaining_tapes = TRUE; + + SaveSetup_ServerSetup(); +} + struct ApiAddScoreThreadData { int level_nr; + boolean tape_saved; + char *leveldir_subdir; char *score_tape_filename; struct ScoreEntry score_entry; }; -static void *CreateThreadData_ApiAddScore(int nr, char *score_tape_filename) +static void *CreateThreadData_ApiAddScore(int nr, boolean tape_saved, + char *score_tape_filename) { struct ApiAddScoreThreadData *data = checked_malloc(sizeof(struct ApiAddScoreThreadData)); @@ -9446,8 +9479,10 @@ static void *CreateThreadData_ApiAddScore(int nr, char *score_tape_filename) score_tape_filename = getScoreTapeFilename(score_entry->tape_basename, nr); data->level_nr = nr; - data->score_entry = *score_entry; + data->tape_saved = tape_saved; + data->leveldir_subdir = getStringCopy(leveldir_current->subdir); data->score_tape_filename = getStringCopy(score_tape_filename); + data->score_entry = *score_entry; return data; } @@ -9456,6 +9491,7 @@ static void FreeThreadData_ApiAddScore(void *data_raw) { struct ApiAddScoreThreadData *data = data_raw; + checked_free(data->leveldir_subdir); checked_free(data->score_tape_filename); checked_free(data); } @@ -9466,6 +9502,7 @@ static boolean SetRequest_ApiAddScore(struct HttpRequest *request, struct ApiAddScoreThreadData *data = data_raw; struct ScoreEntry *score_entry = &data->score_entry; char *score_tape_filename = data->score_tape_filename; + boolean tape_saved = data->tape_saved; int level_nr = data->level_nr; request->hostname = setup.api_server_hostname; @@ -9513,12 +9550,14 @@ static boolean SetRequest_ApiAddScore(struct HttpRequest *request, " \"level_nr\": \"%d\",\n" " \"level_name\": \"%s\",\n" " \"level_author\": \"%s\",\n" + " \"use_step_counter\": \"%d\",\n" " \"rate_time_over_score\": \"%d\",\n" " \"player_name\": \"%s\",\n" " \"player_uuid\": \"%s\",\n" " \"score\": \"%d\",\n" " \"time\": \"%d\",\n" " \"tape_basename\": \"%s\",\n" + " \"tape_saved\": \"%d\",\n" " \"tape\": \"%s\"\n" "}\n", getPasswordJSON(setup.api_server_password), @@ -9533,12 +9572,14 @@ static boolean SetRequest_ApiAddScore(struct HttpRequest *request, level_nr, level_name, level_author, + level.use_step_counter, level.rate_time_over_score, player_name, player_uuid, score_entry->score, score_entry->time, score_entry->tape_basename, + tape_saved, tape_base64); checked_free(tape_base64); @@ -9562,6 +9603,13 @@ static void HandleResponse_ApiAddScore(struct HttpResponse *response, server_scores.uploaded = TRUE; } +static void HandleFailure_ApiAddScore(void *data_raw) +{ + struct ApiAddScoreThreadData *data = data_raw; + + PrepareScoreTapesForUpload(data->leveldir_subdir); +} + #if defined(PLATFORM_EMSCRIPTEN) static void Emscripten_ApiAddScore_Loaded(unsigned handle, void *data_raw, void *buffer, unsigned int size) @@ -9577,6 +9625,8 @@ static void Emscripten_ApiAddScore_Loaded(unsigned handle, void *data_raw, else { Error("server response too large to handle (%d bytes)", size); + + HandleFailure_ApiAddScore(data_raw); } FreeThreadData_ApiAddScore(data_raw); @@ -9587,6 +9637,8 @@ static void Emscripten_ApiAddScore_Failed(unsigned handle, void *data_raw, { Error("server failed to handle request: %d %s", code, status); + HandleFailure_ApiAddScore(data_raw); + FreeThreadData_ApiAddScore(data_raw); } @@ -9629,6 +9681,8 @@ static void ApiAddScore_HttpRequestExt(struct HttpRequest *request, { Error("HTTP request failed: %s", GetHttpError()); + HandleFailure_ApiAddScore(data_raw); + return; } @@ -9638,6 +9692,8 @@ static void ApiAddScore_HttpRequestExt(struct HttpRequest *request, response->status_code, response->status_text); + HandleFailure_ApiAddScore(data_raw); + return; } @@ -9659,54 +9715,69 @@ static int ApiAddScoreThread(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_ApiAddScore_HttpRequest(request, data_raw); #else ApiAddScore_HttpRequest(request, response, data_raw); #endif + program.api_thread_count--; + checked_free(request); checked_free(response); return 0; } -static void ApiAddScoreAsThread(int nr, char *score_tape_filename) +static void ApiAddScoreAsThread(int nr, boolean tape_saved, + char *score_tape_filename) { struct ApiAddScoreThreadData *data = - CreateThreadData_ApiAddScore(nr, score_tape_filename); + CreateThreadData_ApiAddScore(nr, tape_saved, score_tape_filename); ExecuteAsThread(ApiAddScoreThread, "ApiAddScore", data, "upload score to server"); } -void SaveServerScore(int nr) +void SaveServerScore(int nr, boolean tape_saved) { if (!runtime.use_api_server) + { + PrepareScoreTapesForUpload(leveldir_current->subdir); + return; + } - ApiAddScoreAsThread(nr, NULL); + ApiAddScoreAsThread(nr, tape_saved, NULL); } -void SaveServerScoreFromFile(int nr, char *score_tape_filename) +void SaveServerScoreFromFile(int nr, boolean tape_saved, + char *score_tape_filename) { if (!runtime.use_api_server) return; - ApiAddScoreAsThread(nr, score_tape_filename); + ApiAddScoreAsThread(nr, tape_saved, score_tape_filename); } void LoadLocalAndServerScore(int nr, boolean download_score) { int last_added_local = scores.last_added_local; - LoadScore(nr); + // needed if only showing server scores + setScoreInfoToDefaults(); + + if (!strEqual(setup.scores_in_highscore_list, STR_SCORES_TYPE_SERVER_ONLY)) + LoadScore(nr); // restore last added local score entry (before merging server scores) scores.last_added = scores.last_added_local = last_added_local; - if (setup.use_api_server && !setup.only_show_local_scores) + if (setup.use_api_server && + !strEqual(setup.scores_in_highscore_list, STR_SCORES_TYPE_LOCAL_ONLY)) { // load server scores from cache file and trigger update from server LoadServerScore(nr, download_score); @@ -9907,8 +9978,8 @@ static struct TokenInfo global_setup_tokens[] = &setup.show_undo_redo_buttons, "show_undo_redo_buttons" }, { - TYPE_SWITCH, - &setup.only_show_local_scores, "only_show_local_scores" + TYPE_STRING, + &setup.scores_in_highscore_list, "scores_in_highscore_list" }, { TYPE_STRING, @@ -10030,10 +10101,22 @@ static struct TokenInfo server_setup_tokens[] = TYPE_SWITCH, &setup.ask_for_uploading_tapes, TEST_PREFIX "ask_for_uploading_tapes" }, + { + TYPE_SWITCH, + &setup.ask_for_remaining_tapes, TEST_PREFIX "ask_for_remaining_tapes" + }, { TYPE_SWITCH, &setup.provide_uploading_tapes, TEST_PREFIX "provide_uploading_tapes" }, + { + TYPE_SWITCH, + &setup.ask_for_using_api_server,TEST_PREFIX "ask_for_using_api_server" + }, + { + TYPE_SWITCH, + &setup.has_remaining_tapes, TEST_PREFIX "has_remaining_tapes" + }, }; static struct TokenInfo editor_setup_tokens[] = @@ -10603,7 +10686,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->small_game_graphics = FALSE; si->show_load_save_buttons = FALSE; si->show_undo_redo_buttons = FALSE; - si->only_show_local_scores = FALSE; + si->scores_in_highscore_list = getStringCopy(STR_SCORES_TYPE_DEFAULT); si->graphics_set = getStringCopy(GFX_CLASSIC_SUBDIR); si->sounds_set = getStringCopy(SND_CLASSIC_SUBDIR); @@ -10835,7 +10918,10 @@ static void setSetupInfoToDefaults_ServerSetup(struct SetupInfo *si) si->api_server_hostname = getStringCopy(API_SERVER_HOSTNAME); si->api_server_password = getStringCopy(UNDEFINED_PASSWORD); si->ask_for_uploading_tapes = TRUE; + si->ask_for_remaining_tapes = FALSE; si->provide_uploading_tapes = TRUE; + si->ask_for_using_api_server = TRUE; + si->has_remaining_tapes = FALSE; } static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si)