- 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);
-
- 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;
- }
-
- if (response->body_size == 0)
- {
- // no scores available for this level
-
- return;
- }
-
- ConvertHttpResponseBodyToClientEncoding(response);
-
- char *filename = 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;
-}
-
-static void ApiGetScore(int level_nr, char *score_cache_filename)
-{
- struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest));
- struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse));
-
- ApiGetScoreExt(request, response,
- level_nr, score_cache_filename);
-
- checked_free(request);
- checked_free(response);
-}
-
-static int ApiGetScoreThread(void *data_raw)
-{
- struct ApiGetScoreThreadData *data = data_raw;
-
- ApiGetScore(data->level_nr,
- data->score_cache_filename);
-
- FreeThreadData_ApiGetScore(data_raw);
-
- 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);
-}