X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=eab833048a1e18811c6e040928080818497ca9b1;hb=8a2470395f5f3701811ff2da6907c9a4dc95d285;hp=ab6a595876440efa5e72d350130cf8ced12b4b30;hpb=2eb60cf4c36db6802cb11c8eadd9b2c5a0e5fd1c;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index ab6a5958..eab83304 100644 --- a/src/files.c +++ b/src/files.c @@ -8899,6 +8899,144 @@ void SaveScore(int nr) SaveScoreToFilename(filename); } +static char *get_file_base64(char *filename) +{ + struct stat file_status; + + if (stat(filename, &file_status) != 0) + { + Error("cannot stat file '%s'\n", filename); + + return NULL; + } + + int buffer_size = file_status.st_size; + byte *buffer = checked_malloc(buffer_size); + FILE *file; + int i; + + if (!(file = fopen(filename, MODE_READ))) + { + Error("cannot open file '%s'\n", filename); + + checked_free(buffer); + + return NULL; + } + + for (i = 0; i < buffer_size; i++) + { + int c = fgetc(file); + + if (c == EOF) + { + Error("cannot read from input file '%s'\n", filename); + + fclose(file); + checked_free(buffer); + + return NULL; + } + + buffer[i] = (byte)c; + } + + fclose(file); + + int buffer_encoded_size = base64_encoded_size(buffer_size); + char *buffer_encoded = checked_malloc(buffer_encoded_size); + + base64_encode(buffer_encoded, buffer, buffer_size); + + checked_free(buffer); + + return buffer_encoded; +} + +static void UploadScoreToServerExt(struct HttpRequest *request, + struct HttpResponse *response, + int nr) +{ + struct ScoreEntry *score_entry = &scores.entry[scores.last_added]; + + request->hostname = API_SERVER_HOSTNAME; + request->port = API_SERVER_PORT; + request->method = API_SERVER_METHOD; + request->uri = API_SERVER_URI_ADD; + + char *tape_filename = getScoreTapeFilename(score_entry->tape_basename, nr); + char *tape_base64 = get_file_base64(tape_filename); + + if (tape_base64 == NULL) + { + Error("loading and base64 encoding score tape file failed"); + + return; + } + + snprintf(request->body, MAX_HTTP_BODY_SIZE, + "{\n" + " \"game_version\": \"%s\",\n" + " \"levelset_identifier\": \"%s\",\n" + " \"levelset_name\": \"%s\",\n" + " \"levelset_author\": \"%s\",\n" + " \"levelset_num_levels\": \"%d\",\n" + " \"levelset_first_level\": \"%d\",\n" + " \"level_nr\": \"%d\",\n" + " \"player_name\": \"%s\",\n" + " \"score\": \"%d\",\n" + " \"time\": \"%d\",\n" + " \"tape_basename\": \"%s\",\n" + " \"tape\": \"%s\"\n" + "}\n", + getProgramRealVersionString(), + leveldir_current->identifier, + leveldir_current->name, + leveldir_current->author, + leveldir_current->levels, + leveldir_current->first_level, + level_nr, + score_entry->name, + score_entry->score, + score_entry->time, + score_entry->tape_basename, + tape_base64); + + 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; + } +} + +static void UploadScoreToServer(int nr) +{ + struct HttpRequest *request = checked_calloc(sizeof(struct HttpRequest)); + struct HttpResponse *response = checked_calloc(sizeof(struct HttpResponse)); + + UploadScoreToServerExt(request, response, nr); + + checked_free(request); + checked_free(response); +} + +void SaveServerScore(int nr) +{ + UploadScoreToServer(nr); +} + // ============================================================================ // setup file functions