Leaderboards

Fixed crashing errors for certain leaderboard expressions, added OSD messages, enable/disable options in menus, only allow LBs in hardcore mode, read FormatType and display accordingly on submit, memaddr patching for LB values (may not actually be needed), preliminary RPS stuff.
This commit is contained in:
celerizer 2017-10-31 01:08:29 -05:00 committed by GitHub
parent 3ada77d154
commit 1fe0002a21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -52,6 +52,8 @@
#include "../verbosity.h"
#define CHEEVOS_ENABLE_LBOARDS
/* Define this macro to prevent cheevos from being deactivated. */
#undef CHEEVOS_DONT_DEACTIVATE
@ -120,6 +122,16 @@ enum
CHEEVOS_ACTIVE_HARDCORE = 1 << 1
};
enum
{
CHEEVOS_FORMAT_FRAMES = 0,
CHEEVOS_FORMAT_SECS,
CHEEVOS_FORMAT_MILLIS,
CHEEVOS_FORMAT_SCORE,
CHEEVOS_FORMAT_VALUE,
CHEEVOS_FORMAT_OTHER
};
typedef struct
{
cheevos_cond_t *conds;
@ -220,6 +232,7 @@ typedef struct
typedef struct
{
unsigned id;
unsigned format;
const char *title;
const char *description;
int active;
@ -231,6 +244,20 @@ typedef struct
cheevos_expr_t value;
} cheevos_leaderboard_t;
typedef struct
{
cheevos_expr_t value;
char* prestring;
} cheevos_rps_value_t;
//store all strings preceding a value in value_t, store end of Display here
typedef struct
{
cheevos_rps_value_t* values;
unsigned count;
char* finalstring;
} cheevos_rps_t;
typedef struct
{
int console_id;
@ -242,6 +269,7 @@ typedef struct
cheevoset_t core;
cheevoset_t unofficial;
cheevos_leaderboard_t *leaderboards;
cheevos_rps_t script;
unsigned lboard_count;
char token[32];
@ -937,6 +965,8 @@ static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem)
unsigned i;
expr->count = 1;
printf("i got here\n");
for (aux = mem; *aux != '"'; aux++)
{
expr->count += *aux == '_';
@ -945,19 +975,33 @@ static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem)
expr->terms = (cheevos_term_t*)calloc(expr->count, sizeof(cheevos_term_t));
if (!expr->terms)
{
printf("uh oh\n");
return -1;
}
for (i = 0, aux = mem; i < expr->count; i++)
{
cheevos_var_parse(&expr->terms[i].var, &aux);
printf("%c",aux[0]);
if (*aux != '*')
{
// expression has no multiplier
if (*aux == '\0' || *aux == '_' || *aux == '"')
{
expr->terms[i].multiplier = 1;
}
// invalid character in expression
else
{
free((void*)expr->terms);
return -1;
}
}
else
expr->terms[i].multiplier = (int)strtol(aux + 1, &end, 10);
aux = end + 1;
}
@ -977,23 +1021,28 @@ static int cheevos_parse_mem(cheevos_leaderboard_t *lb, const char* mem)
{
if (*mem == 'S' && mem[1] == 'T' && mem[2] == 'A' && mem[3] == ':')
{
//printf("%u\n",mem[0]);
if (cheevos_parse_condition(&lb->start, mem + 4))
goto error;
}
else if (*mem == 'C' && mem[1] == 'A' && mem[2] == 'N' && mem[3] == ':')
{
//printf("%u\n",mem[0]);
if (cheevos_parse_condition(&lb->cancel, mem + 4))
goto error;
}
else if (*mem == 'S' && mem[1] == 'U' && mem[2] == 'B' && mem[3] == ':')
{
//printf("%u\n",mem[0]);
if (cheevos_parse_condition(&lb->submit, mem + 4))
goto error;
}
else if (*mem == 'V' && mem[1] == 'A' && mem[2] == 'L' && mem[3] == ':')
{
//printf("%u",mem[0]);
if (cheevos_parse_expression(&lb->value, mem + 4))
goto error;
//printf("%uokay\n",mem[0]);
}
else
goto error;
@ -1080,20 +1129,90 @@ error:
return -1;
}
/*****************************************************************************
Helper functions for displaying leaderboard values.
*****************************************************************************/
static INLINE const char *cheevos_print_frames(const unsigned value)
{
unsigned mins, secs, millis;
char *string = (char*)malloc(16);
mins = value / 3600;
secs = (value % 3600) / 60;
millis = (int) (value % 60) * (10.00 / 6.00);
snprintf(string, 16, "%02u:%02u.%02u", mins, secs, millis);
return string;
}
static INLINE const char *cheevos_print_millis(const unsigned value)
{
unsigned mins, secs, millis;
char *string = (char*)malloc(16);
mins = value / 6000;
secs = (value % 6000) / 100;
millis = (int) (value % 100);
snprintf(string, 16, "%02u:%02u.%02u", mins, secs, millis);
return string;
}
static INLINE const char *cheevos_print_secs(const unsigned value)
{
unsigned mins, secs;
char *string = (char*)malloc(16);
mins = value / 60;
secs = value % 60;
snprintf(string, 16, "%02u:%02u", mins, secs);
return string;
}
unsigned cheevos_parse_format(const char* format)
{
if (strcmp(format, "VALUE") == 0)
return CHEEVOS_FORMAT_VALUE;
else if (strcmp(format, "TIME") == 0)
return CHEEVOS_FORMAT_FRAMES;
else if (strcmp(format, "TIMESECS") == 0)
return CHEEVOS_FORMAT_SECS;
else if (strcmp(format, "MILLISECS") == 0)
return CHEEVOS_FORMAT_MILLIS;
else if (strcmp(format, "SCORE") == 0)
return CHEEVOS_FORMAT_SCORE;
else
return CHEEVOS_FORMAT_OTHER;
}
#ifdef CHEEVOS_ENABLE_LBOARDS
static int cheevos_new_lboard(cheevos_readud_t *ud)
{
cheevos_leaderboard_t *lboard = cheevos_locals.leaderboards + ud->lboard_count++;
lboard->id = strtol(ud->id.string, NULL, 10);
lboard->format = cheevos_parse_format(cheevos_dupstr(&ud->format));
lboard->title = cheevos_dupstr(&ud->title);
lboard->description = cheevos_dupstr(&ud->desc);
printf("format: %u\n",lboard->format);
if (!lboard->title || !lboard->description)
{
printf("wtf is my name\n");
goto error;
}
if (cheevos_parse_mem(lboard, ud->memaddr.string))
{
printf("dammit im dead\n");
goto error;
}
#ifdef CHEEVOS_VERBOSE
cheevos_log_lboard(lboard);
@ -1320,6 +1439,8 @@ static int cheevos_test_condition(cheevos_cond_t *cond)
unsigned sval = cheevos_var_get_value(&cond->source) + cheevos_locals.add_buffer;
unsigned tval = cheevos_var_get_value(&cond->target);
printf("is %u = %u?\n",sval,tval);
switch (cond->op)
{
case CHEEVOS_COND_OP_EQUALS:
@ -1772,6 +1893,11 @@ static void cheevos_test_leaderboards(void)
lboard->last_value = value;
}
char msg[256];
snprintf(msg, sizeof(msg), "Value: %u", value);
msg[sizeof(msg) - 1] = 0;
runloop_msg_queue_push(msg, 0, 1, false);
if (cheevos_test_lboard_condition(&lboard->submit))
{
char url[256];
@ -1780,12 +1906,39 @@ static void cheevos_test_leaderboards(void)
task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard);
RARCH_LOG("[CHEEVOS]: submit lboard %s\n", lboard->title);
lboard->active = 0;
char msg[256];
switch(lboard->format)
{
case CHEEVOS_FORMAT_VALUE:
snprintf(msg, sizeof(msg), "Submitted %u for %s", value, lboard->title);
break;
case CHEEVOS_FORMAT_SCORE:
snprintf(msg, sizeof(msg), "Submitted %06upts for %s", value, lboard->title);
break;
case CHEEVOS_FORMAT_FRAMES:
snprintf(msg, sizeof(msg), "Submitted %s for %s", cheevos_print_frames(value), lboard->title);
break;
case CHEEVOS_FORMAT_SECS:
snprintf(msg, sizeof(msg), "Submitted %s for %s", cheevos_print_secs(value), lboard->title);
break;
case CHEEVOS_FORMAT_MILLIS:
snprintf(msg, sizeof(msg), "Submitted %s for %s", cheevos_print_millis(value), lboard->title);
break;
default:
snprintf(msg, sizeof(msg), "Tried to submit %u for %s", value, lboard->title);
}
msg[sizeof(msg) - 1] = 0;
runloop_msg_queue_push(msg, 0, 3 * 60, false);
}
if (cheevos_test_lboard_condition(&lboard->cancel))
{
RARCH_LOG("[CHEEVOS]: cancel lboard %s\n", lboard->title);
lboard->active = 0;
runloop_msg_queue_push("Leaderboard attempt cancelled!", 0, 3 * 60, false);
}
}
else
@ -1795,6 +1948,12 @@ static void cheevos_test_leaderboards(void)
RARCH_LOG("[CHEEVOS]: start lboard %s\n", lboard->title);
lboard->active = 1;
lboard->last_value = -1;
char msg[256];
snprintf(msg, sizeof(msg), "Leaderboard Active: %s", lboard->title);
msg[sizeof(msg) - 1] = 0;
runloop_msg_queue_push(msg, 0, 3 * 60, false);
runloop_msg_queue_push(lboard->description, 0, 5*60, false);
}
}
}
@ -2126,9 +2285,9 @@ static void cheevos_patch_addresses(cheevoset_t* set)
{
case CHEEVOS_VAR_TYPE_ADDRESS:
case CHEEVOS_VAR_TYPE_DELTA_MEM:
cheevos_var_patch_addr(&cond->source, cheevos_locals.console_id);
cheevos_var_patch_addr(&cond->source, cond->source.value);
#ifdef CHEEVOS_DUMP_ADDRS
RARCH_LOG("[CHEEVOS]: var %03d:%08X\n", cond->source.bank_id + 1, cond->source.value);
RARCH_LOG("[CHEEVOS]: s-var %03d:%08X\n", cond->source.bank_id + 1, cond->source.value);
#endif
break;
@ -2140,9 +2299,9 @@ static void cheevos_patch_addresses(cheevoset_t* set)
{
case CHEEVOS_VAR_TYPE_ADDRESS:
case CHEEVOS_VAR_TYPE_DELTA_MEM:
cheevos_var_patch_addr(&cond->target, cheevos_locals.console_id);
cheevos_var_patch_addr(&cond->target, cond->target.value);
#ifdef CHEEVOS_DUMP_ADDRS
RARCH_LOG("[CHEEVOS]: var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value);
RARCH_LOG("[CHEEVOS]: t-var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value);
#endif
break;
@ -2154,6 +2313,61 @@ static void cheevos_patch_addresses(cheevoset_t* set)
}
}
static void cheevos_patch_lb_addresses(cheevos_condition_t* condition)
{
unsigned j,k;
cheevos_condset_t* condset = condition->condsets;
for (j = condition->count; j != 0; j--, condset++)
{
cheevos_cond_t* cond = condset->conds;
for (k = condset->count; k != 0; k--, cond++)
{
switch (cond->source.type)
{
case CHEEVOS_VAR_TYPE_ADDRESS:
case CHEEVOS_VAR_TYPE_DELTA_MEM:
cheevos_var_patch_addr(&cond->source, cond->source.value);
#ifdef CHEEVOS_DUMP_ADDRS
RARCH_LOG("[CHEEVOS]: s-var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value);
#endif
break;
default:
break;
}
switch (cond->target.type)
{
case CHEEVOS_VAR_TYPE_ADDRESS:
case CHEEVOS_VAR_TYPE_DELTA_MEM:
cheevos_var_patch_addr(&cond->target, cond->target.value);
#ifdef CHEEVOS_DUMP_ADDRS
RARCH_LOG("[CHEEVOS]: t-var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value);
#endif
break;
default:
break;
}
}
}
}
static void cheevos_patch_lbs(cheevos_leaderboard_t *leaderboard)
{
unsigned i;
for(i = 0; i < cheevos_locals.lboard_count; i++)
{
cheevos_condition_t* start = &leaderboard[i].start;
cheevos_condition_t* cancel = &leaderboard[i].cancel;
cheevos_condition_t* submit = &leaderboard[i].submit;
//cheevos_patch_lb_addresses(start);
//cheevos_patch_lb_addresses(cancel);
//cheevos_patch_lb_addresses(submit);
}
}
void cheevos_test(void)
{
settings_t *settings = config_get_ptr();
@ -2162,16 +2376,18 @@ void cheevos_test(void)
{
cheevos_patch_addresses(&cheevos_locals.core);
cheevos_patch_addresses(&cheevos_locals.unofficial);
//cheevos_patch_lbs(cheevos_locals.leaderboards);
cheevos_locals.addrs_patched = true;
}
cheevos_test_cheevo_set(&cheevos_locals.core);
//cheevos_test_cheevo_set(&cheevos_locals.core);
if (settings->bools.cheevos_test_unofficial)
cheevos_test_cheevo_set(&cheevos_locals.unofficial);
//if (settings->bools.cheevos_test_unofficial)
//cheevos_test_cheevo_set(&cheevos_locals.unofficial);
#ifdef CHEEVOS_ENABLE_LBOARDS
if (settings->bools.cheevos_hardcore_mode_enable && settings->bools.cheevos_leaderboards_enable)
cheevos_test_leaderboards();
#endif
}