- request->hostname = setup.api_server_hostname;
- request->port = API_SERVER_PORT;
- request->method = API_SERVER_METHOD;
- request->uri = API_SERVER_URI_GET;
-
- snprintf(request->body, MAX_HTTP_BODY_SIZE,
- "{\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(),
- getProgramPlatformString(),
- levelset.identifier,
- level_nr);
-
- ConvertHttpRequestBodyToServerEncoding(request);
-
- return TRUE;
-}
-
-static void HandleResponse_ApiGetScore(struct HttpResponse *response,
- void *data_raw)
-{
- struct ApiGetScoreThreadData *data = data_raw;
-
- if (response->body_size == 0)
- {
- // no scores available for this level
-
- return;
- }
-
- ConvertHttpResponseBodyToClientEncoding(response);
-
- char *filename = data->score_cache_filename;
- FILE *file;
- int i;
-
- // used instead of "leveldir_current->subdir" (for network games)
- InitScoreCacheDirectory(levelset.identifier);
-
- if (!(file = fopen(filename, MODE_WRITE)))
- {
- Warn("cannot save score cache file '%s'", filename);
-
- return;
- }
-
- for (i = 0; i < response->body_size; i++)
- fputc(response->body[i], file);
-
- fclose(file);
-
- SetFilePermissions(filename, PERMS_PRIVATE);
-
- server_scores.updated = TRUE;
-}
-
-#if defined(PLATFORM_EMSCRIPTEN)
-static void Emscripten_ApiGetScore_Loaded(unsigned handle, void *data_raw,
- void *buffer, unsigned int size)
-{
- struct HttpResponse *response = GetHttpResponseFromBuffer(buffer, size);
-
- if (response != NULL)
- {
- HandleResponse_ApiGetScore(response, data_raw);
-
- checked_free(response);
- }
- else
- {
- Error("server response too large to handle (%d bytes)", size);
- }
-
- FreeThreadData_ApiGetScore(data_raw);
-}
-
-static void Emscripten_ApiGetScore_Failed(unsigned handle, void *data_raw,
- int code, const char *status)
-{
- Error("server failed to handle request: %d %s", code, status);
-
- FreeThreadData_ApiGetScore(data_raw);
-}
-
-static void Emscripten_ApiGetScore_Progress(unsigned handle, void *data_raw,
- int bytes, int size)
-{
- // nothing to do here
-}
-
-static void Emscripten_ApiGetScore_HttpRequest(struct HttpRequest *request,
- void *data_raw)
-{
- if (!SetRequest_ApiGetScore(request, data_raw))
- {
- FreeThreadData_ApiGetScore(data_raw);
-
- return;
- }
-
- emscripten_async_wget2_data(request->uri,
- request->method,
- request->body,
- data_raw,
- TRUE,
- Emscripten_ApiGetScore_Loaded,
- Emscripten_ApiGetScore_Failed,
- Emscripten_ApiGetScore_Progress);
-}
-
-#else
-
-static void ApiGetScore_HttpRequestExt(struct HttpRequest *request,
- struct HttpResponse *response,
- void *data_raw)
-{
- if (!SetRequest_ApiGetScore(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_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);
-
- return 0;
-}
-
-static void ApiGetScoreAsThread(int nr)
-{
- struct ApiGetScoreThreadData *data = CreateThreadData_ApiGetScore(nr);
-
- ExecuteAsThread(ApiGetScoreThread,
- "ApiGetScore", data,
- "download scores from server");
-}
-
-static void LoadServerScoreFromCache(int nr)
-{
- struct ScoreEntry score_entry;
- struct
- {
- void *value;
- boolean is_string;
- int string_size;
- }
- score_mapping[] =
- {
- { &score_entry.score, FALSE, 0 },
- { &score_entry.time, FALSE, 0 },
- { score_entry.name, TRUE, MAX_PLAYER_NAME_LEN },
- { score_entry.tape_basename, TRUE, MAX_FILENAME_LEN },
-
- { NULL, FALSE, 0 }
- };
- char *filename = getScoreCacheFilename(nr);
- SetupFileHash *score_hash = loadSetupFileHash(filename);
- int i, j;
-
- server_scores.num_entries = 0;
-
- if (score_hash == NULL)
- return;
-
- for (i = 0; i < MAX_SCORE_ENTRIES; i++)
- {
- score_entry = server_scores.entry[i];
-
- for (j = 0; score_mapping[j].value != NULL; j++)
- {
- char token[10];
-
- sprintf(token, "%02d.%d", i, j);
-
- char *value = getHashEntry(score_hash, token);
-
- if (value == NULL)
- continue;
-
- if (score_mapping[j].is_string)
- {
- char *score_value = (char *)score_mapping[j].value;
- int value_size = score_mapping[j].string_size;
-
- strncpy(score_value, value, value_size);
- score_value[value_size] = '\0';
- }
- else
- {
- int *score_value = (int *)score_mapping[j].value;
-
- *score_value = atoi(value);
- }
-
- server_scores.num_entries = i + 1;
- }
-
- server_scores.entry[i] = score_entry;
- }
-
- freeSetupFileHash(score_hash);
-}