From 612b3b69fcdb1749458102a92e099bd15029889b Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Wed, 13 Nov 2024 17:09:46 -0500 Subject: [PATCH 1/6] add game hash query param to patch api calls --- include/rc_api_runtime.h | 2 ++ src/rapi/rc_api_runtime.c | 4 +++ src/rc_client.c | 1 + test/rapi/test_rc_api_runtime.c | 38 +++++++++++++++++++++ test/test_rc_client.c | 60 ++++++++++++++++----------------- 5 files changed, 75 insertions(+), 30 deletions(-) diff --git a/include/rc_api_runtime.h b/include/rc_api_runtime.h index fef1b876..7d4e9727 100644 --- a/include/rc_api_runtime.h +++ b/include/rc_api_runtime.h @@ -73,6 +73,8 @@ typedef struct rc_api_fetch_game_data_request_t { const char* api_token; /* The unique identifier of the game */ uint32_t game_id; + /* The hash associated to the game being played */ + const char* game_hash; } rc_api_fetch_game_data_request_t; diff --git a/src/rapi/rc_api_runtime.c b/src/rapi/rc_api_runtime.c index 0ad58f01..3fd0240c 100644 --- a/src/rapi/rc_api_runtime.c +++ b/src/rapi/rc_api_runtime.c @@ -75,6 +75,10 @@ int rc_api_init_fetch_game_data_request(rc_api_request_t* request, const rc_api_ rc_url_builder_init(&builder, &request->buffer, 48); if (rc_api_url_build_dorequest(&builder, "patch", api_params->username, api_params->api_token)) { rc_url_builder_append_unum_param(&builder, "g", api_params->game_id); + + if (api_params->game_hash && *api_params->game_hash) + rc_url_builder_append_str_param(&builder, "m", api_params->game_hash); + request->post_data = rc_url_builder_finalize(&builder); request->content_type = RC_CONTENT_TYPE_URLENCODED; } diff --git a/src/rc_client.c b/src/rc_client.c index 187d3d09..9b8728a3 100644 --- a/src/rc_client.c +++ b/src/rc_client.c @@ -2371,6 +2371,7 @@ static void rc_client_begin_fetch_game_data(rc_client_load_state_t* load_state) fetch_game_data_request.username = client->user.username; fetch_game_data_request.api_token = client->user.token; fetch_game_data_request.game_id = load_state->hash->game_id; + fetch_game_data_request.game_hash = load_state->hash->hash; result = rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request); if (result != RC_OK) { diff --git a/test/rapi/test_rc_api_runtime.c b/test/rapi/test_rc_api_runtime.c index ddcf368f..18b153a1 100644 --- a/test/rapi/test_rc_api_runtime.c +++ b/test/rapi/test_rc_api_runtime.c @@ -107,6 +107,42 @@ static void test_init_fetch_game_data_request() { rc_api_destroy_request(&request); } +static void test_init_fetch_game_data_request_game_hash() { + rc_api_fetch_game_data_request_t fetch_game_data_request; + rc_api_request_t request; + + memset(&fetch_game_data_request, 0, sizeof(fetch_game_data_request)); + fetch_game_data_request.username = "Username"; + fetch_game_data_request.api_token = "API_TOKEN"; + fetch_game_data_request.game_id = 1234; + fetch_game_data_request.game_hash = "ABCDEF0123456789"; + + ASSERT_NUM_EQUALS(rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request), RC_OK); + ASSERT_STR_EQUALS(request.url, DOREQUEST_URL); + ASSERT_STR_EQUALS(request.post_data, "r=patch&u=Username&t=API_TOKEN&g=1234&m=ABCDEF0123456789"); + ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED); + + rc_api_destroy_request(&request); +} + +static void test_init_fetch_game_data_request_game_hash_empty(void) { + rc_api_fetch_game_data_request_t fetch_game_data_request; + rc_api_request_t request; + + memset(&fetch_game_data_request, 0, sizeof(fetch_game_data_request)); + fetch_game_data_request.username = "Username"; + fetch_game_data_request.api_token = "API_TOKEN"; + fetch_game_data_request.game_id = 1234; + fetch_game_data_request.game_hash = ""; + + ASSERT_NUM_EQUALS(rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request), RC_OK); + ASSERT_STR_EQUALS(request.url, DOREQUEST_URL); + ASSERT_STR_EQUALS(request.post_data, "r=patch&u=Username&t=API_TOKEN&g=1234"); + ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED); + + rc_api_destroy_request(&request); +} + static void test_init_fetch_game_data_request_no_id() { rc_api_fetch_game_data_request_t fetch_game_data_request; rc_api_request_t request; @@ -1270,6 +1306,8 @@ void test_rapi_runtime(void) { /* patch */ TEST(test_init_fetch_game_data_request); + TEST(test_init_fetch_game_data_request_game_hash); + TEST(test_init_fetch_game_data_request_game_hash_empty); TEST(test_init_fetch_game_data_request_no_id); TEST(test_process_fetch_game_data_response_empty); diff --git a/test/test_rc_client.c b/test/test_rc_client.c index 766542d7..7a4ffeb4 100644 --- a/test/test_rc_client.c +++ b/test/test_rc_client.c @@ -645,7 +645,7 @@ static void mock_client_load_game(const char* patchdata, const char* unlocks) reset_mock_api_handlers(); event_count = 0; mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, unlocks); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_success, g_callback_userdata); @@ -659,7 +659,7 @@ static void mock_client_load_game_softcore(const char* patchdata, const char* un reset_mock_api_handlers(); event_count = 0; mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=0&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, unlocks); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_success, g_callback_userdata); @@ -679,7 +679,7 @@ static rc_client_t* mock_client_game_loaded(const char* patchdata, const char* u static void mock_client_load_subset(const char* patchdata, const char* unlocks) { - mock_api_response("r=patch&u=Username&t=ApiToken&g=2345", patchdata); + mock_api_response("r=patch&u=Username&t=ApiToken&g=2345&m=%5bSUBSET2345%5d", patchdata); mock_api_response("r=startsession&u=Username&t=ApiToken&g=2345&h=1&m=%5bSUBSET2345%5d&l=" RCHEEVOS_VERSION_STRING, unlocks); rc_client_begin_load_subset(g_client, 2345, rc_client_callback_expect_success, g_callback_userdata); @@ -1071,7 +1071,7 @@ static void test_logout_during_fetch_game(void) rc_client_callback_expect_no_longer_active, g_callback_userdata); async_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); rc_client_logout(g_client); @@ -1144,7 +1144,7 @@ static void test_get_user_game_summary_encore_mode(void) rc_client_set_unofficial_enabled(g_client, 1); reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_exhaustive); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_exhaustive); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, unlock_6_8h_and_9); rc_client_set_encore_mode_enabled(g_client, 1); @@ -1402,7 +1402,7 @@ static void test_load_game(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); ASSERT_NUM_EQUALS(rc_client_get_load_game_state(g_client), RC_CLIENT_LOAD_GAME_STATE_NONE); @@ -1480,10 +1480,10 @@ static void test_load_game_async_login(void) /* login completion will trigger process to continue */ async_api_response("r=login2&u=Username&p=Pa%24%24word", "{\"Success\":true,\"User\":\"Username\",\"Token\":\"ApiToken\",\"Score\":12345,\"SoftcoreScore\":123,\"Messages\":2,\"Permissions\":1,\"AccountType\":\"Registered\"}"); - assert_api_pending("r=patch&u=Username&t=ApiToken&g=1234"); + assert_api_pending("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF"); ASSERT_NUM_EQUALS(rc_client_get_load_game_state(g_client), RC_CLIENT_LOAD_GAME_STATE_FETCHING_GAME_DATA); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); ASSERT_NUM_EQUALS(rc_client_get_load_game_state(g_client), RC_CLIENT_LOAD_GAME_STATE_STARTING_SESSION); async_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); @@ -1606,7 +1606,7 @@ static void test_load_game_gameid_failure(void) reset_mock_api_handlers(); mock_api_error("r=gameid&m=0123456789ABCDEF", response_429, 429); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_too_many_requests, g_callback_userdata); @@ -1624,7 +1624,7 @@ static void test_load_game_patch_failure(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_error("r=patch&u=Username&t=ApiToken&g=1234", response_429, 429); + mock_api_error("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", response_429, 429); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_too_many_requests, g_callback_userdata); @@ -1642,7 +1642,7 @@ static void test_load_game_startsession_failure(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); mock_api_error("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, response_429, 429); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_too_many_requests, g_callback_userdata); @@ -1660,7 +1660,7 @@ static void test_load_game_startsession_timeout(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); mock_api_error("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, "", 504); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_timeout, g_callback_userdata); @@ -1678,7 +1678,7 @@ static void test_load_game_startsession_custom_timeout(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); mock_api_error("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, "Request has timed out.", RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR); @@ -1731,7 +1731,7 @@ static void test_load_game_patch_aborted(void) rc_client_abort_async(g_client, handle); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); assert_api_not_called("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING); ASSERT_PTR_NULL(g_client->state.load); @@ -1754,7 +1754,7 @@ static void test_load_game_startsession_aborted(void) rc_client_callback_expect_uncalled, g_callback_userdata); async_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); rc_client_abort_async(g_client, handle); @@ -1776,7 +1776,7 @@ static void test_load_game_while_spectating(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); /* spectator mode should not start a session or fetch unlocks */ rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_success, g_callback_userdata); @@ -1862,7 +1862,7 @@ static void test_load_game_process_game_data(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_success, g_callback_userdata); @@ -1927,7 +1927,7 @@ static void test_load_game_destroy_while_fetching_game_data(void) async_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); rc_client_destroy(g_client); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); } static void test_load_unknown_game(void) @@ -2078,7 +2078,7 @@ static void test_unload_game_while_fetching_game_data(void) async_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); rc_client_unload_game(g_client); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); ASSERT_PTR_NULL(g_client->state.load); ASSERT_PTR_NULL(g_client->game); @@ -2095,7 +2095,7 @@ static void test_unload_game_while_starting_session(void) rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_uncalled, g_callback_userdata); async_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); rc_client_unload_game(g_client); @@ -2141,7 +2141,7 @@ static void test_identify_and_load_game_console_specified(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=6a2305a2b6675a97ff792709be1ca857", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=6a2305a2b6675a97ff792709be1ca857", patchdata_2ach_1lbd); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=6a2305a2b6675a97ff792709be1ca857&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_identify_and_load_game(g_client, RC_CONSOLE_NINTENDO, "foo.zip#foo.nes", @@ -2174,7 +2174,7 @@ static void test_identify_and_load_game_console_not_specified(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=6a2305a2b6675a97ff792709be1ca857", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=6a2305a2b6675a97ff792709be1ca857", patchdata_2ach_1lbd); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=6a2305a2b6675a97ff792709be1ca857&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_identify_and_load_game(g_client, RC_CONSOLE_UNKNOWN, "foo.zip#foo.nes", @@ -2477,7 +2477,7 @@ static void test_identify_and_load_game_unknown_hash_client_provided(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=6a2305a2b6675a97ff792709be1ca857", "{\"Success\":true,\"GameID\":0}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=6a2305a2b6675a97ff792709be1ca857", patchdata_2ach_1lbd); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=6a2305a2b6675a97ff792709be1ca857&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_identify_and_load_game(g_client, RC_CONSOLE_NINTENDO, "foo.zip#foo.nes", @@ -2511,7 +2511,7 @@ static void test_identify_and_load_game_multihash(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=6a2305a2b6675a97ff792709be1ca857", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=6a2305a2b6675a97ff792709be1ca857", patchdata_2ach_1lbd); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=6a2305a2b6675a97ff792709be1ca857&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_identify_and_load_game(g_client, RC_CONSOLE_UNKNOWN, "abc.dsk", @@ -3202,7 +3202,7 @@ static void test_change_media_from_hash_while_loading(void) /* media request won't occur until patch data is received */ assert_api_not_called("r=gameid&m=6a2305a2b6675a97ff792709be1ca857"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=4989b063a40dcfa28291ff8d675050e3", patchdata_2ach_1lbd); assert_api_not_called("r=gameid&m=6a2305a2b6675a97ff792709be1ca857"); /* finish loading game */ @@ -3234,7 +3234,7 @@ static void test_change_media_from_hash_while_loading_later(void) /* get past fetching the patch data so there's a valid console for the change media call */ async_api_response("r=gameid&m=4989b063a40dcfa28291ff8d675050e3", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=4989b063a40dcfa28291ff8d675050e3", patchdata_2ach_1lbd); /* change_media should immediately attempt to resolve the new hash */ rc_client_begin_change_media_from_hash(g_client, "6a2305a2b6675a97ff792709be1ca857", @@ -3362,12 +3362,12 @@ static void test_load_subset(void) reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":1234}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=0123456789ABCDEF", patchdata_2ach_1lbd); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_success, g_callback_userdata); - mock_api_response("r=patch&u=Username&t=ApiToken&g=2345", patchdata_subset); + mock_api_response("r=patch&u=Username&t=ApiToken&g=2345&m=%5bSUBSET2345%5d", patchdata_subset); mock_api_response("r=startsession&u=Username&t=ApiToken&g=2345&h=1&m=%5bSUBSET2345%5d&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); rc_client_begin_load_subset(g_client, 2345, rc_client_callback_expect_success, g_callback_userdata); @@ -4554,11 +4554,11 @@ static void test_achievement_list_subset_buckets_subset_first(void) g_client = mock_client_logged_in(); reset_mock_api_handlers(); mock_api_response("r=gameid&m=0123456789ABCDEF", "{\"Success\":true,\"GameID\":2345}"); - mock_api_response("r=patch&u=Username&t=ApiToken&g=2345", patchdata_subset2); + mock_api_response("r=patch&u=Username&t=ApiToken&g=2345&m=0123456789ABCDEF", patchdata_subset2); mock_api_response("r=startsession&u=Username&t=ApiToken&g=2345&h=1&m=0123456789ABCDEF&l=" RCHEEVOS_VERSION_STRING, unlock_5502); rc_client_begin_load_game(g_client, "0123456789ABCDEF", rc_client_callback_expect_success, g_callback_userdata); - mock_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_exhaustive); + mock_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=%5bSUBSET1234%5d", patchdata_exhaustive); mock_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=%5bSUBSET1234%5d&l=" RCHEEVOS_VERSION_STRING, unlock_8); rc_client_begin_load_subset(g_client, 1234, rc_client_callback_expect_success, g_callback_userdata); From e581c18eac86d9d372151dfcda1cc3f34e42c881 Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Wed, 13 Nov 2024 17:16:14 -0500 Subject: [PATCH 2/6] fix tests --- test/test_rc_client.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/test_rc_client.c b/test/test_rc_client.c index 7a4ffeb4..27df73b2 100644 --- a/test/test_rc_client.c +++ b/test/test_rc_client.c @@ -2221,7 +2221,7 @@ static void test_identify_and_load_game_multiconsole_first(void) iterator->consoles[iterator->index + 1] = 0; async_api_response("r=gameid&m=6a2305a2b6675a97ff792709be1ca857", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=6a2305a2b6675a97ff792709be1ca857", patchdata_2ach_1lbd); async_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=6a2305a2b6675a97ff792709be1ca857&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); assert_api_not_pending("r=gameid&m=64b131c5c7fec32985d9c99700babb7e"); @@ -2270,7 +2270,7 @@ static void test_identify_and_load_game_multiconsole_second(void) assert_api_pending("r=gameid&m=64b131c5c7fec32985d9c99700babb7e"); async_api_response("r=gameid&m=64b131c5c7fec32985d9c99700babb7e", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=64b131c5c7fec32985d9c99700babb7", patchdata_2ach_1lbd); async_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=64b131c5c7fec32985d9c99700babb7e&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); ASSERT_PTR_NULL(g_client->state.load); @@ -2589,7 +2589,7 @@ static void test_identify_and_load_game_multihash_differ(void) /* second lookup should succeed */ async_api_response("r=gameid&m=4989b063a40dcfa28291ff8d675050e3", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=4989b063a40dcfa28291ff8d675050e3", patchdata_2ach_1lbd); async_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=4989b063a40dcfa28291ff8d675050e3&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); ASSERT_PTR_NULL(g_client->state.load); @@ -2890,7 +2890,7 @@ static void test_change_media_while_loading(void) /* media request won't occur until patch data is received */ assert_api_not_called("r=gameid&m=6a2305a2b6675a97ff792709be1ca857"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=6a2305a2b6675a97ff792709be1ca857", patchdata_2ach_1lbd); assert_api_not_called("r=gameid&m=6a2305a2b6675a97ff792709be1ca857"); /* finish loading game */ @@ -2933,7 +2933,7 @@ static void test_change_media_while_loading_later(void) /* get past fetching the patch data so there's a valid console for the change media call */ async_api_response("r=gameid&m=4989b063a40dcfa28291ff8d675050e3", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=4989b063a40dcfa28291ff8d675050e3", patchdata_2ach_1lbd); /* change_media should immediately attempt to resolve the new hash */ rc_client_begin_change_media(g_client, "foo.zip#foo.nes", image, image_size, From 6f04b04d07a3a4e7ea8e189985554e04e6b75b56 Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Wed, 13 Nov 2024 17:23:50 -0500 Subject: [PATCH 3/6] more fixes --- test/test_rc_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_rc_client.c b/test/test_rc_client.c index 27df73b2..6422b27c 100644 --- a/test/test_rc_client.c +++ b/test/test_rc_client.c @@ -2270,7 +2270,7 @@ static void test_identify_and_load_game_multiconsole_second(void) assert_api_pending("r=gameid&m=64b131c5c7fec32985d9c99700babb7e"); async_api_response("r=gameid&m=64b131c5c7fec32985d9c99700babb7e", "{\"Success\":true,\"GameID\":1234}"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=64b131c5c7fec32985d9c99700babb7", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=64b131c5c7fec32985d9c99700babb7e", patchdata_2ach_1lbd); async_api_response("r=startsession&u=Username&t=ApiToken&g=1234&h=1&m=64b131c5c7fec32985d9c99700babb7e&l=" RCHEEVOS_VERSION_STRING, "{\"Success\":true}"); ASSERT_PTR_NULL(g_client->state.load); From cf54efc0867ef8665687665a1f7112d3b4151c1c Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Wed, 13 Nov 2024 17:24:24 -0500 Subject: [PATCH 4/6] add missing change --- src/rc_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rc_client.c b/src/rc_client.c index 9b8728a3..de88b89d 100644 --- a/src/rc_client.c +++ b/src/rc_client.c @@ -2371,7 +2371,7 @@ static void rc_client_begin_fetch_game_data(rc_client_load_state_t* load_state) fetch_game_data_request.username = client->user.username; fetch_game_data_request.api_token = client->user.token; fetch_game_data_request.game_id = load_state->hash->game_id; - fetch_game_data_request.game_hash = load_state->hash->hash; + fetch_game_data_request.game_hash = client->game ? client->game->public_.hash : load_state->hash->hash; result = rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request); if (result != RC_OK) { From e261cec961d6d9e17b297901f3732d358ec3aba1 Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Wed, 13 Nov 2024 17:49:34 -0500 Subject: [PATCH 5/6] fix more stuff --- src/rc_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rc_client.c b/src/rc_client.c index de88b89d..9b8728a3 100644 --- a/src/rc_client.c +++ b/src/rc_client.c @@ -2371,7 +2371,7 @@ static void rc_client_begin_fetch_game_data(rc_client_load_state_t* load_state) fetch_game_data_request.username = client->user.username; fetch_game_data_request.api_token = client->user.token; fetch_game_data_request.game_id = load_state->hash->game_id; - fetch_game_data_request.game_hash = client->game ? client->game->public_.hash : load_state->hash->hash; + fetch_game_data_request.game_hash = load_state->hash->hash; result = rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request); if (result != RC_OK) { From ff95368b220203222f6bb333c243a06270add044 Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Wed, 13 Nov 2024 17:53:00 -0500 Subject: [PATCH 6/6] final test fix --- test/test_rc_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_rc_client.c b/test/test_rc_client.c index 6422b27c..bd3bb6db 100644 --- a/test/test_rc_client.c +++ b/test/test_rc_client.c @@ -2890,7 +2890,7 @@ static void test_change_media_while_loading(void) /* media request won't occur until patch data is received */ assert_api_not_called("r=gameid&m=6a2305a2b6675a97ff792709be1ca857"); - async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=6a2305a2b6675a97ff792709be1ca857", patchdata_2ach_1lbd); + async_api_response("r=patch&u=Username&t=ApiToken&g=1234&m=4989b063a40dcfa28291ff8d675050e3", patchdata_2ach_1lbd); assert_api_not_called("r=gameid&m=6a2305a2b6675a97ff792709be1ca857"); /* finish loading game */