mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 18:15:46 -04:00
dep/rcheevos: Bump to 74860c9
This commit is contained in:
@ -475,13 +475,13 @@ int rc_json_get_required_array(uint32_t* num_entries, rc_json_field_t* array_fie
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (!rc_json_get_optional_array(num_entries, array_field, response, field, field_name))
|
||||
if (!rc_json_get_optional_array(num_entries, array_field, field, field_name))
|
||||
return rc_json_missing_field(response, field);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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) {
|
||||
int rc_json_get_optional_array(uint32_t* num_entries, rc_json_field_t* array_field, const rc_json_field_t* field, const char* field_name) {
|
||||
#ifndef NDEBUG
|
||||
if (strcmp(field->name, field_name) != 0)
|
||||
return 0;
|
||||
@ -783,6 +783,52 @@ int rc_json_get_required_unum(uint32_t* out, rc_api_response_t* response, const
|
||||
return rc_json_missing_field(response, field);
|
||||
}
|
||||
|
||||
int rc_json_get_float(float* out, const rc_json_field_t* field, const char* field_name) {
|
||||
int32_t whole, fraction, fraction_denominator;
|
||||
const char* decimal = field->value_start;
|
||||
|
||||
if (!decimal) {
|
||||
*out = 0.0f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!rc_json_get_num(&whole, field, field_name))
|
||||
return 0;
|
||||
|
||||
while (decimal < field->value_end && *decimal != '.')
|
||||
++decimal;
|
||||
|
||||
fraction = 0;
|
||||
fraction_denominator = 1;
|
||||
if (decimal) {
|
||||
++decimal;
|
||||
while (decimal < field->value_end && *decimal >= '0' && *decimal <= '9') {
|
||||
fraction *= 10;
|
||||
fraction += *decimal - '0';
|
||||
fraction_denominator *= 10;
|
||||
++decimal;
|
||||
}
|
||||
}
|
||||
|
||||
if (whole < 0)
|
||||
fraction = -fraction;
|
||||
|
||||
*out = (float)whole + ((float)fraction / (float)fraction_denominator);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rc_json_get_optional_float(float* out, const rc_json_field_t* field, const char* field_name, float default_value) {
|
||||
if (!rc_json_get_float(out, field, field_name))
|
||||
*out = default_value;
|
||||
}
|
||||
|
||||
int rc_json_get_required_float(float* out, rc_api_response_t* response, const rc_json_field_t* field, const char* field_name) {
|
||||
if (rc_json_get_float(out, field, field_name))
|
||||
return 1;
|
||||
|
||||
return rc_json_missing_field(response, field);
|
||||
}
|
||||
|
||||
int rc_json_get_datetime(time_t* out, const rc_json_field_t* field, const char* field_name) {
|
||||
struct tm tm;
|
||||
|
||||
|
@ -6,9 +6,7 @@
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
RC_BEGIN_C_DECLS
|
||||
|
||||
#define RC_CONTENT_TYPE_URLENCODED "application/x-www-form-urlencoded"
|
||||
|
||||
@ -47,16 +45,19 @@ int rc_json_parse_server_response(rc_api_response_t* response, const rc_api_serv
|
||||
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_float(float* 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(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_float(float* out, const rc_json_field_t* field, const char* field_name, float 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(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_optional_array(uint32_t* num_entries, rc_json_field_t* iterator, 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(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_float(float* 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);
|
||||
@ -74,8 +75,6 @@ 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);
|
||||
int rc_api_url_build_dorequest(rc_api_url_builder_t* builder, const char* api, const char* username, const char* api_token);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
RC_END_C_DECLS
|
||||
|
||||
#endif /* RC_API_COMMON_H */
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "rc_api_editor.h"
|
||||
#include "rc_api_common.h"
|
||||
#include "rc_api_runtime.h"
|
||||
|
||||
#include "../rc_compat.h"
|
||||
#include "../rhash/md5.h"
|
||||
@ -185,6 +186,15 @@ void rc_api_destroy_update_code_note_response(rc_api_update_code_note_response_t
|
||||
|
||||
/* --- Update Achievement --- */
|
||||
|
||||
static const char* rc_type_string(uint32_t type) {
|
||||
switch (type) {
|
||||
case RC_ACHIEVEMENT_TYPE_MISSABLE: return "missable";
|
||||
case RC_ACHIEVEMENT_TYPE_PROGRESSION: return "progression";
|
||||
case RC_ACHIEVEMENT_TYPE_WIN: return "win_condition";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
int rc_api_init_update_achievement_request(rc_api_request_t* request, const rc_api_update_achievement_request_t* api_params) {
|
||||
rc_api_url_builder_t builder;
|
||||
char buffer[33];
|
||||
@ -216,6 +226,7 @@ int rc_api_init_update_achievement_request(rc_api_request_t* request, const rc_a
|
||||
rc_url_builder_append_unum_param(&builder, "f", api_params->category);
|
||||
if (api_params->badge)
|
||||
rc_url_builder_append_str_param(&builder, "b", api_params->badge);
|
||||
rc_url_builder_append_str_param(&builder, "x", rc_type_string(api_params->type));
|
||||
|
||||
/* Evaluate the signature. */
|
||||
md5_init(&md5);
|
||||
|
@ -92,6 +92,20 @@ int rc_api_process_fetch_game_data_response(rc_api_fetch_game_data_response_t* r
|
||||
return rc_api_process_fetch_game_data_server_response(response, &response_obj);
|
||||
}
|
||||
|
||||
static int rc_parse_achievement_type(const char* type)
|
||||
{
|
||||
if (strcmp(type, "missable") == 0)
|
||||
return RC_ACHIEVEMENT_TYPE_MISSABLE;
|
||||
|
||||
if (strcmp(type, "win_condition") == 0)
|
||||
return RC_ACHIEVEMENT_TYPE_WIN;
|
||||
|
||||
if (strcmp(type, "progression") == 0)
|
||||
return RC_ACHIEVEMENT_TYPE_PROGRESSION;
|
||||
|
||||
return RC_ACHIEVEMENT_TYPE_STANDARD;
|
||||
}
|
||||
|
||||
int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_response_t* response, const rc_api_server_response_t* server_response) {
|
||||
rc_api_achievement_definition_t* achievement;
|
||||
rc_api_leaderboard_definition_t* leaderboard;
|
||||
@ -120,10 +134,6 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
RC_JSON_NEW_FIELD("RichPresencePatch"),
|
||||
RC_JSON_NEW_FIELD("Achievements"), /* array */
|
||||
RC_JSON_NEW_FIELD("Leaderboards") /* array */
|
||||
/* unused fields
|
||||
RC_JSON_NEW_FIELD("ForumTopicID"),
|
||||
RC_JSON_NEW_FIELD("Flags")
|
||||
* unused fields */
|
||||
};
|
||||
|
||||
rc_json_field_t achievement_fields[] = {
|
||||
@ -136,7 +146,10 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
RC_JSON_NEW_FIELD("Author"),
|
||||
RC_JSON_NEW_FIELD("BadgeName"),
|
||||
RC_JSON_NEW_FIELD("Created"),
|
||||
RC_JSON_NEW_FIELD("Modified")
|
||||
RC_JSON_NEW_FIELD("Modified"),
|
||||
RC_JSON_NEW_FIELD("Type"),
|
||||
RC_JSON_NEW_FIELD("Rarity"),
|
||||
RC_JSON_NEW_FIELD("RarityHardcore")
|
||||
};
|
||||
|
||||
rc_json_field_t leaderboard_fields[] = {
|
||||
@ -247,6 +260,35 @@ int rc_api_process_fetch_game_data_server_response(rc_api_fetch_game_data_respon
|
||||
return RC_MISSING_VALUE;
|
||||
achievement->updated = (time_t)timet;
|
||||
|
||||
achievement->type = RC_ACHIEVEMENT_TYPE_STANDARD;
|
||||
if (achievement_fields[10].value_end) {
|
||||
len = achievement_fields[10].value_end - achievement_fields[10].value_start - 2;
|
||||
if (len < sizeof(format) - 1) {
|
||||
memcpy(format, achievement_fields[10].value_start + 1, len);
|
||||
format[len] = '\0';
|
||||
achievement->type = rc_parse_achievement_type(format);
|
||||
}
|
||||
}
|
||||
|
||||
/* legacy support : if title contains[m], change type to missable and remove[m] from title */
|
||||
if (memcmp(achievement->title, "[m]", 3) == 0) {
|
||||
len = 3;
|
||||
while (achievement->title[len] == ' ')
|
||||
++len;
|
||||
achievement->title += len;
|
||||
achievement->type = RC_ACHIEVEMENT_TYPE_MISSABLE;
|
||||
}
|
||||
else if (achievement_fields[1].value_end && memcmp(achievement_fields[1].value_end - 4, "[m]", 3) == 0) {
|
||||
len = strlen(achievement->title) - 3;
|
||||
while (achievement->title[len - 1] == ' ')
|
||||
--len;
|
||||
((char*)achievement->title)[len] = '\0';
|
||||
achievement->type = RC_ACHIEVEMENT_TYPE_MISSABLE;
|
||||
}
|
||||
|
||||
rc_json_get_optional_float(&achievement->rarity, &achievement_fields[11], "Rarity", 100.0);
|
||||
rc_json_get_optional_float(&achievement->rarity_hardcore, &achievement_fields[12], "RarityHardcore", 100.0);
|
||||
|
||||
++achievement;
|
||||
}
|
||||
}
|
||||
@ -318,6 +360,11 @@ int rc_api_init_ping_request(rc_api_request_t* request, const rc_api_ping_reques
|
||||
if (api_params->rich_presence && *api_params->rich_presence)
|
||||
rc_url_builder_append_str_param(&builder, "m", api_params->rich_presence);
|
||||
|
||||
if (api_params->game_hash && *api_params->game_hash) {
|
||||
rc_url_builder_append_unum_param(&builder, "h", api_params->hardcore);
|
||||
rc_url_builder_append_str_param(&builder, "x", api_params->game_hash);
|
||||
}
|
||||
|
||||
request->post_data = rc_url_builder_finalize(&builder);
|
||||
request->content_type = RC_CONTENT_TYPE_URLENCODED;
|
||||
}
|
||||
|
@ -94,7 +94,14 @@ int rc_api_init_start_session_request(rc_api_request_t* request, const rc_api_st
|
||||
rc_url_builder_init(&builder, &request->buffer, 48);
|
||||
if (rc_api_url_build_dorequest(&builder, "startsession", api_params->username, api_params->api_token)) {
|
||||
rc_url_builder_append_unum_param(&builder, "g", api_params->game_id);
|
||||
|
||||
if (api_params->game_hash && *api_params->game_hash) {
|
||||
rc_url_builder_append_unum_param(&builder, "h", api_params->hardcore);
|
||||
rc_url_builder_append_str_param(&builder, "m", api_params->game_hash);
|
||||
}
|
||||
|
||||
rc_url_builder_append_str_param(&builder, "l", RCHEEVOS_VERSION_STRING);
|
||||
|
||||
request->post_data = rc_url_builder_finalize(&builder);
|
||||
request->content_type = RC_CONTENT_TYPE_URLENCODED;
|
||||
}
|
||||
@ -139,7 +146,7 @@ int rc_api_process_start_session_server_response(rc_api_start_session_response_t
|
||||
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) {
|
||||
if (rc_json_get_optional_array(&response->num_unlocks, &array_field, &fields[2], "Unlocks") && response->num_unlocks) {
|
||||
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 +167,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) {
|
||||
if (rc_json_get_optional_array(&response->num_hardcore_unlocks, &array_field, &fields[3], "HardcoreUnlocks") && response->num_hardcore_unlocks) {
|
||||
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;
|
||||
|
Reference in New Issue
Block a user