mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 16:45:47 -04:00
dep/rcheevos: Update to 8a717b1
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
#include "rc_api_request.h"
|
||||
#include "rc_api_runtime.h"
|
||||
|
||||
#include "../rcheevos/rc_compat.h"
|
||||
#include "../rc_compat.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
@ -16,11 +16,9 @@
|
||||
static char* g_host = NULL;
|
||||
static char* g_imagehost = NULL;
|
||||
|
||||
#undef DEBUG_BUFFERS
|
||||
|
||||
/* --- rc_json --- */
|
||||
|
||||
static int rc_json_parse_object(rc_json_iterator_t* iterator, rc_json_field_t* fields, size_t field_count, unsigned* fields_seen);
|
||||
static int rc_json_parse_object(rc_json_iterator_t* iterator, rc_json_field_t* fields, size_t field_count, uint32_t* fields_seen);
|
||||
static int rc_json_parse_array(rc_json_iterator_t* iterator, rc_json_field_t* field);
|
||||
|
||||
static int rc_json_match_char(rc_json_iterator_t* iterator, char c)
|
||||
@ -184,9 +182,9 @@ static int rc_json_get_next_field(rc_json_iterator_t* iterator, rc_json_field_t*
|
||||
return RC_OK;
|
||||
}
|
||||
|
||||
static int rc_json_parse_object(rc_json_iterator_t* iterator, rc_json_field_t* fields, size_t field_count, unsigned* fields_seen) {
|
||||
static int rc_json_parse_object(rc_json_iterator_t* iterator, rc_json_field_t* fields, size_t field_count, uint32_t* fields_seen) {
|
||||
size_t i;
|
||||
unsigned num_fields = 0;
|
||||
uint32_t num_fields = 0;
|
||||
rc_json_field_t field;
|
||||
int result;
|
||||
|
||||
@ -261,12 +259,7 @@ static int rc_json_extract_html_error(rc_api_response_t* response, const rc_api_
|
||||
if (isdigit((int)*title_start)) {
|
||||
const char* title_end = strstr(title_start + 7, "</title>");
|
||||
if (title_end) {
|
||||
char* dst = rc_buf_reserve(&response->buffer, (title_end - title_start) + 1);
|
||||
response->error_message = dst;
|
||||
memcpy(dst, title_start, title_end - title_start);
|
||||
dst += (title_end - title_start);
|
||||
*dst++ = '\0';
|
||||
rc_buf_consume(&response->buffer, response->error_message, dst);
|
||||
response->error_message = rc_buffer_strncpy(&response->buffer, title_start, title_end - title_start);
|
||||
response->succeeded = 0;
|
||||
return RC_INVALID_JSON;
|
||||
}
|
||||
@ -279,19 +272,38 @@ static int rc_json_extract_html_error(rc_api_response_t* response, const rc_api_
|
||||
if (end > json && end[-1] == '\r')
|
||||
--end;
|
||||
|
||||
if (end > json) {
|
||||
char* dst = rc_buf_reserve(&response->buffer, (end - json) + 1);
|
||||
response->error_message = dst;
|
||||
memcpy(dst, json, end - json);
|
||||
dst += (end - json);
|
||||
*dst++ = '\0';
|
||||
rc_buf_consume(&response->buffer, response->error_message, dst);
|
||||
}
|
||||
if (end > json)
|
||||
response->error_message = rc_buffer_strncpy(&response->buffer, json, end - json);
|
||||
|
||||
response->succeeded = 0;
|
||||
return RC_INVALID_JSON;
|
||||
}
|
||||
|
||||
static int rc_json_convert_error_code(const char* server_error_code)
|
||||
{
|
||||
switch (server_error_code[0]) {
|
||||
case 'a':
|
||||
if (strcmp(server_error_code, "access_denied") == 0)
|
||||
return RC_ACCESS_DENIED;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (strcmp(server_error_code, "expired_token") == 0)
|
||||
return RC_EXPIRED_TOKEN;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (strcmp(server_error_code, "invalid_credentials") == 0)
|
||||
return RC_INVALID_CREDENTIALS;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RC_API_FAILURE;
|
||||
}
|
||||
|
||||
int rc_json_parse_server_response(rc_api_response_t* response, const rc_api_server_response_t* server_response, rc_json_field_t* fields, size_t field_count) {
|
||||
int result;
|
||||
|
||||
@ -306,7 +318,38 @@ int rc_json_parse_server_response(rc_api_response_t* response, const rc_api_serv
|
||||
|
||||
response->error_message = NULL;
|
||||
|
||||
if (!server_response || !server_response->body || !*server_response->body) {
|
||||
if (!server_response) {
|
||||
response->succeeded = 0;
|
||||
return RC_NO_RESPONSE;
|
||||
}
|
||||
|
||||
if (server_response->http_status_code == RC_API_SERVER_RESPONSE_CLIENT_ERROR ||
|
||||
server_response->http_status_code == RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR) {
|
||||
/* client provided error message is passed as the response body */
|
||||
response->error_message = server_response->body;
|
||||
response->succeeded = 0;
|
||||
return RC_NO_RESPONSE;
|
||||
}
|
||||
|
||||
if (!server_response->body || !*server_response->body) {
|
||||
/* expect valid HTTP status codes to have bodies that we can extract the message from,
|
||||
* but provide some default messages in case they don't. */
|
||||
switch (server_response->http_status_code) {
|
||||
case 504: /* 504 Gateway Timeout */
|
||||
case 522: /* 522 Connection Timed Out */
|
||||
case 524: /* 524 A Timeout Occurred */
|
||||
response->error_message = "Request has timed out.";
|
||||
break;
|
||||
|
||||
case 521: /* 521 Web Server is Down */
|
||||
case 523: /* 523 Origin is Unreachable */
|
||||
response->error_message = "Could not connect to server.";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
response->succeeded = 0;
|
||||
return RC_NO_RESPONSE;
|
||||
}
|
||||
@ -323,6 +366,13 @@ int rc_json_parse_server_response(rc_api_response_t* response, const rc_api_serv
|
||||
|
||||
rc_json_get_optional_string(&response->error_message, response, &fields[1], "Error", NULL);
|
||||
rc_json_get_optional_bool(&response->succeeded, &fields[0], "Success", 1);
|
||||
|
||||
/* Code will be the third field in the fields array, but may not always be present */
|
||||
if (field_count > 2 && strcmp(fields[2].name, "Code") == 0) {
|
||||
rc_json_get_optional_string(&response->error_code, response, &fields[2], "Code", NULL);
|
||||
if (response->error_code != NULL)
|
||||
result = rc_json_convert_error_code(response->error_code);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -333,14 +383,14 @@ static int rc_json_missing_field(rc_api_response_t* response, const rc_json_fiel
|
||||
const size_t not_found_len = strlen(not_found);
|
||||
const size_t field_len = strlen(field->name);
|
||||
|
||||
char* write = rc_buf_reserve(&response->buffer, field_len + not_found_len + 1);
|
||||
uint8_t* write = rc_buffer_reserve(&response->buffer, field_len + not_found_len + 1);
|
||||
if (write) {
|
||||
response->error_message = write;
|
||||
response->error_message = (char*)write;
|
||||
memcpy(write, field->name, field_len);
|
||||
write += field_len;
|
||||
memcpy(write, not_found, not_found_len + 1);
|
||||
write += not_found_len + 1;
|
||||
rc_buf_consume(&response->buffer, response->error_message, write);
|
||||
rc_buffer_consume(&response->buffer, (uint8_t*)response->error_message, write);
|
||||
}
|
||||
|
||||
response->succeeded = 0;
|
||||
@ -383,18 +433,18 @@ static int rc_json_get_array_entry_value(rc_json_field_t* field, rc_json_iterato
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rc_json_get_required_unum_array(unsigned** entries, unsigned* num_entries, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
int rc_json_get_required_unum_array(uint32_t** entries, uint32_t* num_entries, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
rc_json_iterator_t iterator;
|
||||
rc_json_field_t array;
|
||||
rc_json_field_t value;
|
||||
unsigned* entry;
|
||||
uint32_t* entry;
|
||||
|
||||
memset(&array, 0, sizeof(array));
|
||||
if (!rc_json_get_required_array(num_entries, &array, response, field, field_name))
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
if (*num_entries) {
|
||||
*entries = (unsigned*)rc_buf_alloc(&response->buffer, *num_entries * sizeof(unsigned));
|
||||
*entries = (uint32_t*)rc_buffer_alloc(&response->buffer, *num_entries * sizeof(uint32_t));
|
||||
if (!*entries)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -419,7 +469,7 @@ int rc_json_get_required_unum_array(unsigned** entries, unsigned* num_entries, r
|
||||
return RC_OK;
|
||||
}
|
||||
|
||||
int rc_json_get_required_array(unsigned* num_entries, rc_json_field_t* array_field, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
int rc_json_get_required_array(uint32_t* num_entries, rc_json_field_t* array_field, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
#ifndef NDEBUG
|
||||
if (strcmp(field->name, field_name) != 0)
|
||||
return 0;
|
||||
@ -431,7 +481,7 @@ int rc_json_get_required_array(unsigned* num_entries, rc_json_field_t* array_fie
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rc_json_get_optional_array(unsigned* num_entries, rc_json_field_t* array_field, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
int rc_json_get_optional_array(uint32_t* num_entries, rc_json_field_t* array_field, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
#ifndef NDEBUG
|
||||
if (strcmp(field->name, field_name) != 0)
|
||||
return 0;
|
||||
@ -468,16 +518,16 @@ int rc_json_get_array_entry_object(rc_json_field_t* fields, size_t field_count,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned rc_json_decode_hex4(const char* input) {
|
||||
static uint32_t rc_json_decode_hex4(const char* input) {
|
||||
char hex[5];
|
||||
|
||||
memcpy(hex, input, 4);
|
||||
hex[4] = '\0';
|
||||
|
||||
return (unsigned)strtoul(hex, NULL, 16);
|
||||
return (uint32_t)strtoul(hex, NULL, 16);
|
||||
}
|
||||
|
||||
static int rc_json_ucs32_to_utf8(unsigned char* dst, unsigned ucs32_char) {
|
||||
static int rc_json_ucs32_to_utf8(uint8_t* dst, uint32_t ucs32_char) {
|
||||
if (ucs32_char < 0x80) {
|
||||
dst[0] = (ucs32_char & 0x7F);
|
||||
return 1;
|
||||
@ -522,7 +572,7 @@ static int rc_json_ucs32_to_utf8(unsigned char* dst, unsigned ucs32_char) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
int rc_json_get_string(const char** out, rc_api_buffer_t* buffer, const rc_json_field_t* field, const char* field_name) {
|
||||
int rc_json_get_string(const char** out, rc_buffer_t* buffer, const rc_json_field_t* field, const char* field_name) {
|
||||
const char* src = field->value_start;
|
||||
size_t len = field->value_end - field->value_start;
|
||||
char* dst;
|
||||
@ -553,7 +603,7 @@ int rc_json_get_string(const char** out, rc_api_buffer_t* buffer, const rc_json_
|
||||
return 1;
|
||||
}
|
||||
|
||||
*out = dst = rc_buf_reserve(buffer, len - 1); /* -2 for quotes, +1 for null terminator */
|
||||
*out = dst = (char*)rc_buffer_reserve(buffer, len - 1); /* -2 for quotes, +1 for null terminator */
|
||||
|
||||
do {
|
||||
if (*src == '\\') {
|
||||
@ -574,13 +624,13 @@ int rc_json_get_string(const char** out, rc_api_buffer_t* buffer, const rc_json_
|
||||
|
||||
if (*src == 'u') {
|
||||
/* unicode character */
|
||||
unsigned ucs32_char = rc_json_decode_hex4(src + 1);
|
||||
uint32_t ucs32_char = rc_json_decode_hex4(src + 1);
|
||||
src += 5;
|
||||
|
||||
if (ucs32_char >= 0xD800 && ucs32_char < 0xE000) {
|
||||
/* surrogate lead - look for surrogate tail */
|
||||
if (ucs32_char < 0xDC00 && src[0] == '\\' && src[1] == 'u') {
|
||||
const unsigned surrogate = rc_json_decode_hex4(src + 2);
|
||||
const uint32_t surrogate = rc_json_decode_hex4(src + 2);
|
||||
src += 6;
|
||||
|
||||
if (surrogate >= 0xDC00 && surrogate < 0xE000) {
|
||||
@ -613,13 +663,13 @@ int rc_json_get_string(const char** out, rc_api_buffer_t* buffer, const rc_json_
|
||||
} while (*src != '\"');
|
||||
|
||||
} else {
|
||||
*out = dst = rc_buf_reserve(buffer, len + 1); /* +1 for null terminator */
|
||||
*out = dst = (char*)rc_buffer_reserve(buffer, len + 1); /* +1 for null terminator */
|
||||
memcpy(dst, src, len);
|
||||
dst += len;
|
||||
}
|
||||
|
||||
*dst++ = '\0';
|
||||
rc_buf_consume(buffer, *out, dst);
|
||||
rc_buffer_consume(buffer, (uint8_t*)(*out), (uint8_t*)dst);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -635,9 +685,9 @@ int rc_json_get_required_string(const char** out, rc_api_response_t* response, c
|
||||
return rc_json_missing_field(response, field);
|
||||
}
|
||||
|
||||
int rc_json_get_num(int* out, const rc_json_field_t* field, const char* field_name) {
|
||||
int rc_json_get_num(int32_t* out, const rc_json_field_t* field, const char* field_name) {
|
||||
const char* src = field->value_start;
|
||||
int value = 0;
|
||||
int32_t value = 0;
|
||||
int negative = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -677,21 +727,21 @@ int rc_json_get_num(int* out, const rc_json_field_t* field, const char* field_na
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rc_json_get_optional_num(int* out, const rc_json_field_t* field, const char* field_name, int default_value) {
|
||||
void rc_json_get_optional_num(int32_t* out, const rc_json_field_t* field, const char* field_name, int default_value) {
|
||||
if (!rc_json_get_num(out, field, field_name))
|
||||
*out = default_value;
|
||||
}
|
||||
|
||||
int rc_json_get_required_num(int* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
int rc_json_get_required_num(int32_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
if (rc_json_get_num(out, field, field_name))
|
||||
return 1;
|
||||
|
||||
return rc_json_missing_field(response, field);
|
||||
}
|
||||
|
||||
int rc_json_get_unum(unsigned* out, const rc_json_field_t* field, const char* field_name) {
|
||||
int rc_json_get_unum(uint32_t* out, const rc_json_field_t* field, const char* field_name) {
|
||||
const char* src = field->value_start;
|
||||
int value = 0;
|
||||
uint32_t value = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (strcmp(field->name, field_name) != 0)
|
||||
@ -721,12 +771,12 @@ int rc_json_get_unum(unsigned* out, const rc_json_field_t* field, const char* fi
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rc_json_get_optional_unum(unsigned* out, const rc_json_field_t* field, const char* field_name, unsigned default_value) {
|
||||
void rc_json_get_optional_unum(uint32_t* out, const rc_json_field_t* field, const char* field_name, uint32_t default_value) {
|
||||
if (!rc_json_get_unum(out, field, field_name))
|
||||
*out = default_value;
|
||||
}
|
||||
|
||||
int rc_json_get_required_unum(unsigned* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
int rc_json_get_required_unum(uint32_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
if (rc_json_get_unum(out, field, field_name))
|
||||
return 1;
|
||||
|
||||
@ -819,133 +869,27 @@ int rc_json_get_required_bool(int* out, rc_api_response_t* response, const rc_js
|
||||
return rc_json_missing_field(response, field);
|
||||
}
|
||||
|
||||
/* --- rc_buf --- */
|
||||
/* --- rc_api_request --- */
|
||||
|
||||
void rc_buf_init(rc_api_buffer_t* buffer) {
|
||||
buffer->chunk.write = buffer->chunk.start = &buffer->data[0];
|
||||
buffer->chunk.end = &buffer->data[sizeof(buffer->data)];
|
||||
buffer->chunk.next = NULL;
|
||||
}
|
||||
|
||||
void rc_buf_destroy(rc_api_buffer_t* buffer) {
|
||||
rc_api_buffer_chunk_t *chunk;
|
||||
#ifdef DEBUG_BUFFERS
|
||||
int count = 0;
|
||||
int wasted = 0;
|
||||
int total = 0;
|
||||
#endif
|
||||
|
||||
/* first chunk is not allocated. skip it. */
|
||||
chunk = buffer->chunk.next;
|
||||
|
||||
/* deallocate any additional buffers */
|
||||
while (chunk) {
|
||||
rc_api_buffer_chunk_t* next = chunk->next;
|
||||
#ifdef DEBUG_BUFFERS
|
||||
total += (int)(chunk->end - chunk->data);
|
||||
wasted += (int)(chunk->end - chunk->write);
|
||||
++count;
|
||||
#endif
|
||||
free(chunk);
|
||||
chunk = next;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_BUFFERS
|
||||
printf("-- %d allocated buffers (%d/%d used, %d wasted, %0.2f%% efficiency)\n", count,
|
||||
total - wasted, total, wasted, (float)(100.0 - (wasted * 100.0) / total));
|
||||
#endif
|
||||
}
|
||||
|
||||
char* rc_buf_reserve(rc_api_buffer_t* buffer, size_t amount) {
|
||||
rc_api_buffer_chunk_t* chunk = &buffer->chunk;
|
||||
size_t remaining;
|
||||
while (chunk) {
|
||||
remaining = chunk->end - chunk->write;
|
||||
if (remaining >= amount)
|
||||
return chunk->write;
|
||||
|
||||
if (!chunk->next) {
|
||||
/* allocate a chunk of memory that is a multiple of 256-bytes. the first 32 bytes will be associated
|
||||
* to the chunk header, and the remaining will be used for data.
|
||||
*/
|
||||
const size_t chunk_header_size = sizeof(rc_api_buffer_chunk_t);
|
||||
const size_t alloc_size = (chunk_header_size + amount + 0xFF) & ~0xFF;
|
||||
chunk->next = (rc_api_buffer_chunk_t*)malloc(alloc_size);
|
||||
if (!chunk->next)
|
||||
break;
|
||||
|
||||
chunk->next->start = (char*)chunk->next + chunk_header_size;
|
||||
chunk->next->write = chunk->next->start;
|
||||
chunk->next->end = (char*)chunk->next + alloc_size;
|
||||
chunk->next->next = NULL;
|
||||
}
|
||||
|
||||
chunk = chunk->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rc_buf_consume(rc_api_buffer_t* buffer, const char* start, char* end) {
|
||||
rc_api_buffer_chunk_t* chunk = &buffer->chunk;
|
||||
do {
|
||||
if (chunk->write == start) {
|
||||
size_t offset = (end - chunk->start);
|
||||
offset = (offset + 7) & ~7;
|
||||
chunk->write = &chunk->start[offset];
|
||||
|
||||
if (chunk->write > chunk->end)
|
||||
chunk->write = chunk->end;
|
||||
break;
|
||||
}
|
||||
|
||||
chunk = chunk->next;
|
||||
} while (chunk);
|
||||
}
|
||||
|
||||
void* rc_buf_alloc(rc_api_buffer_t* buffer, size_t amount) {
|
||||
char* ptr = rc_buf_reserve(buffer, amount);
|
||||
rc_buf_consume(buffer, ptr, ptr + amount);
|
||||
return (void*)ptr;
|
||||
}
|
||||
|
||||
char* rc_buf_strncpy(rc_api_buffer_t* buffer, const char* src, size_t len) {
|
||||
char* dst = rc_buf_reserve(buffer, len + 1);
|
||||
memcpy(dst, src, len);
|
||||
dst[len] = '\0';
|
||||
rc_buf_consume(buffer, dst, dst + len + 2);
|
||||
return dst;
|
||||
}
|
||||
|
||||
char* rc_buf_strcpy(rc_api_buffer_t* buffer, const char* src) {
|
||||
return rc_buf_strncpy(buffer, src, strlen(src));
|
||||
}
|
||||
|
||||
void rc_api_destroy_request(rc_api_request_t* request) {
|
||||
rc_buf_destroy(&request->buffer);
|
||||
}
|
||||
|
||||
void rc_api_format_md5(char checksum[33], const unsigned char digest[16]) {
|
||||
snprintf(checksum, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7],
|
||||
digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]
|
||||
);
|
||||
void rc_api_destroy_request(rc_api_request_t* request)
|
||||
{
|
||||
rc_buffer_destroy(&request->buffer);
|
||||
}
|
||||
|
||||
/* --- rc_url_builder --- */
|
||||
|
||||
void rc_url_builder_init(rc_api_url_builder_t* builder, rc_api_buffer_t* buffer, size_t estimated_size) {
|
||||
rc_api_buffer_chunk_t* used_buffer;
|
||||
void rc_url_builder_init(rc_api_url_builder_t* builder, rc_buffer_t* buffer, size_t estimated_size) {
|
||||
rc_buffer_chunk_t* used_buffer;
|
||||
|
||||
memset(builder, 0, sizeof(*builder));
|
||||
builder->buffer = buffer;
|
||||
builder->write = builder->start = rc_buf_reserve(buffer, estimated_size);
|
||||
builder->write = builder->start = (char*)rc_buffer_reserve(buffer, estimated_size);
|
||||
|
||||
used_buffer = &buffer->chunk;
|
||||
while (used_buffer && used_buffer->write != builder->write)
|
||||
while (used_buffer && used_buffer->write != (uint8_t*)builder->write)
|
||||
used_buffer = used_buffer->next;
|
||||
|
||||
builder->end = (used_buffer) ? used_buffer->end : builder->start + estimated_size;
|
||||
builder->end = (used_buffer) ? (char*)used_buffer->end : builder->start + estimated_size;
|
||||
}
|
||||
|
||||
const char* rc_url_builder_finalize(rc_api_url_builder_t* builder) {
|
||||
@ -954,7 +898,7 @@ const char* rc_url_builder_finalize(rc_api_url_builder_t* builder) {
|
||||
if (builder->result != RC_OK)
|
||||
return NULL;
|
||||
|
||||
rc_buf_consume(builder->buffer, builder->start, builder->write);
|
||||
rc_buffer_consume(builder->buffer, (uint8_t*)builder->start, (uint8_t*)builder->write);
|
||||
return builder->start;
|
||||
}
|
||||
|
||||
@ -964,7 +908,7 @@ static int rc_url_builder_reserve(rc_api_url_builder_t* builder, size_t amount)
|
||||
if (remaining < amount) {
|
||||
const size_t used = builder->write - builder->start;
|
||||
const size_t current_size = builder->end - builder->start;
|
||||
const size_t buffer_prefix_size = sizeof(rc_api_buffer_chunk_t);
|
||||
const size_t buffer_prefix_size = sizeof(rc_buffer_chunk_t);
|
||||
char* new_start;
|
||||
size_t new_size = (current_size < 256) ? 256 : current_size * 2;
|
||||
do {
|
||||
@ -975,11 +919,11 @@ static int rc_url_builder_reserve(rc_api_url_builder_t* builder, size_t amount)
|
||||
new_size *= 2;
|
||||
} while (1);
|
||||
|
||||
/* rc_buf_reserve will align to 256 bytes after including the buffer prefix. attempt to account for that */
|
||||
/* rc_buffer_reserve will align to 256 bytes after including the buffer prefix. attempt to account for that */
|
||||
if ((remaining - amount) > buffer_prefix_size)
|
||||
new_size -= buffer_prefix_size;
|
||||
|
||||
new_start = rc_buf_reserve(builder->buffer, new_size);
|
||||
new_start = (char*)rc_buffer_reserve(builder->buffer, new_size);
|
||||
if (!new_start) {
|
||||
builder->result = RC_OUT_OF_MEMORY;
|
||||
return RC_OUT_OF_MEMORY;
|
||||
@ -1070,7 +1014,7 @@ static int rc_url_builder_append_param_equals(rc_api_url_builder_t* builder, con
|
||||
return builder->result;
|
||||
}
|
||||
|
||||
void rc_url_builder_append_unum_param(rc_api_url_builder_t* builder, const char* param, unsigned value) {
|
||||
void rc_url_builder_append_unum_param(rc_api_url_builder_t* builder, const char* param, uint32_t value) {
|
||||
if (rc_url_builder_append_param_equals(builder, param) == RC_OK) {
|
||||
char num[16];
|
||||
int chars = snprintf(num, sizeof(num), "%u", value);
|
||||
@ -1078,7 +1022,7 @@ void rc_url_builder_append_unum_param(rc_api_url_builder_t* builder, const char*
|
||||
}
|
||||
}
|
||||
|
||||
void rc_url_builder_append_num_param(rc_api_url_builder_t* builder, const char* param, int value) {
|
||||
void rc_url_builder_append_num_param(rc_api_url_builder_t* builder, const char* param, int32_t value) {
|
||||
if (rc_url_builder_append_param_equals(builder, param) == RC_OK) {
|
||||
char num[16];
|
||||
int chars = snprintf(num, sizeof(num), "%d", value);
|
||||
@ -1093,7 +1037,7 @@ void rc_url_builder_append_str_param(rc_api_url_builder_t* builder, const char*
|
||||
|
||||
void rc_api_url_build_dorequest_url(rc_api_request_t* request) {
|
||||
#define DOREQUEST_ENDPOINT "/dorequest.php"
|
||||
rc_buf_init(&request->buffer);
|
||||
rc_buffer_init(&request->buffer);
|
||||
|
||||
if (!g_host) {
|
||||
request->url = RETROACHIEVEMENTS_HOST DOREQUEST_ENDPOINT;
|
||||
@ -1102,13 +1046,13 @@ void rc_api_url_build_dorequest_url(rc_api_request_t* request) {
|
||||
const size_t endpoint_len = sizeof(DOREQUEST_ENDPOINT);
|
||||
const size_t host_len = strlen(g_host);
|
||||
const size_t url_len = host_len + endpoint_len;
|
||||
char* url = rc_buf_reserve(&request->buffer, url_len);
|
||||
uint8_t* url = rc_buffer_reserve(&request->buffer, url_len);
|
||||
|
||||
memcpy(url, g_host, host_len);
|
||||
memcpy(url + host_len, DOREQUEST_ENDPOINT, endpoint_len);
|
||||
rc_buf_consume(&request->buffer, url, url + url_len);
|
||||
rc_buffer_consume(&request->buffer, url, url + url_len);
|
||||
|
||||
request->url = url;
|
||||
request->url = (char*)url;
|
||||
}
|
||||
#undef DOREQUEST_ENDPOINT
|
||||
}
|
||||
@ -1182,7 +1126,7 @@ void rc_api_set_image_host(const char* hostname) {
|
||||
int rc_api_init_fetch_image_request(rc_api_request_t* request, const rc_api_fetch_image_request_t* api_params) {
|
||||
rc_api_url_builder_t builder;
|
||||
|
||||
rc_buf_init(&request->buffer);
|
||||
rc_buffer_init(&request->buffer);
|
||||
rc_url_builder_init(&builder, &request->buffer, 64);
|
||||
|
||||
if (g_imagehost) {
|
||||
|
@ -16,13 +16,13 @@ typedef struct rc_api_url_builder_t {
|
||||
char* write;
|
||||
char* start;
|
||||
char* end;
|
||||
/* pointer to a preallocated rc_api_buffer_t */
|
||||
rc_api_buffer_t* buffer;
|
||||
/* pointer to a preallocated rc_buffer_t */
|
||||
rc_buffer_t* buffer;
|
||||
int result;
|
||||
}
|
||||
rc_api_url_builder_t;
|
||||
|
||||
void rc_url_builder_init(rc_api_url_builder_t* builder, rc_api_buffer_t* buffer, size_t estimated_size);
|
||||
void rc_url_builder_init(rc_api_url_builder_t* builder, rc_buffer_t* buffer, size_t estimated_size);
|
||||
void rc_url_builder_append(rc_api_url_builder_t* builder, const char* data, size_t len);
|
||||
const char* rc_url_builder_finalize(rc_api_url_builder_t* builder);
|
||||
|
||||
@ -33,7 +33,7 @@ typedef struct rc_json_field_t {
|
||||
const char* value_end;
|
||||
const char* name;
|
||||
size_t name_len;
|
||||
unsigned array_size;
|
||||
uint32_t array_size;
|
||||
}
|
||||
rc_json_field_t;
|
||||
|
||||
@ -44,44 +44,35 @@ typedef struct rc_json_iterator_t {
|
||||
rc_json_iterator_t;
|
||||
|
||||
int rc_json_parse_server_response(rc_api_response_t* response, const rc_api_server_response_t* server_response, rc_json_field_t* fields, size_t field_count);
|
||||
int rc_json_get_string(const char** out, rc_api_buffer_t* buffer, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_num(int* out, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_unum(unsigned* out, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_string(const char** out, rc_buffer_t* buffer, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_num(int32_t* out, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_unum(uint32_t* out, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_bool(int* out, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_datetime(time_t* out, const rc_json_field_t* field, const char* field_name);
|
||||
void rc_json_get_optional_string(const char** out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name, const char* default_value);
|
||||
void rc_json_get_optional_num(int* out, const rc_json_field_t* field, const char* field_name, int default_value);
|
||||
void rc_json_get_optional_unum(unsigned* out, const rc_json_field_t* field, const char* field_name, unsigned default_value);
|
||||
void rc_json_get_optional_num(int32_t* out, const rc_json_field_t* field, const char* field_name, int default_value);
|
||||
void rc_json_get_optional_unum(uint32_t* out, const rc_json_field_t* field, const char* field_name, uint32_t default_value);
|
||||
void rc_json_get_optional_bool(int* out, const rc_json_field_t* field, const char* field_name, int default_value);
|
||||
int rc_json_get_optional_array(unsigned* num_entries, rc_json_field_t* iterator, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_optional_array(uint32_t* num_entries, rc_json_field_t* iterator, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_string(const char** out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_num(int* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_unum(unsigned* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_num(int32_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_unum(uint32_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_bool(int* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_datetime(time_t* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_object(rc_json_field_t* fields, size_t field_count, rc_api_response_t* response, rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_unum_array(unsigned** entries, unsigned* num_entries, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_array(unsigned* num_entries, rc_json_field_t* array_field, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_unum_array(uint32_t** entries, uint32_t* num_entries, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_required_array(uint32_t* num_entries, rc_json_field_t* array_field, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name);
|
||||
int rc_json_get_array_entry_object(rc_json_field_t* fields, size_t field_count, rc_json_iterator_t* iterator);
|
||||
int rc_json_get_next_object_field(rc_json_iterator_t* iterator, rc_json_field_t* field);
|
||||
int rc_json_get_object_string_length(const char* json);
|
||||
|
||||
void rc_buf_init(rc_api_buffer_t* buffer);
|
||||
void rc_buf_destroy(rc_api_buffer_t* buffer);
|
||||
char* rc_buf_reserve(rc_api_buffer_t* buffer, size_t amount);
|
||||
void rc_buf_consume(rc_api_buffer_t* buffer, const char* start, char* end);
|
||||
void* rc_buf_alloc(rc_api_buffer_t* buffer, size_t amount);
|
||||
char* rc_buf_strcpy(rc_api_buffer_t* buffer, const char* src);
|
||||
char* rc_buf_strncpy(rc_api_buffer_t* buffer, const char* src, size_t len);
|
||||
|
||||
void rc_url_builder_append_encoded_str(rc_api_url_builder_t* builder, const char* str);
|
||||
void rc_url_builder_append_num_param(rc_api_url_builder_t* builder, const char* param, int value);
|
||||
void rc_url_builder_append_unum_param(rc_api_url_builder_t* builder, const char* param, unsigned value);
|
||||
void rc_url_builder_append_num_param(rc_api_url_builder_t* builder, const char* param, int32_t value);
|
||||
void rc_url_builder_append_unum_param(rc_api_url_builder_t* builder, const char* param, uint32_t value);
|
||||
void rc_url_builder_append_str_param(rc_api_url_builder_t* builder, const char* param, const char* value);
|
||||
|
||||
void rc_api_url_build_dorequest_url(rc_api_request_t* request);
|
||||
int rc_api_url_build_dorequest(rc_api_url_builder_t* builder, const char* api, const char* username, const char* api_token);
|
||||
void rc_api_format_md5(char checksum[33], const unsigned char digest[16]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "rc_api_editor.h"
|
||||
#include "rc_api_common.h"
|
||||
|
||||
#include "../rcheevos/rc_compat.h"
|
||||
#include "../rc_compat.h"
|
||||
#include "../rhash/md5.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -60,7 +60,7 @@ int rc_api_process_fetch_code_notes_server_response(rc_api_fetch_code_notes_resp
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -70,7 +70,7 @@ int rc_api_process_fetch_code_notes_server_response(rc_api_fetch_code_notes_resp
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
if (response->num_notes) {
|
||||
response->notes = (rc_api_code_note_t*)rc_buf_alloc(&response->response.buffer, response->num_notes * sizeof(rc_api_code_note_t));
|
||||
response->notes = (rc_api_code_note_t*)rc_buffer_alloc(&response->response.buffer, response->num_notes * sizeof(rc_api_code_note_t));
|
||||
if (!response->notes)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -117,7 +117,7 @@ int rc_api_process_fetch_code_notes_server_response(rc_api_fetch_code_notes_resp
|
||||
}
|
||||
|
||||
void rc_api_destroy_fetch_code_notes_response(rc_api_fetch_code_notes_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Update Code Note --- */
|
||||
@ -170,7 +170,7 @@ int rc_api_process_update_code_note_server_response(rc_api_update_code_note_resp
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -180,7 +180,7 @@ int rc_api_process_update_code_note_server_response(rc_api_update_code_note_resp
|
||||
}
|
||||
|
||||
void rc_api_destroy_update_code_note_response(rc_api_update_code_note_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Update Achievement --- */
|
||||
@ -231,7 +231,7 @@ int rc_api_init_update_achievement_request(rc_api_request_t* request, const rc_a
|
||||
snprintf(buffer, sizeof(buffer), "%u", api_params->points * 3);
|
||||
md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer));
|
||||
md5_finish(&md5, hash);
|
||||
rc_api_format_md5(buffer, hash);
|
||||
rc_format_md5(buffer, hash);
|
||||
rc_url_builder_append_str_param(&builder, "h", buffer);
|
||||
|
||||
request->post_data = rc_url_builder_finalize(&builder);
|
||||
@ -260,7 +260,7 @@ int rc_api_process_update_achievement_server_response(rc_api_update_achievement_
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -273,7 +273,7 @@ int rc_api_process_update_achievement_server_response(rc_api_update_achievement_
|
||||
}
|
||||
|
||||
void rc_api_destroy_update_achievement_response(rc_api_update_achievement_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Update Leaderboard --- */
|
||||
@ -333,7 +333,7 @@ int rc_api_init_update_leaderboard_request(rc_api_request_t* request, const rc_a
|
||||
md5_append(&md5, (md5_byte_t*)"RE2", 3);
|
||||
md5_append(&md5, (md5_byte_t*)api_params->format, (int)strlen(api_params->format));
|
||||
md5_finish(&md5, hash);
|
||||
rc_api_format_md5(buffer, hash);
|
||||
rc_format_md5(buffer, hash);
|
||||
rc_url_builder_append_str_param(&builder, "h", buffer);
|
||||
|
||||
request->post_data = rc_url_builder_finalize(&builder);
|
||||
@ -362,7 +362,7 @@ int rc_api_process_update_leaderboard_server_response(rc_api_update_leaderboard_
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -375,7 +375,7 @@ int rc_api_process_update_leaderboard_server_response(rc_api_update_leaderboard_
|
||||
}
|
||||
|
||||
void rc_api_destroy_update_leaderboard_response(rc_api_update_leaderboard_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Fetch Badge Range --- */
|
||||
@ -417,7 +417,7 @@ int rc_api_process_fetch_badge_range_server_response(rc_api_fetch_badge_range_re
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -432,7 +432,7 @@ int rc_api_process_fetch_badge_range_server_response(rc_api_fetch_badge_range_re
|
||||
}
|
||||
|
||||
void rc_api_destroy_fetch_badge_range_response(rc_api_fetch_badge_range_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Add Game Hash --- */
|
||||
@ -498,7 +498,7 @@ int rc_api_process_add_game_hash_server_response(rc_api_add_game_hash_response_t
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -514,5 +514,5 @@ int rc_api_process_add_game_hash_server_response(rc_api_add_game_hash_response_t
|
||||
}
|
||||
|
||||
void rc_api_destroy_add_game_hash_response(rc_api_add_game_hash_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ int rc_api_process_fetch_achievement_info_server_response(rc_api_fetch_achieveme
|
||||
rc_api_achievement_awarded_entry_t* entry;
|
||||
rc_json_field_t array_field;
|
||||
rc_json_iterator_t iterator;
|
||||
unsigned timet;
|
||||
uint32_t timet;
|
||||
int result;
|
||||
|
||||
rc_json_field_t fields[] = {
|
||||
@ -75,7 +75,7 @@ int rc_api_process_fetch_achievement_info_server_response(rc_api_fetch_achieveme
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK)
|
||||
@ -97,7 +97,7 @@ int rc_api_process_fetch_achievement_info_server_response(rc_api_fetch_achieveme
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
if (response->num_recently_awarded) {
|
||||
response->recently_awarded = (rc_api_achievement_awarded_entry_t*)rc_buf_alloc(&response->response.buffer, response->num_recently_awarded * sizeof(rc_api_achievement_awarded_entry_t));
|
||||
response->recently_awarded = (rc_api_achievement_awarded_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_recently_awarded * sizeof(rc_api_achievement_awarded_entry_t));
|
||||
if (!response->recently_awarded)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -122,7 +122,7 @@ int rc_api_process_fetch_achievement_info_server_response(rc_api_fetch_achieveme
|
||||
}
|
||||
|
||||
void rc_api_destroy_fetch_achievement_info_response(rc_api_fetch_achievement_info_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Fetch Leaderboard Info --- */
|
||||
@ -165,7 +165,7 @@ int rc_api_process_fetch_leaderboard_info_server_response(rc_api_fetch_leaderboa
|
||||
rc_api_lboard_info_entry_t* entry;
|
||||
rc_json_field_t array_field;
|
||||
rc_json_iterator_t iterator;
|
||||
unsigned timet;
|
||||
uint32_t timet;
|
||||
int result;
|
||||
size_t len;
|
||||
char format[16];
|
||||
@ -206,7 +206,7 @@ int rc_api_process_fetch_leaderboard_info_server_response(rc_api_fetch_leaderboa
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK)
|
||||
@ -217,7 +217,7 @@ int rc_api_process_fetch_leaderboard_info_server_response(rc_api_fetch_leaderboa
|
||||
|
||||
if (!rc_json_get_required_unum(&response->id, &response->response, &leaderboarddata_fields[0], "LBID"))
|
||||
return RC_MISSING_VALUE;
|
||||
if (!rc_json_get_required_num(&response->lower_is_better, &response->response, &leaderboarddata_fields[2], "LowerIsBetter"))
|
||||
if (!rc_json_get_required_unum(&response->lower_is_better, &response->response, &leaderboarddata_fields[2], "LowerIsBetter"))
|
||||
return RC_MISSING_VALUE;
|
||||
if (!rc_json_get_required_string(&response->title, &response->response, &leaderboarddata_fields[3], "LBTitle"))
|
||||
return RC_MISSING_VALUE;
|
||||
@ -250,7 +250,7 @@ int rc_api_process_fetch_leaderboard_info_server_response(rc_api_fetch_leaderboa
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
if (response->num_entries) {
|
||||
response->entries = (rc_api_lboard_info_entry_t*)rc_buf_alloc(&response->response.buffer, response->num_entries * sizeof(rc_api_lboard_info_entry_t));
|
||||
response->entries = (rc_api_lboard_info_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_entries * sizeof(rc_api_lboard_info_entry_t));
|
||||
if (!response->entries)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -284,7 +284,7 @@ int rc_api_process_fetch_leaderboard_info_server_response(rc_api_fetch_leaderboa
|
||||
}
|
||||
|
||||
void rc_api_destroy_fetch_leaderboard_info_response(rc_api_fetch_leaderboard_info_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Fetch Games List --- */
|
||||
@ -331,7 +331,7 @@ int rc_api_process_fetch_games_list_server_response(rc_api_fetch_games_list_resp
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK)
|
||||
@ -344,9 +344,9 @@ int rc_api_process_fetch_games_list_server_response(rc_api_fetch_games_list_resp
|
||||
}
|
||||
|
||||
response->num_entries = fields[2].array_size;
|
||||
rc_buf_reserve(&response->response.buffer, response->num_entries * (32 + sizeof(rc_api_game_list_entry_t)));
|
||||
rc_buffer_reserve(&response->response.buffer, response->num_entries * (32 + sizeof(rc_api_game_list_entry_t)));
|
||||
|
||||
response->entries = (rc_api_game_list_entry_t*)rc_buf_alloc(&response->response.buffer, response->num_entries * sizeof(rc_api_game_list_entry_t));
|
||||
response->entries = (rc_api_game_list_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_entries * sizeof(rc_api_game_list_entry_t));
|
||||
if (!response->entries)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -369,5 +369,5 @@ int rc_api_process_fetch_games_list_server_response(rc_api_fetch_games_list_resp
|
||||
}
|
||||
|
||||
void rc_api_destroy_fetch_games_list_response(rc_api_fetch_games_list_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "rc_runtime.h"
|
||||
#include "rc_runtime_types.h"
|
||||
#include "../rcheevos/rc_compat.h"
|
||||
#include "../rc_compat.h"
|
||||
#include "../rhash/md5.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -48,7 +48,7 @@ int rc_api_process_resolve_hash_server_response(rc_api_resolve_hash_response_t*
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK)
|
||||
@ -59,7 +59,7 @@ int rc_api_process_resolve_hash_server_response(rc_api_resolve_hash_response_t*
|
||||
}
|
||||
|
||||
void rc_api_destroy_resolve_hash_response(rc_api_resolve_hash_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Fetch Game Data --- */
|
||||
@ -102,7 +102,7 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
const char* last_author_field = "";
|
||||
size_t last_author_len = 0;
|
||||
size_t len;
|
||||
unsigned timet;
|
||||
uint32_t timet;
|
||||
int result;
|
||||
char format[16];
|
||||
|
||||
@ -150,7 +150,7 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -191,7 +191,7 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
len += (patchdata_fields[6].value_end - patchdata_fields[6].value_start) - /* leaderboards */
|
||||
patchdata_fields[6].array_size * (60 - sizeof(rc_api_leaderboard_definition_t));
|
||||
|
||||
rc_buf_reserve(&response->response.buffer, len);
|
||||
rc_buffer_reserve(&response->response.buffer, len);
|
||||
/* end estimation */
|
||||
|
||||
rc_json_get_optional_string(&response->rich_presence_script, &response->response, &patchdata_fields[4], "RichPresencePatch", "");
|
||||
@ -202,7 +202,7 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
if (response->num_achievements) {
|
||||
response->achievements = (rc_api_achievement_definition_t*)rc_buf_alloc(&response->response.buffer, response->num_achievements * sizeof(rc_api_achievement_definition_t));
|
||||
response->achievements = (rc_api_achievement_definition_t*)rc_buffer_alloc(&response->response.buffer, response->num_achievements * sizeof(rc_api_achievement_definition_t));
|
||||
if (!response->achievements)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -255,7 +255,7 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
if (response->num_leaderboards) {
|
||||
response->leaderboards = (rc_api_leaderboard_definition_t*)rc_buf_alloc(&response->response.buffer, response->num_leaderboards * sizeof(rc_api_leaderboard_definition_t));
|
||||
response->leaderboards = (rc_api_leaderboard_definition_t*)rc_buffer_alloc(&response->response.buffer, response->num_leaderboards * sizeof(rc_api_leaderboard_definition_t));
|
||||
if (!response->leaderboards)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -273,8 +273,10 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
return RC_MISSING_VALUE;
|
||||
if (!rc_json_get_required_string(&leaderboard->definition, &response->response, &leaderboard_fields[3], "Mem"))
|
||||
return RC_MISSING_VALUE;
|
||||
rc_json_get_optional_bool(&leaderboard->lower_is_better, &leaderboard_fields[5], "LowerIsBetter", 0);
|
||||
rc_json_get_optional_bool(&leaderboard->hidden, &leaderboard_fields[6], "Hidden", 0);
|
||||
rc_json_get_optional_bool(&result, &leaderboard_fields[5], "LowerIsBetter", 0);
|
||||
leaderboard->lower_is_better = (uint8_t)result;
|
||||
rc_json_get_optional_bool(&result, &leaderboard_fields[6], "Hidden", 0);
|
||||
leaderboard->hidden = (uint8_t)result;
|
||||
|
||||
if (!leaderboard_fields[4].value_end)
|
||||
return RC_MISSING_VALUE;
|
||||
@ -296,7 +298,7 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
}
|
||||
|
||||
void rc_api_destroy_fetch_game_data_response(rc_api_fetch_game_data_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Ping --- */
|
||||
@ -340,13 +342,13 @@ int rc_api_process_ping_server_response(rc_api_ping_response_t* response, const
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
return rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
}
|
||||
|
||||
void rc_api_destroy_ping_response(rc_api_ping_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Award Achievement --- */
|
||||
@ -377,7 +379,7 @@ int rc_api_init_award_achievement_request(rc_api_request_t* request, const rc_ap
|
||||
snprintf(buffer, sizeof(buffer), "%d", api_params->hardcore ? 1 : 0);
|
||||
md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer));
|
||||
md5_finish(&md5, digest);
|
||||
rc_api_format_md5(buffer, digest);
|
||||
rc_format_md5(buffer, digest);
|
||||
rc_url_builder_append_str_param(&builder, "v", buffer);
|
||||
|
||||
request->post_data = rc_url_builder_finalize(&builder);
|
||||
@ -409,7 +411,7 @@ int rc_api_process_award_achievement_server_response(rc_api_award_achievement_re
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK)
|
||||
@ -437,7 +439,7 @@ int rc_api_process_award_achievement_server_response(rc_api_award_achievement_re
|
||||
}
|
||||
|
||||
void rc_api_destroy_award_achievement_response(rc_api_award_achievement_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Submit Leaderboard Entry --- */
|
||||
@ -469,7 +471,7 @@ int rc_api_init_submit_lboard_entry_request(rc_api_request_t* request, const rc_
|
||||
snprintf(buffer, sizeof(buffer), "%d", api_params->score);
|
||||
md5_append(&md5, (md5_byte_t*)buffer, (int)strlen(buffer));
|
||||
md5_finish(&md5, digest);
|
||||
rc_api_format_md5(buffer, digest);
|
||||
rc_format_md5(buffer, digest);
|
||||
rc_url_builder_append_str_param(&builder, "v", buffer);
|
||||
|
||||
request->post_data = rc_url_builder_finalize(&builder);
|
||||
@ -543,7 +545,7 @@ int rc_api_process_submit_lboard_entry_server_response(rc_api_submit_lboard_entr
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -568,7 +570,7 @@ int rc_api_process_submit_lboard_entry_server_response(rc_api_submit_lboard_entr
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
if (response->num_top_entries) {
|
||||
response->top_entries = (rc_api_lboard_entry_t*)rc_buf_alloc(&response->response.buffer, response->num_top_entries * sizeof(rc_api_lboard_entry_t));
|
||||
response->top_entries = (rc_api_lboard_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_top_entries * sizeof(rc_api_lboard_entry_t));
|
||||
if (!response->top_entries)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -595,5 +597,5 @@ int rc_api_process_submit_lboard_entry_server_response(rc_api_submit_lboard_entr
|
||||
}
|
||||
|
||||
void rc_api_destroy_submit_lboard_entry_response(rc_api_submit_lboard_entry_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "rc_api_user.h"
|
||||
#include "rc_api_common.h"
|
||||
|
||||
#include "../rcheevos/rc_version.h"
|
||||
#include "../rc_version.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -16,7 +16,7 @@ int rc_api_init_login_request(rc_api_request_t* request, const rc_api_login_requ
|
||||
return RC_INVALID_STATE;
|
||||
|
||||
rc_url_builder_init(&builder, &request->buffer, 48);
|
||||
rc_url_builder_append_str_param(&builder, "r", "login");
|
||||
rc_url_builder_append_str_param(&builder, "r", "login2");
|
||||
rc_url_builder_append_str_param(&builder, "u", api_params->username);
|
||||
|
||||
if (api_params->password && api_params->password[0])
|
||||
@ -47,6 +47,7 @@ int rc_api_process_login_server_response(rc_api_login_response_t* response, cons
|
||||
rc_json_field_t fields[] = {
|
||||
RC_JSON_NEW_FIELD("Success"),
|
||||
RC_JSON_NEW_FIELD("Error"),
|
||||
RC_JSON_NEW_FIELD("Code"),
|
||||
RC_JSON_NEW_FIELD("User"),
|
||||
RC_JSON_NEW_FIELD("Token"),
|
||||
RC_JSON_NEW_FIELD("Score"),
|
||||
@ -56,28 +57,28 @@ int rc_api_process_login_server_response(rc_api_login_response_t* response, cons
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
return result;
|
||||
|
||||
if (!rc_json_get_required_string(&response->username, &response->response, &fields[2], "User"))
|
||||
if (!rc_json_get_required_string(&response->username, &response->response, &fields[3], "User"))
|
||||
return RC_MISSING_VALUE;
|
||||
if (!rc_json_get_required_string(&response->api_token, &response->response, &fields[3], "Token"))
|
||||
if (!rc_json_get_required_string(&response->api_token, &response->response, &fields[4], "Token"))
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
rc_json_get_optional_unum(&response->score, &fields[4], "Score", 0);
|
||||
rc_json_get_optional_unum(&response->score_softcore, &fields[5], "SoftcoreScore", 0);
|
||||
rc_json_get_optional_unum(&response->num_unread_messages, &fields[6], "Messages", 0);
|
||||
rc_json_get_optional_unum(&response->score, &fields[5], "Score", 0);
|
||||
rc_json_get_optional_unum(&response->score_softcore, &fields[6], "SoftcoreScore", 0);
|
||||
rc_json_get_optional_unum(&response->num_unread_messages, &fields[7], "Messages", 0);
|
||||
|
||||
rc_json_get_optional_string(&response->display_name, &response->response, &fields[7], "DisplayName", response->username);
|
||||
rc_json_get_optional_string(&response->display_name, &response->response, &fields[8], "DisplayName", response->username);
|
||||
|
||||
return RC_OK;
|
||||
}
|
||||
|
||||
void rc_api_destroy_login_response(rc_api_login_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Start Session --- */
|
||||
@ -115,7 +116,7 @@ int rc_api_process_start_session_server_response(rc_api_start_session_response_t
|
||||
rc_api_unlock_entry_t* unlock;
|
||||
rc_json_field_t array_field;
|
||||
rc_json_iterator_t iterator;
|
||||
unsigned timet;
|
||||
uint32_t timet;
|
||||
int result;
|
||||
|
||||
rc_json_field_t fields[] = {
|
||||
@ -132,14 +133,14 @@ int rc_api_process_start_session_server_response(rc_api_start_session_response_t
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
return result;
|
||||
|
||||
if (rc_json_get_optional_array(&response->num_unlocks, &array_field, &response->response, &fields[2], "Unlocks") && response->num_unlocks) {
|
||||
response->unlocks = (rc_api_unlock_entry_t*)rc_buf_alloc(&response->response.buffer, response->num_unlocks * sizeof(rc_api_unlock_entry_t));
|
||||
response->unlocks = (rc_api_unlock_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_unlocks * sizeof(rc_api_unlock_entry_t));
|
||||
if (!response->unlocks)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -160,7 +161,7 @@ int rc_api_process_start_session_server_response(rc_api_start_session_response_t
|
||||
}
|
||||
|
||||
if (rc_json_get_optional_array(&response->num_hardcore_unlocks, &array_field, &response->response, &fields[3], "HardcoreUnlocks") && response->num_hardcore_unlocks) {
|
||||
response->hardcore_unlocks = (rc_api_unlock_entry_t*)rc_buf_alloc(&response->response.buffer, response->num_hardcore_unlocks * sizeof(rc_api_unlock_entry_t));
|
||||
response->hardcore_unlocks = (rc_api_unlock_entry_t*)rc_buffer_alloc(&response->response.buffer, response->num_hardcore_unlocks * sizeof(rc_api_unlock_entry_t));
|
||||
if (!response->hardcore_unlocks)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
@ -187,7 +188,7 @@ int rc_api_process_start_session_server_response(rc_api_start_session_response_t
|
||||
}
|
||||
|
||||
void rc_api_destroy_start_session_response(rc_api_start_session_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
||||
/* --- Fetch User Unlocks --- */
|
||||
@ -231,7 +232,7 @@ int rc_api_process_fetch_user_unlocks_server_response(rc_api_fetch_user_unlocks_
|
||||
};
|
||||
|
||||
memset(response, 0, sizeof(*response));
|
||||
rc_buf_init(&response->response.buffer);
|
||||
rc_buffer_init(&response->response.buffer);
|
||||
|
||||
result = rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
@ -242,5 +243,5 @@ int rc_api_process_fetch_user_unlocks_server_response(rc_api_fetch_user_unlocks_
|
||||
}
|
||||
|
||||
void rc_api_destroy_fetch_user_unlocks_response(rc_api_fetch_user_unlocks_response_t* response) {
|
||||
rc_buf_destroy(&response->response.buffer);
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
Reference in New Issue
Block a user