X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=d6c9b5733668fe966c88d957568c9c9516720ad0;hb=bcb1d6118c2d3484e1881a78fd859562745aa553;hp=468473e3ab1d4312ba055cb2efbbad2fa4048124;hpb=a1058e2a13f1132331a123b735bdeb90cbc9af03;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 468473e3..d6c9b573 100644 --- a/src/files.c +++ b/src/files.c @@ -9032,6 +9032,10 @@ void SaveScore(int nr) void ExecuteAsThread(SDL_ThreadFunction function, char *name, void *data, char *error) { +#if defined(PLATFORM_EMSCRIPTEN) + // threads currently not fully supported by Emscripten/SDL and some browsers + function(data); +#else SDL_Thread *thread = SDL_CreateThread(function, name, data); if (thread != NULL) @@ -9041,6 +9045,7 @@ void ExecuteAsThread(SDL_ThreadFunction function, char *name, void *data, // nasty kludge to lower probability of intermingled thread error messages Delay(1); +#endif } char *getPasswordJSON(char *password) @@ -9063,11 +9068,38 @@ char *getPasswordJSON(char *password) return password_json; } -static void DownloadServerScoreToCacheExt(struct HttpRequest *request, - struct HttpResponse *response, - int level_nr, - char *score_cache_filename) +struct ApiGetScoreThreadData +{ + int level_nr; + char *score_cache_filename; +}; + +static void *CreateThreadData_ApiGetScore(int nr) +{ + struct ApiGetScoreThreadData *data = + checked_malloc(sizeof(struct ApiGetScoreThreadData)); + char *score_cache_filename = getScoreCacheFilename(nr); + + data->level_nr = nr; + data->score_cache_filename = getStringCopy(score_cache_filename); + + return data; +} + +static void FreeThreadData_ApiGetScore(void *data_raw) +{ + struct ApiGetScoreThreadData *data = data_raw; + + checked_free(data->score_cache_filename); + checked_free(data); +} + +static boolean SetRequest_ApiGetScore(struct HttpRequest *request, + void *data_raw) { + struct ApiGetScoreThreadData *data = data_raw; + int level_nr = data->level_nr; + request->hostname = setup.api_server_hostname; request->port = API_SERVER_PORT; request->method = API_SERVER_METHOD; @@ -9077,30 +9109,25 @@ static void DownloadServerScoreToCacheExt(struct HttpRequest *request, "{\n" "%s" " \"game_version\": \"%s\",\n" + " \"game_platform\": \"%s\",\n" " \"levelset_identifier\": \"%s\",\n" " \"level_nr\": \"%d\"\n" "}\n", getPasswordJSON(setup.api_server_password), getProgramRealVersionString(), - levelset.identifier, level_nr); + getProgramPlatformString(), + levelset.identifier, + level_nr); ConvertHttpRequestBodyToServerEncoding(request); - 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 TRUE; +} - return; - } +static void HandleResponse_ApiGetScore(struct HttpResponse *response, + void *data_raw) +{ + struct ApiGetScoreThreadData *data = data_raw; if (response->body_size == 0) { @@ -9111,7 +9138,7 @@ static void DownloadServerScoreToCacheExt(struct HttpRequest *request, ConvertHttpResponseBodyToClientEncoding(response); - char *filename = score_cache_filename; + char *filename = data->score_cache_filename; FILE *file; int i; @@ -9135,48 +9162,121 @@ static void DownloadServerScoreToCacheExt(struct HttpRequest *request, server_scores.updated = TRUE; } -static void DownloadServerScoreToCache(int level_nr, char *score_cache_filename) +#if defined(PLATFORM_EMSCRIPTEN) +static void Emscripten_ApiGetScore_Loaded(unsigned handle, void *data_raw, + void *buffer, unsigned int size) { - struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest)); - struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse)); + struct HttpResponse *response = GetHttpResponseFromBuffer(buffer, size); - DownloadServerScoreToCacheExt(request, response, - level_nr, score_cache_filename); + if (response != NULL) + { + HandleResponse_ApiGetScore(response, data_raw); - checked_free(request); - checked_free(response); + checked_free(response); + } + else + { + Error("server response too large to handle (%d bytes)", size); + } + + FreeThreadData_ApiGetScore(data_raw); } -struct DownloadServerScoreToCacheThreadData +static void Emscripten_ApiGetScore_Failed(unsigned handle, void *data_raw, + int code, const char *status) { - int level_nr; - char *score_cache_filename; -}; + Error("server failed to handle request: %d %s", code, status); + + FreeThreadData_ApiGetScore(data_raw); +} -static int DownloadServerScoreToCacheThread(void *data_raw) +static void Emscripten_ApiGetScore_Progress(unsigned handle, void *data_raw, + int bytes, int size) { - struct DownloadServerScoreToCacheThreadData *data = data_raw; + // nothing to do here +} - DownloadServerScoreToCache(data->level_nr, - data->score_cache_filename); +static void Emscripten_ApiGetScore_HttpRequest(struct HttpRequest *request, + void *data_raw) +{ + if (!SetRequest_ApiGetScore(request, data_raw)) + { + FreeThreadData_ApiGetScore(data_raw); - checked_free(data->score_cache_filename); - checked_free(data); + return; + } - return 0; + emscripten_async_wget2_data(request->uri, + request->method, + request->body, + data_raw, + TRUE, + Emscripten_ApiGetScore_Loaded, + Emscripten_ApiGetScore_Failed, + Emscripten_ApiGetScore_Progress); } -static void DownloadServerScoreToCacheAsThread(int nr) +#else + +static void ApiGetScore_HttpRequestExt(struct HttpRequest *request, + struct HttpResponse *response, + void *data_raw) { - struct DownloadServerScoreToCacheThreadData *data = - checked_malloc(sizeof(struct DownloadServerScoreToCacheThreadData)); - char *score_cache_filename = getScoreCacheFilename(nr); + if (!SetRequest_ApiGetScore(request, data_raw)) + return; - data->level_nr = nr; - data->score_cache_filename = getStringCopy(score_cache_filename); + 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_ApiGetScore(response, data_raw); +} + +static void ApiGetScore_HttpRequest(struct HttpRequest *request, + struct HttpResponse *response, + void *data_raw) +{ + ApiGetScore_HttpRequestExt(request, response, data_raw); + + FreeThreadData_ApiGetScore(data_raw); +} +#endif + +static int ApiGetScoreThread(void *data_raw) +{ + struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest)); + struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse)); + +#if defined(PLATFORM_EMSCRIPTEN) + Emscripten_ApiGetScore_HttpRequest(request, data_raw); +#else + ApiGetScore_HttpRequest(request, response, data_raw); +#endif + + checked_free(request); + checked_free(response); - ExecuteAsThread(DownloadServerScoreToCacheThread, - "DownloadServerScoreToCache", data, + return 0; +} + +static void ApiGetScoreAsThread(int nr) +{ + struct ApiGetScoreThreadData *data = CreateThreadData_ApiGetScore(nr); + + ExecuteAsThread(ApiGetScoreThread, + "ApiGetScore", data, "download scores from server"); } @@ -9262,7 +9362,7 @@ void LoadServerScore(int nr, boolean download_score) { // 2nd step: download server scores from score server to cache file // (as thread, as it might time out if the server is not reachable) - DownloadServerScoreToCacheAsThread(nr); + ApiGetScoreAsThread(nr); } } @@ -9320,12 +9420,45 @@ static char *get_file_base64(char *filename) return buffer_encoded; } -static void UploadScoreToServerExt(struct HttpRequest *request, - struct HttpResponse *response, - int level_nr, - char *score_tape_filename, - struct ScoreEntry *score_entry) +struct ApiAddScoreThreadData +{ + int level_nr; + char *score_tape_filename; + struct ScoreEntry score_entry; +}; + +static void *CreateThreadData_ApiAddScore(int nr, char *score_tape_filename) +{ + struct ApiAddScoreThreadData *data = + checked_malloc(sizeof(struct ApiAddScoreThreadData)); + struct ScoreEntry *score_entry = &scores.entry[scores.last_added]; + + if (score_tape_filename == NULL) + score_tape_filename = getScoreTapeFilename(score_entry->tape_basename, nr); + + data->level_nr = nr; + data->score_entry = *score_entry; + data->score_tape_filename = getStringCopy(score_tape_filename); + + return data; +} + +static void FreeThreadData_ApiAddScore(void *data_raw) +{ + struct ApiAddScoreThreadData *data = data_raw; + + checked_free(data->score_tape_filename); + checked_free(data); +} + +static boolean SetRequest_ApiAddScore(struct HttpRequest *request, + void *data_raw) { + struct ApiAddScoreThreadData *data = data_raw; + struct ScoreEntry *score_entry = &data->score_entry; + char *score_tape_filename = data->score_tape_filename; + int level_nr = data->level_nr; + request->hostname = setup.api_server_hostname; request->port = API_SERVER_PORT; request->method = API_SERVER_METHOD; @@ -9337,7 +9470,7 @@ static void UploadScoreToServerExt(struct HttpRequest *request, { Error("loading and base64 encoding score tape file failed"); - return; + return FALSE; } char *player_name_raw = score_entry->name; @@ -9361,6 +9494,7 @@ static void UploadScoreToServerExt(struct HttpRequest *request, "{\n" "%s" " \"game_version\": \"%s\",\n" + " \"game_platform\": \"%s\",\n" " \"batch_time\": \"%d\",\n" " \"levelset_identifier\": \"%s\",\n" " \"levelset_name\": \"%s\",\n" @@ -9380,6 +9514,7 @@ static void UploadScoreToServerExt(struct HttpRequest *request, "}\n", getPasswordJSON(setup.api_server_password), getProgramRealVersionString(), + getProgramPlatformString(), (int)global.autoplay_time, levelset_identifier, levelset_name, @@ -9409,6 +9544,78 @@ static void UploadScoreToServerExt(struct HttpRequest *request, ConvertHttpRequestBodyToServerEncoding(request); + return TRUE; +} + +static void HandleResponse_ApiAddScore(struct HttpResponse *response, + void *data_raw) +{ + server_scores.uploaded = TRUE; +} + +#if defined(PLATFORM_EMSCRIPTEN) +static void Emscripten_ApiAddScore_Loaded(unsigned handle, void *data_raw, + void *buffer, unsigned int size) +{ + struct HttpResponse *response = GetHttpResponseFromBuffer(buffer, size); + + if (response != NULL) + { + HandleResponse_ApiAddScore(response, data_raw); + + checked_free(response); + } + else + { + Error("server response too large to handle (%d bytes)", size); + } + + FreeThreadData_ApiAddScore(data_raw); +} + +static void Emscripten_ApiAddScore_Failed(unsigned handle, void *data_raw, + int code, const char *status) +{ + Error("server failed to handle request: %d %s", code, status); + + FreeThreadData_ApiAddScore(data_raw); +} + +static void Emscripten_ApiAddScore_Progress(unsigned handle, void *data_raw, + int bytes, int size) +{ + // nothing to do here +} + +static void Emscripten_ApiAddScore_HttpRequest(struct HttpRequest *request, + void *data_raw) +{ + if (!SetRequest_ApiAddScore(request, data_raw)) + { + FreeThreadData_ApiAddScore(data_raw); + + return; + } + + emscripten_async_wget2_data(request->uri, + request->method, + request->body, + data_raw, + TRUE, + Emscripten_ApiAddScore_Loaded, + Emscripten_ApiAddScore_Failed, + Emscripten_ApiAddScore_Progress); +} + +#else + +static void ApiAddScore_HttpRequestExt(struct HttpRequest *request, + struct HttpResponse *response, + void *data_raw) +{ + if (!SetRequest_ApiAddScore(request, data_raw)) + return; + if (!DoHttpRequest(request, response)) { Error("HTTP request failed: %s", GetHttpError()); @@ -9425,58 +9632,43 @@ static void UploadScoreToServerExt(struct HttpRequest *request, return; } - server_scores.uploaded = TRUE; + HandleResponse_ApiAddScore(response, data_raw); } -static void UploadScoreToServer(int level_nr, char *score_tape_filename, - struct ScoreEntry *score_entry) +static void ApiAddScore_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)); - - UploadScoreToServerExt(request, response, - level_nr, score_tape_filename, score_entry); + ApiAddScore_HttpRequestExt(request, response, data_raw); - checked_free(request); - checked_free(response); + FreeThreadData_ApiAddScore(data_raw); } +#endif -struct UploadScoreToServerThreadData -{ - int level_nr; - char *score_tape_filename; - struct ScoreEntry score_entry; -}; - -static int UploadScoreToServerThread(void *data_raw) +static int ApiAddScoreThread(void *data_raw) { - struct UploadScoreToServerThreadData *data = data_raw; + struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest)); + struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse)); - UploadScoreToServer(data->level_nr, - data->score_tape_filename, - &data->score_entry); +#if defined(PLATFORM_EMSCRIPTEN) + Emscripten_ApiAddScore_HttpRequest(request, data_raw); +#else + ApiAddScore_HttpRequest(request, response, data_raw); +#endif - checked_free(data->score_tape_filename); - checked_free(data); + checked_free(request); + checked_free(response); return 0; } -static void UploadScoreToServerAsThread(int nr, char *score_tape_filename) +static void ApiAddScoreAsThread(int nr, char *score_tape_filename) { - struct UploadScoreToServerThreadData *data = - checked_malloc(sizeof(struct UploadScoreToServerThreadData)); - struct ScoreEntry *score_entry = &scores.entry[scores.last_added]; - - if (score_tape_filename == NULL) - score_tape_filename = getScoreTapeFilename(score_entry->tape_basename, nr); - - data->level_nr = nr; - data->score_entry = *score_entry; - data->score_tape_filename = getStringCopy(score_tape_filename); + struct ApiAddScoreThreadData *data = + CreateThreadData_ApiAddScore(nr, score_tape_filename); - ExecuteAsThread(UploadScoreToServerThread, - "UploadScoreToServer", data, + ExecuteAsThread(ApiAddScoreThread, + "ApiAddScore", data, "upload score to server"); } @@ -9485,7 +9677,7 @@ void SaveServerScore(int nr) if (!runtime.use_api_server) return; - UploadScoreToServerAsThread(nr, NULL); + ApiAddScoreAsThread(nr, NULL); } void SaveServerScoreFromFile(int nr, char *score_tape_filename) @@ -9493,7 +9685,7 @@ void SaveServerScoreFromFile(int nr, char *score_tape_filename) if (!runtime.use_api_server) return; - UploadScoreToServerAsThread(nr, score_tape_filename); + ApiAddScoreAsThread(nr, score_tape_filename); } void LoadLocalAndServerScore(int nr, boolean download_score)