mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-06 03:25:36 +00:00
Achievements: Tidy up API calls
This commit is contained in:
parent
aee66edd6e
commit
6cde51b7b5
@ -239,7 +239,10 @@ RC_EXPORT void RC_CCONV rc_api_destroy_fetch_game_titles_response(rc_api_fetch_g
|
||||
* API parameters for a fetch games list request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_hash_library_request_t {
|
||||
/* The unique identifier of the console to query */
|
||||
/**
|
||||
* The unique identifier of the console to query.
|
||||
* Passing RC_CONSOLE_UNKNOWN will return hashes for all consoles.
|
||||
*/
|
||||
uint32_t console_id;
|
||||
} rc_api_fetch_hash_library_request_t;
|
||||
|
||||
|
@ -216,19 +216,19 @@ RC_EXPORT void RC_CCONV rc_api_destroy_fetch_followed_users_response(rc_api_fetc
|
||||
/* --- Fetch All Progress --- */
|
||||
|
||||
/**
|
||||
* API parameters for a fetch all progress request.
|
||||
* API parameters for a fetch all user progress request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_all_progress_request_t {
|
||||
typedef struct rc_api_fetch_all_user_progress_request_t {
|
||||
/* The username of the player */
|
||||
const char* username;
|
||||
/* The API token from the login request */
|
||||
const char* api_token;
|
||||
/* The unique identifier of the console to query */
|
||||
uint32_t console_id;
|
||||
} rc_api_fetch_all_progress_request_t;
|
||||
} rc_api_fetch_all_user_progress_request_t;
|
||||
|
||||
/* An all-progress entry */
|
||||
typedef struct rc_api_all_progress_entry_t {
|
||||
/* An all-user-progress entry */
|
||||
typedef struct rc_api_all_user_progress_entry_t {
|
||||
/* The unique identifier of the game */
|
||||
uint32_t game_id;
|
||||
/* The total number of achievements for this game */
|
||||
@ -237,25 +237,25 @@ typedef struct rc_api_all_progress_entry_t {
|
||||
uint32_t num_unlocked_achievements;
|
||||
/* The total number of unlocked achievements for this game in hardcore mode */
|
||||
uint32_t num_unlocked_achievements_hardcore;
|
||||
} rc_api_all_progress_entry_t;
|
||||
} rc_api_all_user_progress_entry_t;
|
||||
|
||||
/**
|
||||
* Response data for a fetch all progress request.
|
||||
* Response data for a fetch all user progress request.
|
||||
*/
|
||||
typedef struct rc_api_fetch_all_progress_response_t {
|
||||
typedef struct rc_api_fetch_all_user_progress_response_t {
|
||||
/* An array of entries, one per game */
|
||||
rc_api_all_progress_entry_t* entries;
|
||||
rc_api_all_user_progress_entry_t* entries;
|
||||
/* The number of items in the entries array */
|
||||
uint32_t num_entries;
|
||||
|
||||
/* Common server-provided response information */
|
||||
rc_api_response_t response;
|
||||
} rc_api_fetch_all_progress_response_t;
|
||||
} rc_api_fetch_all_user_progress_response_t;
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_all_progress_request(rc_api_request_t* request, const rc_api_fetch_all_progress_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_all_progress_request_hosted(rc_api_request_t* request, const rc_api_fetch_all_progress_request_t* api_params, const rc_api_host_t* host);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_all_progress_server_response(rc_api_fetch_all_progress_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_all_progress_response(rc_api_fetch_all_progress_response_t* response);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_all_user_progress_request(rc_api_request_t* request, const rc_api_fetch_all_user_progress_request_t* api_params);
|
||||
RC_EXPORT int RC_CCONV rc_api_init_fetch_all_user_progress_request_hosted(rc_api_request_t* request, const rc_api_fetch_all_user_progress_request_t* api_params, const rc_api_host_t* host);
|
||||
RC_EXPORT int RC_CCONV rc_api_process_fetch_all_user_progress_server_response(rc_api_fetch_all_user_progress_response_t* response, const rc_api_server_response_t* server_response);
|
||||
RC_EXPORT void RC_CCONV rc_api_destroy_fetch_all_user_progress_response(rc_api_fetch_all_user_progress_response_t* response);
|
||||
|
||||
RC_END_C_DECLS
|
||||
|
||||
|
@ -323,7 +323,7 @@ typedef struct rc_client_subset_t {
|
||||
RC_EXPORT const rc_client_subset_t* RC_CCONV rc_client_get_subset_info(rc_client_t* client, uint32_t subset_id);
|
||||
|
||||
/*****************************************************************************\
|
||||
| Game Info |
|
||||
| Fetch Game Hashes |
|
||||
\*****************************************************************************/
|
||||
|
||||
typedef struct rc_client_hash_library_entry_t
|
||||
@ -357,13 +357,16 @@ typedef void(RC_CCONV* rc_client_fetch_hash_library_callback_t)(int result, cons
|
||||
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_hash_library(
|
||||
rc_client_t* client, uint32_t console_id, rc_client_fetch_hash_library_callback_t callback, void* callback_userdata);
|
||||
|
||||
|
||||
/**
|
||||
* Destroys a previously-allocated result from the rc_client_destroy_hash_library() callback.
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_client_destroy_hash_library(rc_client_hash_library_t* list);
|
||||
|
||||
typedef struct rc_client_all_progress_list_entry_t
|
||||
/*****************************************************************************\
|
||||
| Game Info |
|
||||
\*****************************************************************************/
|
||||
|
||||
typedef struct rc_client_all_user_progress_entry_t
|
||||
{
|
||||
/* The unique identifier of the game */
|
||||
uint32_t game_id;
|
||||
@ -373,21 +376,21 @@ typedef struct rc_client_all_progress_list_entry_t
|
||||
uint32_t num_unlocked_achievements;
|
||||
/* The total number of unlocked achievements for this game in hardcore mode */
|
||||
uint32_t num_unlocked_achievements_hardcore;
|
||||
} rc_client_all_progress_list_entry_t;
|
||||
} rc_client_all_user_progress_entry_t;
|
||||
|
||||
typedef struct rc_client_all_progress_list_t
|
||||
typedef struct rc_client_all_user_progress_t
|
||||
{
|
||||
/* An array of entries, one per game */
|
||||
rc_client_all_progress_list_entry_t* entries;
|
||||
rc_client_all_user_progress_entry_t* entries;
|
||||
/* The number of items in the entries array */
|
||||
uint32_t num_entries;
|
||||
} rc_client_all_progress_list_t;
|
||||
} rc_client_all_user_progress_t;
|
||||
|
||||
/**
|
||||
* Callback that is fired when an all progress query completes. list may be null if the query failed.
|
||||
*/
|
||||
typedef void(RC_CCONV* rc_client_fetch_all_progress_list_callback_t)(int result, const char* error_message,
|
||||
rc_client_all_progress_list_t* list,
|
||||
typedef void(RC_CCONV* rc_client_fetch_all_user_progress_callback_t)(int result, const char* error_message,
|
||||
rc_client_all_user_progress_t* list,
|
||||
rc_client_t* client, void* callback_userdata);
|
||||
|
||||
/**
|
||||
@ -396,13 +399,13 @@ typedef void(RC_CCONV* rc_client_fetch_all_progress_list_callback_t)(int result,
|
||||
* the user's achievement unlock count for both softcore and hardcore modes.
|
||||
*/
|
||||
RC_EXPORT rc_client_async_handle_t* RC_CCONV
|
||||
rc_client_begin_fetch_all_progress_list(rc_client_t* client, uint32_t console_id,
|
||||
rc_client_fetch_all_progress_list_callback_t callback, void* callback_userdata);
|
||||
rc_client_begin_fetch_all_user_progress(rc_client_t* client, uint32_t console_id,
|
||||
rc_client_fetch_all_user_progress_callback_t callback, void* callback_userdata);
|
||||
|
||||
/**
|
||||
* Destroys a previously-allocated result from the rc_client_begin_fetch_all_progress_list() callback.
|
||||
*/
|
||||
RC_EXPORT void RC_CCONV rc_client_destroy_all_progress_list(rc_client_all_progress_list_t* list);
|
||||
RC_EXPORT void RC_CCONV rc_client_destroy_all_user_progress(rc_client_all_user_progress_t* list);
|
||||
|
||||
/*****************************************************************************\
|
||||
| Achievements |
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include "rc_api_common.h"
|
||||
#include "rc_api_runtime.h"
|
||||
|
||||
#include "rc_consoles.h"
|
||||
#include "rc_runtime_types.h"
|
||||
|
||||
#include "../rc_compat.h"
|
||||
@ -509,9 +508,7 @@ int rc_api_init_fetch_hash_library_request_hosted(rc_api_request_t* request,
|
||||
rc_api_url_builder_t builder;
|
||||
rc_api_url_build_dorequest_url(request, host);
|
||||
|
||||
if (api_params->console_id == RC_CONSOLE_UNKNOWN)
|
||||
return RC_INVALID_STATE;
|
||||
|
||||
/* note: unauthenticated request */
|
||||
rc_url_builder_init(&builder, &request->buffer, 48);
|
||||
rc_url_builder_append_str_param(&builder, "r", "hashlibrary");
|
||||
rc_url_builder_append_unum_param(&builder, "c", api_params->console_id);
|
||||
@ -529,7 +526,6 @@ int rc_api_process_fetch_hash_library_server_response(rc_api_fetch_hash_library_
|
||||
rc_json_iterator_t iterator;
|
||||
rc_json_field_t field;
|
||||
int result;
|
||||
char* end;
|
||||
|
||||
rc_json_field_t fields[] = {
|
||||
RC_JSON_NEW_FIELD("Success"),
|
||||
@ -545,36 +541,36 @@ int rc_api_process_fetch_hash_library_server_response(rc_api_fetch_hash_library_
|
||||
if (result != RC_OK)
|
||||
return result;
|
||||
|
||||
if (!fields[2].value_start)
|
||||
{
|
||||
if (!fields[2].value_start) {
|
||||
/* call rc_json_get_required_object to generate the error message */
|
||||
rc_json_get_required_object(NULL, 0, &response->response, &fields[2], "MD5List");
|
||||
return RC_MISSING_VALUE;
|
||||
}
|
||||
|
||||
response->num_entries = fields[2].array_size;
|
||||
rc_buffer_reserve(&response->response.buffer, response->num_entries * (32 + sizeof(rc_api_hash_library_entry_t)));
|
||||
if (response->num_entries > 0) {
|
||||
rc_buffer_reserve(&response->response.buffer, response->num_entries * (32 + sizeof(rc_api_hash_library_entry_t)));
|
||||
|
||||
response->entries = (rc_api_hash_library_entry_t*)rc_buffer_alloc(
|
||||
&response->response.buffer, response->num_entries * sizeof(rc_api_hash_library_entry_t));
|
||||
if (!response->entries)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
response->entries = (rc_api_hash_library_entry_t*)rc_buffer_alloc(
|
||||
&response->response.buffer, response->num_entries * sizeof(rc_api_hash_library_entry_t));
|
||||
if (!response->entries)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
memset(&iterator, 0, sizeof(iterator));
|
||||
iterator.json = fields[2].value_start;
|
||||
iterator.end = fields[2].value_end;
|
||||
memset(&iterator, 0, sizeof(iterator));
|
||||
iterator.json = fields[2].value_start;
|
||||
iterator.end = fields[2].value_end;
|
||||
|
||||
entry = response->entries;
|
||||
while (rc_json_get_next_object_field(&iterator, &field))
|
||||
{
|
||||
/* TODO: This isn't handling escape characters in the key, the RC JSON parsing functions have no method for it. */
|
||||
entry->hash = rc_buffer_strncpy(&response->response.buffer, field.name, field.name_len);
|
||||
entry = response->entries;
|
||||
while (rc_json_get_next_object_field(&iterator, &field)) {
|
||||
/* TODO: This isn't handling escape characters in the key, the RC JSON parsing functions have no method for it. */
|
||||
entry->hash = rc_buffer_strncpy(&response->response.buffer, field.name, field.name_len);
|
||||
|
||||
field.name = "";
|
||||
if (!rc_json_get_unum(&entry->game_id, &field, ""))
|
||||
return RC_MISSING_VALUE;
|
||||
field.name = "";
|
||||
if (!rc_json_get_unum(&entry->game_id, &field, ""))
|
||||
return RC_MISSING_VALUE;
|
||||
|
||||
++entry;
|
||||
++entry;
|
||||
}
|
||||
}
|
||||
|
||||
return RC_OK;
|
||||
|
@ -376,15 +376,15 @@ void rc_api_destroy_fetch_followed_users_response(rc_api_fetch_followed_users_re
|
||||
|
||||
/* --- Fetch All Progress --- */
|
||||
|
||||
int rc_api_init_fetch_all_progress_request(rc_api_request_t* request,
|
||||
const rc_api_fetch_all_progress_request_t* api_params)
|
||||
int rc_api_init_fetch_all_user_progress_request(rc_api_request_t* request,
|
||||
const rc_api_fetch_all_user_progress_request_t* api_params)
|
||||
{
|
||||
return rc_api_init_fetch_all_progress_request_hosted(request, api_params, &g_host);
|
||||
return rc_api_init_fetch_all_user_progress_request_hosted(request, api_params, &g_host);
|
||||
}
|
||||
|
||||
int rc_api_init_fetch_all_progress_request_hosted(rc_api_request_t* request,
|
||||
const rc_api_fetch_all_progress_request_t* api_params,
|
||||
const rc_api_host_t* host)
|
||||
int rc_api_init_fetch_all_user_progress_request_hosted(rc_api_request_t* request,
|
||||
const rc_api_fetch_all_user_progress_request_t* api_params,
|
||||
const rc_api_host_t* host)
|
||||
{
|
||||
rc_api_url_builder_t builder;
|
||||
|
||||
@ -404,14 +404,11 @@ int rc_api_init_fetch_all_progress_request_hosted(rc_api_request_t* request,
|
||||
return builder.result;
|
||||
}
|
||||
|
||||
int rc_api_process_fetch_all_progress_server_response(rc_api_fetch_all_progress_response_t* response,
|
||||
const rc_api_server_response_t* server_response)
|
||||
int rc_api_process_fetch_all_user_progress_server_response(rc_api_fetch_all_user_progress_response_t* response,
|
||||
const rc_api_server_response_t* server_response)
|
||||
{
|
||||
rc_api_all_progress_entry_t* entry;
|
||||
rc_json_iterator_t iterator;
|
||||
rc_json_field_t field;
|
||||
rc_api_all_user_progress_entry_t* entry;
|
||||
int result;
|
||||
char* end;
|
||||
|
||||
rc_json_field_t fields[] = {
|
||||
RC_JSON_NEW_FIELD("Success"),
|
||||
@ -430,51 +427,57 @@ int rc_api_process_fetch_all_progress_server_response(rc_api_fetch_all_progress_
|
||||
|
||||
result =
|
||||
rc_json_parse_server_response(&response->response, server_response, fields, sizeof(fields) / sizeof(fields[0]));
|
||||
if (result != RC_OK)
|
||||
if (result != RC_OK || !response->response.succeeded)
|
||||
return result;
|
||||
|
||||
if (!fields[2].value_start)
|
||||
{
|
||||
if (!fields[2].value_start) {
|
||||
/* call rc_json_get_required_object to generate the error message */
|
||||
rc_json_get_required_object(NULL, 0, &response->response, &fields[2], "Response");
|
||||
return RC_MISSING_VALUE;
|
||||
}
|
||||
|
||||
response->num_entries = fields[2].array_size;
|
||||
rc_buffer_reserve(&response->response.buffer, response->num_entries * sizeof(rc_api_all_progress_entry_t));
|
||||
|
||||
response->entries = (rc_api_all_progress_entry_t*)rc_buffer_alloc(
|
||||
&response->response.buffer, response->num_entries * sizeof(rc_api_all_progress_entry_t));
|
||||
if (!response->entries)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
if (response->num_entries > 0) {
|
||||
rc_json_iterator_t iterator;
|
||||
rc_json_field_t field;
|
||||
char* end;
|
||||
|
||||
memset(&iterator, 0, sizeof(iterator));
|
||||
iterator.json = fields[2].value_start;
|
||||
iterator.end = fields[2].value_end;
|
||||
rc_buffer_reserve(&response->response.buffer, response->num_entries * sizeof(rc_api_all_user_progress_entry_t));
|
||||
|
||||
entry = response->entries;
|
||||
while (rc_json_get_next_object_field(&iterator, &field))
|
||||
{
|
||||
entry->game_id = strtol(field.name, &end, 10);
|
||||
response->entries = (rc_api_all_user_progress_entry_t*)rc_buffer_alloc(
|
||||
&response->response.buffer, response->num_entries * sizeof(rc_api_all_user_progress_entry_t));
|
||||
if (!response->entries)
|
||||
return RC_OUT_OF_MEMORY;
|
||||
|
||||
field.name = "";
|
||||
if (!rc_json_get_required_object(entry_fields, sizeof(entry_fields) / sizeof(entry_fields[0]), response, &field,
|
||||
""))
|
||||
memset(&iterator, 0, sizeof(iterator));
|
||||
iterator.json = fields[2].value_start;
|
||||
iterator.end = fields[2].value_end;
|
||||
|
||||
entry = response->entries;
|
||||
while (rc_json_get_next_object_field(&iterator, &field))
|
||||
{
|
||||
return RC_MISSING_VALUE;
|
||||
entry->game_id = strtol(field.name, &end, 10);
|
||||
|
||||
field.name = "";
|
||||
if (!rc_json_get_required_object(entry_fields, sizeof(entry_fields) / sizeof(entry_fields[0]),
|
||||
&response->response, &field, ""))
|
||||
{
|
||||
return RC_MISSING_VALUE;
|
||||
}
|
||||
|
||||
rc_json_get_optional_unum(&entry->num_achievements, &entry_fields[0], "Achievements", 0);
|
||||
rc_json_get_optional_unum(&entry->num_unlocked_achievements, &entry_fields[1], "Unlocked", 0);
|
||||
rc_json_get_optional_unum(&entry->num_unlocked_achievements_hardcore, &entry_fields[2], "UnlockedHardcore", 0);
|
||||
|
||||
++entry;
|
||||
}
|
||||
|
||||
rc_json_get_optional_unum(&entry->num_achievements, &entry_fields[0], "Achievements", 0);
|
||||
rc_json_get_optional_unum(&entry->num_unlocked_achievements, &entry_fields[1], "Unlocked", 0);
|
||||
rc_json_get_optional_unum(&entry->num_unlocked_achievements_hardcore, &entry_fields[2], "UnlockedHardcore", 0);
|
||||
|
||||
++entry;
|
||||
}
|
||||
|
||||
return RC_OK;
|
||||
}
|
||||
|
||||
void rc_api_destroy_fetch_all_progress_response(rc_api_fetch_all_progress_response_t* response)
|
||||
void rc_api_destroy_fetch_all_user_progress_response(rc_api_fetch_all_user_progress_response_t* response)
|
||||
{
|
||||
rc_buffer_destroy(&response->response.buffer);
|
||||
}
|
||||
|
@ -3247,7 +3247,7 @@ static void rc_client_fetch_hash_library_callback(const rc_api_server_response_t
|
||||
else
|
||||
{
|
||||
rc_client_hash_library_t* list;
|
||||
const size_t list_size = sizeof(*list) + sizeof(rc_client_leaderboard_entry_t) * hashlib_response.num_entries;
|
||||
const size_t list_size = sizeof(*list) + sizeof(rc_client_hash_library_entry_t) * hashlib_response.num_entries;
|
||||
size_t needed_size = list_size;
|
||||
uint32_t i;
|
||||
|
||||
@ -3339,21 +3339,24 @@ void rc_client_destroy_hash_library(rc_client_hash_library_t* list)
|
||||
free(list);
|
||||
}
|
||||
|
||||
typedef struct rc_client_fetch_all_progress_callback_data_t
|
||||
/* ===== Fetch Game Hashes ===== */
|
||||
|
||||
typedef struct rc_client_fetch_all_user_progress_callback_data_t
|
||||
{
|
||||
rc_client_t* client;
|
||||
rc_client_fetch_all_progress_list_callback_t callback;
|
||||
rc_client_fetch_all_user_progress_callback_t callback;
|
||||
void* callback_userdata;
|
||||
uint32_t console_id;
|
||||
rc_client_async_handle_t async_handle;
|
||||
} rc_client_fetch_all_progress_callback_data_t;
|
||||
} rc_client_fetch_all_user_progress_callback_data_t;
|
||||
|
||||
static void rc_client_fetch_all_progress_callback(const rc_api_server_response_t* server_response, void* callback_data)
|
||||
static void rc_client_fetch_all_user_progress_callback(const rc_api_server_response_t* server_response,
|
||||
void* callback_data)
|
||||
{
|
||||
rc_client_fetch_all_progress_callback_data_t* ap_callback_data =
|
||||
(rc_client_fetch_all_progress_callback_data_t*)callback_data;
|
||||
rc_client_fetch_all_user_progress_callback_data_t* ap_callback_data =
|
||||
(rc_client_fetch_all_user_progress_callback_data_t*)callback_data;
|
||||
rc_client_t* client = ap_callback_data->client;
|
||||
rc_api_fetch_all_progress_response_t ap_response;
|
||||
rc_api_fetch_all_user_progress_response_t ap_response;
|
||||
const char* error_message;
|
||||
int result;
|
||||
|
||||
@ -3367,7 +3370,7 @@ static void rc_client_fetch_all_progress_callback(const rc_api_server_response_t
|
||||
return;
|
||||
}
|
||||
|
||||
result = rc_api_process_fetch_all_progress_server_response(&ap_response, server_response);
|
||||
result = rc_api_process_fetch_all_user_progress_server_response(&ap_response, server_response);
|
||||
error_message = rc_client_server_error_message(&result, server_response->http_status_code, &ap_response.response);
|
||||
if (error_message)
|
||||
{
|
||||
@ -3377,10 +3380,10 @@ static void rc_client_fetch_all_progress_callback(const rc_api_server_response_t
|
||||
}
|
||||
else
|
||||
{
|
||||
rc_client_all_progress_list_t* list;
|
||||
const size_t list_size = sizeof(*list) + sizeof(rc_client_all_progress_list_entry_t) * ap_response.num_entries;
|
||||
rc_client_all_user_progress_t* list;
|
||||
const size_t list_size = sizeof(*list) + sizeof(rc_client_all_user_progress_entry_t) * ap_response.num_entries;
|
||||
|
||||
list = (rc_client_all_progress_list_t*)malloc(list_size);
|
||||
list = (rc_client_all_user_progress_t*)malloc(list_size);
|
||||
if (!list)
|
||||
{
|
||||
ap_callback_data->callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client,
|
||||
@ -3388,10 +3391,10 @@ static void rc_client_fetch_all_progress_callback(const rc_api_server_response_t
|
||||
}
|
||||
else
|
||||
{
|
||||
rc_client_all_progress_list_entry_t* entry = list->entries =
|
||||
(rc_client_all_progress_list_entry_t*)((uint8_t*)list + sizeof(*list));
|
||||
const rc_api_all_progress_entry_t* hlentry = ap_response.entries;
|
||||
const rc_api_all_progress_entry_t* stop = hlentry + ap_response.num_entries;
|
||||
rc_client_all_user_progress_entry_t* entry = list->entries =
|
||||
(rc_client_all_user_progress_entry_t*)((uint8_t*)list + sizeof(*list));
|
||||
const rc_api_all_user_progress_entry_t* hlentry = ap_response.entries;
|
||||
const rc_api_all_user_progress_entry_t* stop = hlentry + ap_response.num_entries;
|
||||
|
||||
for (; hlentry < stop; ++hlentry, ++entry)
|
||||
{
|
||||
@ -3407,16 +3410,16 @@ static void rc_client_fetch_all_progress_callback(const rc_api_server_response_t
|
||||
}
|
||||
}
|
||||
|
||||
rc_api_destroy_fetch_all_progress_response(&ap_response);
|
||||
rc_api_destroy_fetch_all_user_progress_response(&ap_response);
|
||||
free(ap_callback_data);
|
||||
}
|
||||
|
||||
rc_client_async_handle_t* rc_client_begin_fetch_all_progress_list(rc_client_t* client, uint32_t console_id,
|
||||
rc_client_fetch_all_progress_list_callback_t callback,
|
||||
rc_client_async_handle_t* rc_client_begin_fetch_all_user_progress(rc_client_t* client, uint32_t console_id,
|
||||
rc_client_fetch_all_user_progress_callback_t callback,
|
||||
void* callback_userdata)
|
||||
{
|
||||
rc_api_fetch_all_progress_request_t api_params;
|
||||
rc_client_fetch_all_progress_callback_data_t* callback_data;
|
||||
rc_api_fetch_all_user_progress_request_t api_params;
|
||||
rc_client_fetch_all_user_progress_callback_data_t* callback_data;
|
||||
rc_client_async_handle_t* async_handle;
|
||||
rc_api_request_t request;
|
||||
int result;
|
||||
@ -3437,7 +3440,7 @@ rc_client_async_handle_t* rc_client_begin_fetch_all_progress_list(rc_client_t* c
|
||||
api_params.api_token = client->user.token;
|
||||
api_params.console_id = console_id;
|
||||
|
||||
result = rc_api_init_fetch_all_progress_request_hosted(&request, &api_params, &client->state.host);
|
||||
result = rc_api_init_fetch_all_user_progress_request_hosted(&request, &api_params, &client->state.host);
|
||||
|
||||
if (result != RC_OK)
|
||||
{
|
||||
@ -3446,7 +3449,7 @@ rc_client_async_handle_t* rc_client_begin_fetch_all_progress_list(rc_client_t* c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
callback_data = (rc_client_fetch_all_progress_callback_data_t*)calloc(1, sizeof(*callback_data));
|
||||
callback_data = (rc_client_fetch_all_user_progress_callback_data_t*)calloc(1, sizeof(*callback_data));
|
||||
if (!callback_data)
|
||||
{
|
||||
callback(RC_OUT_OF_MEMORY, rc_error_str(RC_OUT_OF_MEMORY), NULL, client, callback_userdata);
|
||||
@ -3460,13 +3463,13 @@ rc_client_async_handle_t* rc_client_begin_fetch_all_progress_list(rc_client_t* c
|
||||
|
||||
async_handle = &callback_data->async_handle;
|
||||
rc_client_begin_async(client, async_handle);
|
||||
client->callbacks.server_call(&request, rc_client_fetch_all_progress_callback, callback_data, client);
|
||||
client->callbacks.server_call(&request, rc_client_fetch_all_user_progress_callback, callback_data, client);
|
||||
rc_api_destroy_request(&request);
|
||||
|
||||
return rc_client_async_handle_valid(client, async_handle) ? async_handle : NULL;
|
||||
}
|
||||
|
||||
void rc_client_destroy_all_progress_list(rc_client_all_progress_list_t* list)
|
||||
void rc_client_destroy_all_user_progress(rc_client_all_user_progress_t* list)
|
||||
{
|
||||
free(list);
|
||||
}
|
||||
|
@ -218,14 +218,14 @@ static void CancelHashDatabaseRequests();
|
||||
|
||||
static void FetchHashLibraryCallback(int result, const char* error_message, rc_client_hash_library_t* list,
|
||||
rc_client_t* client, void* callback_userdata);
|
||||
static void FetchAllProgressCallback(int result, const char* error_message, rc_client_all_progress_list_t* list,
|
||||
static void FetchAllProgressCallback(int result, const char* error_message, rc_client_all_user_progress_t* list,
|
||||
rc_client_t* client, void* callback_userdata);
|
||||
|
||||
static void BuildHashDatabase(const rc_client_hash_library_t* hashlib, const rc_client_all_progress_list_t* allprog);
|
||||
static void BuildHashDatabase(const rc_client_hash_library_t* hashlib, const rc_client_all_user_progress_t* allprog);
|
||||
static bool SortAndSaveHashDatabase(Error* error);
|
||||
|
||||
static FileSystem::ManagedCFilePtr OpenProgressDatabase(bool for_write, bool truncate, Error* error);
|
||||
static void BuildProgressDatabase(const rc_client_all_progress_list_t* allprog);
|
||||
static void BuildProgressDatabase(const rc_client_all_user_progress_t* allprog);
|
||||
static void UpdateProgressDatabase(bool force);
|
||||
static void ClearProgressDatabase();
|
||||
|
||||
@ -295,7 +295,7 @@ struct State
|
||||
rc_client_async_handle_t* fetch_hash_library_request = nullptr;
|
||||
rc_client_hash_library_t* fetch_hash_library_result = nullptr;
|
||||
rc_client_async_handle_t* fetch_all_progress_request = nullptr;
|
||||
rc_client_all_progress_list_t* fetch_all_progress_result = nullptr;
|
||||
rc_client_all_user_progress_t* fetch_all_progress_result = nullptr;
|
||||
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
rc_client_async_handle_t* load_raintegration_request = nullptr;
|
||||
@ -1588,7 +1588,7 @@ void Achievements::HandleSubsetCompleteEvent(const rc_client_event_t* event)
|
||||
INFO_LOG("Subset {} ({}) complete", event->subset->title, event->subset->id);
|
||||
UpdateGameSummary(false, false);
|
||||
|
||||
if (g_settings.achievements_notifications && event->subset->badge_name)
|
||||
if (g_settings.achievements_notifications && event->subset->badge_name[0] != '\0')
|
||||
{
|
||||
// Need to grab the icon for the subset.
|
||||
std::string badge_path = GetLocalImagePath(event->subset->badge_name, RC_IMAGE_TYPE_GAME);
|
||||
@ -3960,7 +3960,7 @@ void Achievements::BeginRefreshHashDatabase()
|
||||
s_state.fetch_hash_library_request =
|
||||
rc_client_begin_fetch_hash_library(s_state.client, RC_CONSOLE_PLAYSTATION, FetchHashLibraryCallback, nullptr);
|
||||
s_state.fetch_all_progress_request =
|
||||
rc_client_begin_fetch_all_progress_list(s_state.client, RC_CONSOLE_PLAYSTATION, FetchAllProgressCallback, nullptr);
|
||||
rc_client_begin_fetch_all_user_progress(s_state.client, RC_CONSOLE_PLAYSTATION, FetchAllProgressCallback, nullptr);
|
||||
if (!s_state.fetch_hash_library_request || !s_state.fetch_hash_library_request)
|
||||
{
|
||||
ERROR_LOG("Failed to create hash database refresh requests.");
|
||||
@ -3984,7 +3984,7 @@ void Achievements::FetchHashLibraryCallback(int result, const char* error_messag
|
||||
FinishRefreshHashDatabase();
|
||||
}
|
||||
|
||||
void Achievements::FetchAllProgressCallback(int result, const char* error_message, rc_client_all_progress_list_t* list,
|
||||
void Achievements::FetchAllProgressCallback(int result, const char* error_message, rc_client_all_user_progress_t* list,
|
||||
rc_client_t* client, void* callback_userdata)
|
||||
{
|
||||
s_state.fetch_all_progress_request = nullptr;
|
||||
@ -4004,7 +4004,7 @@ void Achievements::CancelHashDatabaseRequests()
|
||||
{
|
||||
if (s_state.fetch_all_progress_result)
|
||||
{
|
||||
rc_client_destroy_all_progress_list(s_state.fetch_all_progress_result);
|
||||
rc_client_destroy_all_user_progress(s_state.fetch_all_progress_result);
|
||||
s_state.fetch_all_progress_result = nullptr;
|
||||
}
|
||||
if (s_state.fetch_all_progress_request)
|
||||
@ -4040,7 +4040,7 @@ void Achievements::FinishRefreshHashDatabase()
|
||||
BuildProgressDatabase(s_state.fetch_all_progress_result);
|
||||
|
||||
// tidy up
|
||||
rc_client_destroy_all_progress_list(s_state.fetch_all_progress_result);
|
||||
rc_client_destroy_all_user_progress(s_state.fetch_all_progress_result);
|
||||
s_state.fetch_all_progress_result = nullptr;
|
||||
rc_client_destroy_hash_library(s_state.fetch_hash_library_result);
|
||||
s_state.fetch_hash_library_result = nullptr;
|
||||
@ -4050,7 +4050,7 @@ void Achievements::FinishRefreshHashDatabase()
|
||||
}
|
||||
|
||||
void Achievements::BuildHashDatabase(const rc_client_hash_library_t* hashlib,
|
||||
const rc_client_all_progress_list_t* allprog)
|
||||
const rc_client_all_user_progress_t* allprog)
|
||||
{
|
||||
std::vector<HashDatabaseEntry> dbentries;
|
||||
dbentries.reserve(hashlib->num_entries);
|
||||
@ -4079,8 +4079,8 @@ void Achievements::BuildHashDatabase(const rc_client_hash_library_t* hashlib,
|
||||
}
|
||||
|
||||
// fill in achievement counts
|
||||
for (const rc_client_all_progress_list_entry_t& entry :
|
||||
std::span<const rc_client_all_progress_list_entry_t>(allprog->entries, allprog->num_entries))
|
||||
for (const rc_client_all_user_progress_entry_t& entry :
|
||||
std::span<const rc_client_all_user_progress_entry_t>(allprog->entries, allprog->num_entries))
|
||||
{
|
||||
// can have multiple hashes with the same game id, update count on all of them
|
||||
bool found_one = false;
|
||||
@ -4108,6 +4108,11 @@ void Achievements::BuildHashDatabase(const rc_client_hash_library_t* hashlib,
|
||||
bool Achievements::CreateHashDatabaseFromSeedDatabase(const std::string& path, Error* error)
|
||||
{
|
||||
std::optional<std::string> yaml_data = Host::ReadResourceFileToString("achievement_hashlib.yaml", false, error);
|
||||
if (!yaml_data.has_value())
|
||||
{
|
||||
Error::SetStringView(error, "Seed database is missing.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const ryml::Tree yaml =
|
||||
ryml::parse_in_place(to_csubstr(path), c4::substr(reinterpret_cast<char*>(yaml_data->data()), yaml_data->size()));
|
||||
@ -4374,7 +4379,7 @@ FileSystem::ManagedCFilePtr Achievements::OpenProgressDatabase(bool for_write, b
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Achievements::BuildProgressDatabase(const rc_client_all_progress_list_t* allprog)
|
||||
void Achievements::BuildProgressDatabase(const rc_client_all_user_progress_t* allprog)
|
||||
{
|
||||
// no point storing it in memory, just write directly to the file
|
||||
Error error;
|
||||
@ -4401,8 +4406,8 @@ void Achievements::BuildProgressDatabase(const rc_client_all_progress_list_t* al
|
||||
writer.WriteU32(games_with_unlocks);
|
||||
if (games_with_unlocks > 0)
|
||||
{
|
||||
for (const rc_client_all_progress_list_entry_t& entry :
|
||||
std::span<const rc_client_all_progress_list_entry_t>(allprog->entries, allprog->num_entries))
|
||||
for (const rc_client_all_user_progress_entry_t& entry :
|
||||
std::span<const rc_client_all_user_progress_entry_t>(allprog->entries, allprog->num_entries))
|
||||
{
|
||||
if ((entry.num_unlocked_achievements + entry.num_unlocked_achievements_hardcore) == 0)
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user