diff --git a/cheevos.c b/cheevos.c index 2f34e0baa5..509ec7fe50 100644 --- a/cheevos.c +++ b/cheevos.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include "cheevos.h" @@ -981,7 +983,7 @@ static int test_cheevo( cheevo_t* cheevo ) if ( condset < end ) { ret_val = test_cond_set( condset, &dirty_conds, &reset_conds, 0 ); - if ( ret_val ) RARCH_LOG( "%s\n", condset->expression ); + if ( ret_val ) RARCH_LOG( "CHEEVOS %s\n", condset->expression ); condset++; } @@ -989,7 +991,7 @@ static int test_cheevo( cheevo_t* cheevo ) { int res = test_cond_set( condset, &dirty_conds, &reset_conds, 0 ); ret_val_sub_cond |= res; - if ( res ) RARCH_LOG( "%s\n", condset->expression ); + if ( res ) RARCH_LOG( "CHEEVOS %s\n", condset->expression ); condset++; } @@ -1025,8 +1027,12 @@ static void test_cheevo_set( const cheevoset_t* set ) { if ( cheevo->active && test_cheevo( cheevo ) ) { - RARCH_LOG( "ACHIEVEMENT! %s\n", cheevo->title ); - RARCH_LOG( "ACHIEVEMENT! %s\n", cheevo->description ); + RARCH_LOG( "CHEEVOS %s\n", cheevo->title ); + RARCH_LOG( "CHEEVOS %s\n", cheevo->description ); + + rarch_main_msg_queue_push( cheevo->title, 0, 3 * 60, false ); + rarch_main_msg_queue_push( cheevo->description, 0, 5 * 60, false ); + cheevo->active = 0; } } @@ -1097,7 +1103,7 @@ static const char* cheevos_http_get( const char* url, size_t* size ) size_t length; char* result; - RARCH_LOG( "HTTP GET %s\n", url ); + RARCH_LOG( "CHEEVOS http get %s\n", url ); conn = net_http_connection_new( url ); if ( !conn ) @@ -1145,7 +1151,7 @@ error1: net_http_delete( http ); net_http_connection_free( conn ); - RARCH_LOG( "HTTP result is %s\n", result ); + RARCH_LOG( "CHEEVOS http result is %s\n", result ); if ( size ) { @@ -1156,8 +1162,8 @@ error1: #else /* HAVE_NETWORKING */ - RARCH_LOG( "HTTP GET %s\n", url ); - RARCH_ERROR( "Network unavailable\n" ); + RARCH_LOG( "CHEEVOS http get %s\n", url ); + RARCH_ERROR( "CHEEVOS Network unavailable\n" ); if ( size ) { @@ -1292,7 +1298,7 @@ static int cheevos_login( void ) res = cheevos_get_value( json, 0x0e2dbd26U /* Token */, cheevos_config.token, sizeof( cheevos_config.token ) ); } - RARCH_LOG( "cheevos user token is %s\n", cheevos_config.token ); + RARCH_LOG( "CHEEVOS user token is %s\n", cheevos_config.token ); return res; } @@ -1320,42 +1326,14 @@ int cheevos_get_by_game_id( const char** json, unsigned game_id ) return 0; } -#define CHEEVOS_EIGHT_MB ( 8 * 1024 * 1024 ) - -int cheevos_get_by_content( const char** json, const void* data, size_t size, unsigned flags ) +static unsigned cheevos_get_game_id( unsigned char* hash ) { MD5_CTX ctx; - char buffer[ 4096 ]; - size_t len; - unsigned char hash[ 16 ]; char request[ 256 ]; + const char* json; char game_id[ 16 ]; int res; - MD5_Init( &ctx ); - MD5_Update( &ctx, data, size ); - - if ( ( flags & CHEEVOS_FLAGS_IS_SNES ) && size < CHEEVOS_EIGHT_MB ) - { - size = CHEEVOS_EIGHT_MB - size; - memset( (void*)buffer, 0, sizeof( buffer ) ); - - while ( size ) - { - len = sizeof( buffer ); - - if ( len > size ) - { - len = size; - } - - MD5_Update( &ctx, (void*)buffer, len ); - size -= len; - } - } - - MD5_Final( hash, &ctx ); - 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", @@ -1368,23 +1346,69 @@ int cheevos_get_by_content( const char** json, const void* data, size_t size, un request[ sizeof( request ) - 1 ] = 0; - *json = cheevos_http_get( request, NULL ); + json = cheevos_http_get( request, NULL ); - if ( !*json ) + if ( !json ) { return -1; } - res = cheevos_get_value( *json, 0xb4960eecU /* GameID */, game_id, sizeof( game_id ) ); - free( (void*)*json ); + res = cheevos_get_value( json, 0xb4960eecU /* GameID */, game_id, sizeof( game_id ) ); + free( (void*)json ); - if ( !res ) + return res ? 0 : strtoul( game_id, NULL, 10 ); +} + +#define CHEEVOS_EIGHT_MB ( 8 * 1024 * 1024 ) + +int cheevos_get_by_content( const char** json, const void* data, size_t size ) +{ + MD5_CTX ctx, saved_ctx; + char buffer[ 4096 ]; + size_t len; + unsigned char hash[ 16 ]; + char request[ 256 ]; + unsigned game_id; + int res; + + MD5_Init( &ctx ); + MD5_Update( &ctx, data, size ); + saved_ctx = ctx; + MD5_Final( hash, &ctx ); + + game_id = cheevos_get_game_id( hash ); + + if ( !game_id ) { - RARCH_LOG( "game id is %s\n", game_id ); - res = cheevos_get_by_game_id( json, strtoul( game_id, NULL, 10 ) ); + /* If the content is a SNES game, continue MD5 with zeroes. */ + size = CHEEVOS_EIGHT_MB - size; + memset( (void*)buffer, 0, sizeof( buffer ) ); + + while ( size ) + { + len = sizeof( buffer ); + + if ( len > size ) + { + len = size; + } + + MD5_Update( &saved_ctx, (void*)buffer, len ); + size -= len; + } + + MD5_Final( hash, &saved_ctx ); + + game_id = cheevos_get_game_id( hash ); + + if ( !game_id ) + { + return -1; + } } - return res; + RARCH_LOG( "CHEEVOS game id is %u\n", game_id ); + return cheevos_get_by_game_id( json, game_id ); } #else /* HAVE_CHEEVOS */ diff --git a/cheevos.h b/cheevos.h index a8dfdc27f0..ce37e89495 100644 --- a/cheevos.h +++ b/cheevos.h @@ -29,17 +29,12 @@ typedef struct } cheevos_config_t; -enum -{ - CHEEVOS_FLAGS_IS_SNES = 1 << 0, /* forces * mb padded with zeroes */ -}; - extern cheevos_config_t cheevos_config; int cheevos_load( const char* json ); void cheevos_test( void ); void cheevos_unload( void ); int cheevos_get_by_game_id( const char** json, unsigned game_id ); -int cheevos_get_by_content( const char** json, const void* data, size_t size, unsigned flags ); +int cheevos_get_by_content( const char** json, const void* data, size_t size ); #endif /* __RARCH_CHEEVOS_H */ diff --git a/content.c b/content.c index aff3bfab2a..1fbd1f51d6 100644 --- a/content.c +++ b/content.c @@ -515,7 +515,7 @@ static bool load_content(const struct retro_subsystem_info *special, { if (*content->elems[0].data) { - if ( cheevos_get_by_content(&json, info->data, info->size, CHEEVOS_FLAGS_IS_SNES) == 0 ) + if ( cheevos_get_by_content(&json, info->data, info->size) == 0 ) { cheevos_load(json); free((void*)json);