Merge pull request #2350 from leiradel/master

better rom detection; playing activity is sent asynchronously
This commit is contained in:
Twinaphex 2015-11-05 01:54:58 +01:00
commit 12bd612337

166
cheevos.c
View File

@ -1197,7 +1197,7 @@ static int cheevos_login(retro_time_t *timeout)
static void cheevo_unlocker(void *payload)
{
cheevo_t *cheevo = (cheevo_t*)payload;
unsigned cheevo_id = (unsigned)(uintptr_t)payload;
char request[256];
const char *result;
@ -1206,19 +1206,19 @@ static void cheevo_unlocker(void *payload)
snprintf(
request, sizeof(request),
"http://retroachievements.org/dorequest.php?r=awardachievement&u=%s&t=%s&a=%u&h=%d",
config_get_ptr()->cheevos.username, cheevos_locals.token, cheevo->id, 0
config_get_ptr()->cheevos.username, cheevos_locals.token, cheevo_id, 0
);
request[sizeof(request) - 1] = 0;
RARCH_LOG("CHEEVOS awarding achievement %u: %s\n", cheevo->id, request);
RARCH_LOG("CHEEVOS awarding achievement %u: %s\n", cheevo_id, request);
if (!http_get(&result, NULL, request, NULL))
{
RARCH_LOG("CHEEVOS awarded achievement %u: %s\n", cheevo->id, result);
RARCH_LOG("CHEEVOS awarded achievement %u: %s\n", cheevo_id, result);
free((void*)result);
}
else
RARCH_LOG("CHEEVOS error awarding achievement %u\n", cheevo->id);
RARCH_LOG("CHEEVOS error awarding achievement %u\n", cheevo_id);
}
}
@ -1237,7 +1237,7 @@ static void test_cheevo_set(const cheevoset_t *set)
rarch_main_msg_queue_push(cheevo->title, 0, 3 * 60, false);
rarch_main_msg_queue_push(cheevo->description, 0, 5 * 60, false);
async_job_add(cheevos_locals.jobs, cheevo_unlocker, (void*)cheevo);
async_job_add(cheevos_locals.jobs, cheevo_unlocker, (void*)(uintptr_t)cheevo->id);
cheevo->active = 0;
}
@ -1348,8 +1348,7 @@ static unsigned cheevos_get_game_id(unsigned char *hash, retro_time_t *timeout)
snprintf(
request, sizeof(request),
"http://retroachievements.org/dorequest.php?r=gameid&u=%s&m=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
config_get_ptr()->cheevos.username,
"http://retroachievements.org/dorequest.php?r=gameid&m=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
hash[ 0], hash[ 1], hash[ 2], hash[ 3],
hash[ 4], hash[ 5], hash[ 6], hash[ 7],
hash[ 8], hash[ 9], hash[10], hash[11],
@ -1374,12 +1373,13 @@ static unsigned cheevos_get_game_id(unsigned char *hash, retro_time_t *timeout)
return 0;
}
static int cheevos_playing_activity(unsigned game_id, retro_time_t *timeout)
static void cheevo_playing(void *payload)
{
unsigned game_id = (unsigned)(uintptr_t)payload;
char request[256];
const char* json;
if (!cheevos_login(timeout))
if (!cheevos_login(NULL))
{
snprintf(
request, sizeof(request),
@ -1389,17 +1389,15 @@ static int cheevos_playing_activity(unsigned game_id, retro_time_t *timeout)
request[sizeof(request) - 1] = 0;
if (!http_get(&json, NULL, request, timeout))
if (!http_get(&json, NULL, request, NULL))
{
free((void*)json);
RARCH_LOG("CHEEVOS posted playing game %u activity\n", game_id);
return 0;
return;
}
else
RARCH_LOG("CHEEVOS error posting playing game %u activity\n", game_id);
}
return -1;
}
typedef struct
@ -1576,8 +1574,6 @@ static void cheevos_fill_md5(size_t size, size_t total, MD5_CTX *ctx)
}
}
typedef unsigned (*cheevos_id_finder_t)(const struct retro_game_info *, retro_time_t);
static unsigned cheevos_find_game_id_generic(const struct retro_game_info *info, retro_time_t timeout)
{
MD5_CTX ctx;
@ -1730,28 +1726,56 @@ static unsigned cheevos_find_game_id_nes(const struct retro_game_info *info, ret
return cheevos_get_game_id(hash, &to);
}
typedef struct
{
unsigned (*finder)(const struct retro_game_info *, retro_time_t);
const char *name;
const uint32_t *ext_hashes;
} cheevos_finder_t;
int cheevos_load(const struct retro_game_info *info)
{
static const cheevos_id_finder_t finders[] =
static const uint32_t genesis_exts[] =
{
cheevos_find_game_id_genesis,
cheevos_find_game_id_generic,
cheevos_find_game_id_snes,
cheevos_find_game_id_nes,
0x0b888feeU, /* mdx */
0x005978b6U, /* md */
0x0b88aa89U, /* smd */
0x0b88767fU, /* gen */
0x0b8861beU, /* bin */
0x0b886782U, /* cue */
0x0b8880d0U, /* iso */
0x0b88aa98U, /* sms */
0x005977f3U, /* gg */
0x0059797fU, /* sg */
0
};
static const char *finders_names[] =
static const uint32_t snes_exts[] =
{
"Genesis (6Mb padding)",
"Generic (plain content)",
"SNES (8Mb padding)",
"NES (discards VROM)",
0x0b88aa88U, /* smc */
0x0b8872bbU, /* fig */
0x0b88a9a1U, /* sfc */
0x0b887623U, /* gd3 */
0x0b887627U, /* gd7 */
0x0b886bf3U, /* dx2 */
0x0b886312U, /* bsx */
0x0b88abd2U, /* swc */
0
};
static cheevos_finder_t finders[] =
{
{cheevos_find_game_id_snes, "SNES (8Mb padding)", snes_exts},
{cheevos_find_game_id_genesis, "Genesis (6Mb padding)", genesis_exts},
{cheevos_find_game_id_nes, "NES (discards VROM)", NULL},
{cheevos_find_game_id_generic, "Generic (plain content)", NULL},
};
retro_time_t timeout = 5000000;
unsigned game_id = 0;
size_t memory;
int i;
struct retro_system_info sysinfo;
const char *ext;
const char *json;
cheevos_locals.loaded = 0;
@ -1768,40 +1792,82 @@ int cheevos_load(const struct retro_game_info *info)
if (!memory)
{
rarch_main_msg_queue_push("This core doesn't support achievements", 0, 5 * 60, false);
return -1;
//return -1;
}
for (i = 0; i < sizeof(finders) / sizeof(finders[0]); i++)
{
RARCH_LOG("CHEEVOS trying method %s\n", finders_names[i]);
game_id = finders[i](info, 5000000);
if (game_id)
break;
}
/* The the supported extensions as a hint to what method we should use. */
if (game_id)
core.retro_get_system_info(&sysinfo);
ext = sysinfo.valid_extensions;
while (ext)
{
cheevos_playing_activity(game_id, &timeout);
const char *end = strchr(ext, '|');
unsigned hash;
int i, j;
if (!cheevos_get_by_game_id(&json, game_id, &timeout))
if (end)
hash = cheevos_djb2(ext, end - ext);
else
hash = cheevos_djb2(ext, strlen(ext));
ext = end + (end != NULL);
for (i = 0; i < sizeof(finders) / sizeof(finders[0]); i++)
{
if (!cheevos_parse(json))
if (finders[i].ext_hashes)
{
cheevos_deactivate_unlocks(game_id, &timeout);
free((void*)json);
cheevos_locals.loaded = 1;
return 0;
for (j = 0; finders[i].ext_hashes[j]; j++)
{
if (finders[i].ext_hashes[j] == hash)
{
RARCH_LOG("CHEEVOS testing %s\n", finders[i].name);
game_id = finders[i].finder(info, 5000000);
if (game_id)
goto found;
break;
}
}
}
free((void*)json);
}
rarch_main_msg_queue_push("Error loading achievements", 0, 5 * 60, false);
for (i = 0; i < sizeof(finders) / sizeof(finders[0]); i++)
{
if (!finders[i].ext_hashes)
{
RARCH_LOG("CHEEVOS testing %s\n", finders[i].name);
game_id = finders[i].finder(info, 5000000);
if (game_id)
goto found;
}
}
}
else
rarch_main_msg_queue_push("This game doesn't feature achievements", 0, 5 * 60, false);
rarch_main_msg_queue_push("This game doesn't feature achievements", 0, 5 * 60, false);
return -1;
found:
if (!cheevos_get_by_game_id(&json, game_id, &timeout))
{
if (!cheevos_parse(json))
{
cheevos_deactivate_unlocks(game_id, &timeout);
free((void*)json);
cheevos_locals.loaded = 1;
async_job_add(cheevos_locals.jobs, cheevo_playing, (void*)(uintptr_t)game_id);
return 0;
}
free((void*)json);
}
rarch_main_msg_queue_push("Error loading achievements", 0, 5 * 60, false);
return -1;
}