mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 21:32:45 +00:00
add delay retries to leaderboard submits
This commit is contained in:
parent
ca6b07cc47
commit
db5358f70f
@ -133,7 +133,8 @@ typedef struct
|
||||
enum rcheevos_async_io_type
|
||||
{
|
||||
CHEEVOS_ASYNC_RICHPRESENCE,
|
||||
CHEEVOS_ASYNC_AWARD_ACHIEVEMENT
|
||||
CHEEVOS_ASYNC_AWARD_ACHIEVEMENT,
|
||||
CHEEVOS_ASYNC_SUBMIT_LBOARD
|
||||
};
|
||||
|
||||
typedef struct rcheevos_async_io_request
|
||||
@ -143,6 +144,8 @@ typedef struct rcheevos_async_io_request
|
||||
int attempt_count;
|
||||
char type;
|
||||
char hardcore;
|
||||
char* success_message;
|
||||
char* failure_message;
|
||||
char user_agent[256];
|
||||
} rcheevos_async_io_request;
|
||||
|
||||
@ -373,6 +376,7 @@ static void rcheevos_log_url(const char* format, const char* url)
|
||||
|
||||
static retro_time_t rcheevos_async_send_rich_presence(rcheevos_async_io_request* request);
|
||||
static void rcheevos_async_award_achievement(rcheevos_async_io_request* request);
|
||||
static void rcheevos_async_submit_lboard(rcheevos_async_io_request* request);
|
||||
|
||||
static void rcheevos_async_task_handler(retro_task_t* task)
|
||||
{
|
||||
@ -398,6 +402,11 @@ static void rcheevos_async_task_handler(retro_task_t* task)
|
||||
rcheevos_async_award_achievement(request);
|
||||
task_set_finished(task, 1);
|
||||
break;
|
||||
|
||||
case CHEEVOS_ASYNC_SUBMIT_LBOARD:
|
||||
rcheevos_async_submit_lboard(request);
|
||||
task_set_finished(task, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,6 +420,28 @@ static void rcheevos_async_schedule(rcheevos_async_io_request* request, retro_ti
|
||||
task_queue_push(task);
|
||||
}
|
||||
|
||||
static void rcheevos_async_task_callback(retro_task_t* task, void* task_data, void* user_data, const char* error)
|
||||
{
|
||||
rcheevos_async_io_request* request = (rcheevos_async_io_request*)user_data;
|
||||
|
||||
if (!error)
|
||||
{
|
||||
CHEEVOS_LOG(RCHEEVOS_TAG "%s %u\n", request->success_message, request->id);
|
||||
free(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* double the wait between each attempt until we hit a maximum delay of two minutes
|
||||
* 250ms -> 500ms -> 1s -> 2s -> 4s -> 8s -> 16s -> 32s -> 64s -> 120s -> 120s... */
|
||||
retro_time_t retry_delay = (request->attempt_count > 8) ? (120 * 1000 * 1000) : ((250 * 1000) << request->attempt_count);
|
||||
|
||||
request->attempt_count++;
|
||||
rcheevos_async_schedule(request, retry_delay);
|
||||
|
||||
CHEEVOS_ERR(RCHEEVOS_TAG "%s %u: %s\n", request->failure_message, request->id, error);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* rcheevos_rc_error(int ret)
|
||||
{
|
||||
switch (ret)
|
||||
@ -686,28 +717,6 @@ error:
|
||||
Test all the achievements (call once per frame).
|
||||
*****************************************************************************/
|
||||
|
||||
static void rcheevos_award_task_callback(retro_task_t* task, void* task_data, void* user_data, const char* error)
|
||||
{
|
||||
rcheevos_async_io_request* request = (rcheevos_async_io_request*)user_data;
|
||||
|
||||
if (!error)
|
||||
{
|
||||
CHEEVOS_LOG(RCHEEVOS_TAG "Awarded achievement %u\n", request->id);
|
||||
free(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* double the wait between each attempt until we hit a maximum delay of two minutes
|
||||
* 250ms -> 500ms -> 1s -> 2s -> 4s -> 8s -> 16s -> 32s -> 64s -> 120s -> 120s... */
|
||||
retro_time_t retry_delay = (request->attempt_count > 8) ? (120 * 1000 * 1000) : ((250 * 1000) << request->attempt_count);
|
||||
|
||||
request->attempt_count++;
|
||||
rcheevos_async_schedule(request, retry_delay);
|
||||
|
||||
CHEEVOS_ERR(RCHEEVOS_TAG "Error awarding achievement %u: %s\n", request->id, error);
|
||||
}
|
||||
}
|
||||
|
||||
static void rcheevos_async_award_achievement(rcheevos_async_io_request* request)
|
||||
{
|
||||
char buffer[256];
|
||||
@ -722,7 +731,7 @@ static void rcheevos_async_award_achievement(rcheevos_async_io_request* request)
|
||||
}
|
||||
|
||||
rcheevos_log_url(RCHEEVOS_TAG "rc_url_award_cheevo: %s\n", buffer);
|
||||
task_push_http_transfer_with_user_agent(buffer, true, NULL, request->user_agent, rcheevos_award_task_callback, request);
|
||||
task_push_http_transfer_with_user_agent(buffer, true, NULL, request->user_agent, rcheevos_async_task_callback, request);
|
||||
}
|
||||
|
||||
static void rcheevos_award(rcheevos_cheevo_t* cheevo, int mode)
|
||||
@ -761,6 +770,8 @@ static void rcheevos_award(rcheevos_cheevo_t* cheevo, int mode)
|
||||
request->type = CHEEVOS_ASYNC_AWARD_ACHIEVEMENT;
|
||||
request->id = cheevo->info->id;
|
||||
request->hardcore = ((mode & RCHEEVOS_ACTIVE_HARDCORE) != 0) ? 1 : 0;
|
||||
request->success_message = "Awarded achievement";
|
||||
request->failure_message = "Error awarding achievement";
|
||||
rcheevos_get_user_agent(request->user_agent);
|
||||
rcheevos_async_award_achievement(request);
|
||||
}
|
||||
@ -891,51 +902,22 @@ static void rcheevos_test_cheevo_set(bool official)
|
||||
}
|
||||
}
|
||||
|
||||
static void rcheevos_lboard_submit_task(retro_task_t *task, void* task_data, void* user_data,
|
||||
const char* error)
|
||||
static void rcheevos_async_submit_lboard(rcheevos_async_io_request* request)
|
||||
{
|
||||
int ret;
|
||||
MD5_CTX ctx;
|
||||
uint8_t hash[16];
|
||||
char signature[64];
|
||||
char buffer[256];
|
||||
char user_agent[256];
|
||||
const rcheevos_lboard_t* lboard = (const rcheevos_lboard_t*)user_data;
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *cheevos_username = settings->arrays.cheevos_username;
|
||||
|
||||
if (!error)
|
||||
{
|
||||
CHEEVOS_LOG(RCHEEVOS_TAG "Submitted leaderboard %u\n", lboard->info->id);
|
||||
return;
|
||||
}
|
||||
|
||||
CHEEVOS_ERR(RCHEEVOS_TAG "Error submitting leaderboard %u: %s\n", lboard->info->id, error);
|
||||
|
||||
/* Try again. */
|
||||
|
||||
/* Evaluate the signature. */
|
||||
snprintf(signature, sizeof(signature), "%u%s%u", lboard->info->id,
|
||||
cheevos_username, lboard->info->id);
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, (void*)signature, strlen(signature));
|
||||
MD5_Final(hash, &ctx);
|
||||
|
||||
/* Start the request. */
|
||||
ret = rc_url_submit_lboard(buffer, sizeof(buffer), cheevos_username,
|
||||
rcheevos_locals.token, lboard->info->id, lboard->last_value, hash);
|
||||
settings_t *settings = config_get_ptr();
|
||||
int ret = rc_url_submit_lboard(buffer, sizeof(buffer), settings->arrays.cheevos_username,
|
||||
rcheevos_locals.token, request->id, request->value, rcheevos_locals.hash);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
CHEEVOS_ERR(RCHEEVOS_TAG "Buffer to small to create URL\n");
|
||||
CHEEVOS_ERR(RCHEEVOS_TAG "Buffer too small to create URL\n");
|
||||
free(request);
|
||||
return;
|
||||
}
|
||||
|
||||
rcheevos_get_user_agent(user_agent);
|
||||
|
||||
rcheevos_log_url(RCHEEVOS_TAG "rc_url_submit_lboard: %s\n", buffer);
|
||||
task_push_http_transfer_with_user_agent(buffer, true, NULL, user_agent, rcheevos_lboard_submit_task, user_data);
|
||||
task_push_http_transfer_with_user_agent(buffer, true, NULL, request->user_agent, rcheevos_async_task_callback, request);
|
||||
}
|
||||
|
||||
static void rcheevos_lboard_submit(rcheevos_lboard_t* lboard)
|
||||
@ -962,7 +944,16 @@ static void rcheevos_lboard_submit(rcheevos_lboard_t* lboard)
|
||||
runloop_msg_queue_push(buffer, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
|
||||
/* Start the submit task. */
|
||||
rcheevos_lboard_submit_task(NULL, NULL, lboard, "no error, first try");
|
||||
{
|
||||
rcheevos_async_io_request* request = (rcheevos_async_io_request*)calloc(1, sizeof(rcheevos_async_io_request));
|
||||
request->type = CHEEVOS_ASYNC_SUBMIT_LBOARD;
|
||||
request->id = lboard->info->id;
|
||||
request->value = lboard->last_value;
|
||||
request->success_message = "Submitted leaderboard";
|
||||
request->failure_message = "Error submitting leaderboard";
|
||||
rcheevos_get_user_agent(request->user_agent);
|
||||
rcheevos_async_submit_lboard(request);
|
||||
}
|
||||
}
|
||||
|
||||
static void rcheevos_test_leaderboards(void)
|
||||
|
2
deps/rcheevos/include/rurl.h
vendored
2
deps/rcheevos/include/rurl.h
vendored
@ -9,7 +9,7 @@ extern "C" {
|
||||
|
||||
int rc_url_award_cheevo(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned cheevo_id, int hardcore);
|
||||
|
||||
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, int value, unsigned char hash[16]);
|
||||
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, int value, const char* game_hash);
|
||||
|
||||
int rc_url_get_gameid(char* buffer, size_t size, unsigned char hash[16]);
|
||||
|
||||
|
29
deps/rcheevos/src/rurl/url.c
vendored
29
deps/rcheevos/src/rurl/url.c
vendored
@ -1,6 +1,18 @@
|
||||
#include "rurl.h"
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include <rhash.h> /* libretro-common/include/rhash.h */
|
||||
#define md5_state_t MD5_CTX
|
||||
#define md5_byte_t unsigned char
|
||||
#define md5_init(state) MD5_Init(state)
|
||||
#define md5_append(state, buffer, size) MD5_Update(state, buffer, size)
|
||||
#define md5_finish(state, hash) MD5_Final(hash, state)
|
||||
#else
|
||||
#include "..\rhash\md5.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int rc_url_encode(char* encoded, size_t len, const char* str) {
|
||||
for (;;) {
|
||||
@ -69,9 +81,12 @@ int rc_url_award_cheevo(char* buffer, size_t size, const char* user_name, const
|
||||
return (size_t)written >= size ? -1 : 0;
|
||||
}
|
||||
|
||||
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, int value, unsigned char hash[16]) {
|
||||
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, int value, const char* game_hash) {
|
||||
char urle_user_name[64];
|
||||
char urle_login_token[64];
|
||||
char signature[64];
|
||||
unsigned char hash[16];
|
||||
md5_state_t state;
|
||||
int written;
|
||||
|
||||
if (rc_url_encode(urle_user_name, sizeof(urle_user_name), user_name) != 0) {
|
||||
@ -81,7 +96,13 @@ int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const
|
||||
if (rc_url_encode(urle_login_token, sizeof(urle_login_token), login_token) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Evaluate the signature. */
|
||||
snprintf(signature, sizeof(signature), "%u%s%u", lboard_id, user_name, lboard_id);
|
||||
md5_init(&state);
|
||||
md5_append(&state, (unsigned char*)signature, (int)strlen(signature));
|
||||
md5_finish(&state, hash);
|
||||
|
||||
written = snprintf(
|
||||
buffer,
|
||||
size,
|
||||
@ -94,6 +115,10 @@ int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const
|
||||
hash[ 8], hash[ 9], hash[10], hash[11],hash[12], hash[13], hash[14], hash[15]
|
||||
);
|
||||
|
||||
if (game_hash && strlen(game_hash) == 32 && (size - (size_t)written) >= 35) {
|
||||
written += snprintf(buffer + written, size - (size_t)written, "&m=%s", game_hash);
|
||||
}
|
||||
|
||||
return (size_t)written >= size ? -1 : 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user