Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add internal flag to allow DLL to run leaderboards in softcore #311

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/rc_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,8 @@ static void rc_client_activate_leaderboards(rc_client_game_info_t* game, rc_clie
{
rc_client_leaderboard_info_t* leaderboard;
rc_client_leaderboard_info_t* stop;
const uint8_t leaderboards_allowed =
client->state.hardcore || client->state.allow_leaderboards_in_softcore;

uint32_t active_count = 0;
rc_client_subset_info_t* subset = game->subsets;
Expand All @@ -1318,15 +1320,15 @@ static void rc_client_activate_leaderboards(rc_client_game_info_t* game, rc_clie
continue;

case RC_CLIENT_LEADERBOARD_STATE_INACTIVE:
if (client->state.hardcore) {
if (leaderboards_allowed) {
rc_reset_lboard(leaderboard->lboard);
leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_ACTIVE;
++active_count;
}
break;

default:
if (client->state.hardcore)
if (leaderboards_allowed)
++active_count;
else
leaderboard->public_.state = RC_CLIENT_LEADERBOARD_STATE_INACTIVE;
Expand Down Expand Up @@ -4008,6 +4010,11 @@ static void rc_client_submit_leaderboard_entry(rc_client_t* client, rc_client_le
{
rc_client_submit_leaderboard_entry_callback_data_t* callback_data;

if (!client->state.hardcore) {
RC_CLIENT_LOG_INFO_FORMATTED(client, "Leaderboard %u entry submission not allowed in softcore", leaderboard->public_.id);
return;
}

if (client->callbacks.can_submit_leaderboard_entry &&
!client->callbacks.can_submit_leaderboard_entry(leaderboard->public_.id, client)) {
RC_CLIENT_LOG_INFO_FORMATTED(client, "Leaderboard %u entry submission blocked by client", leaderboard->public_.id);
Expand Down Expand Up @@ -4946,7 +4953,7 @@ void rc_client_do_frame(rc_client_t* client)
if (client->game->pending_events & RC_CLIENT_GAME_PENDING_EVENT_PROGRESS_TRACKER)
rc_client_do_frame_update_progress_tracker(client, client->game);

if (client->state.hardcore) {
if (client->state.hardcore || client->state.allow_leaderboards_in_softcore) {
for (subset = client->game->subsets; subset; subset = subset->next) {
if (subset->active)
rc_client_do_frame_process_leaderboards(client, subset);
Expand Down Expand Up @@ -5412,7 +5419,9 @@ static void rc_client_disable_hardcore(rc_client_t* client)

if (client->game) {
rc_client_toggle_hardcore_achievements(client->game, client, RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE);
rc_client_deactivate_leaderboards(client->game, client);

if (!client->state.allow_leaderboards_in_softcore)
rc_client_deactivate_leaderboards(client->game, client);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/rc_client_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ typedef struct rc_client_state_t {
uint8_t log_level;
uint8_t user;
uint8_t disconnect;
uint8_t allow_leaderboards_in_softcore;

struct rc_client_load_state_t* load;
struct rc_client_async_handle_t* async_handles[4];
Expand Down
86 changes: 86 additions & 0 deletions test/test_rc_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -6885,6 +6885,7 @@ static void test_do_frame_leaderboard_submit_blocked(void)
ASSERT_NUM_EQUALS(event->leaderboard_tracker->id, 1);
ASSERT_STR_EQUALS(event->leaderboard_tracker->display, "000017");

/* but make sure the server wasn't called */
assert_api_not_called(api_call);

event_count = 0;
Expand All @@ -6900,6 +6901,90 @@ static void test_do_frame_leaderboard_submit_blocked(void)
ASSERT_PTR_NOT_NULL(find_event(RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED, 44));
ASSERT_PTR_NOT_NULL(find_event(RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD, 44));

/* make sure the server was called */
assert_api_called(api_call);

rc_client_destroy(g_client);
}

static void test_do_frame_leaderboard_submit_softcore(void)
{
rc_client_leaderboard_info_t* leaderboard;
rc_client_event_t* event;
uint8_t memory[64];
const char* api_call = "r=submitlbentry&u=Username&t=ApiToken&i=44&s=17&m=0123456789ABCDEF&v=a27fa205f7f30c8d13d74806ea5425b6";
memset(memory, 0, sizeof(memory));

g_client = mock_client_game_loaded(patchdata_exhaustive, no_unlocks);
rc_client_set_hardcore_enabled(g_client, 0);

ASSERT_PTR_NOT_NULL(g_client->game);
mock_memory(memory, sizeof(memory));

mock_api_response(api_call,
"{\"Success\":true,\"Response\":{\"Score\":17,\"BestScore\":23,"
"\"TopEntries\":[{\"User\":\"Player1\",\"Score\":44,\"Rank\":1},{\"User\":\"Username\",\"Score\":23,\"Rank\":2}],"
"\"RankInfo\":{\"Rank\":2,\"NumEntries\":\"2\"}}}");

event_count = 0;
rc_client_do_frame(g_client);
ASSERT_NUM_EQUALS(event_count, 0);

/* start the leaderboard - will be ignored in softcore */
memory[0x0B] = 1;
memory[0x0E] = 17;
rc_client_do_frame(g_client);
ASSERT_NUM_EQUALS(event_count, 0);

/* allow leaderboards to be processed in softcore. have to manually activate as it wasn't activated on game load */
g_client->state.allow_leaderboards_in_softcore = 1;
leaderboard = (rc_client_leaderboard_info_t*)rc_client_get_leaderboard_info(g_client, 44);
leaderboard->public_.state = RC_CLIENT_LEADERBOARD_BUCKET_ACTIVE;
leaderboard->lboard->state = RC_LBOARD_STATE_ACTIVE;

rc_client_do_frame(g_client);
ASSERT_NUM_EQUALS(event_count, 2);
ASSERT_PTR_NOT_NULL(find_event(RC_CLIENT_EVENT_LEADERBOARD_STARTED, 44));
ASSERT_PTR_NOT_NULL(find_event(RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW, 1));

event_count = 0;
rc_client_do_frame(g_client);
ASSERT_NUM_EQUALS(event_count, 0);

/* submit the leaderboard */
memory[0x0B] = 0;
memory[0x0D] = 1;
rc_client_do_frame(g_client);
ASSERT_NUM_EQUALS(event_count, 2);

event = find_event(RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED, 44);
ASSERT_PTR_NOT_NULL(event);
ASSERT_NUM_EQUALS(event->leaderboard->state, RC_CLIENT_LEADERBOARD_STATE_ACTIVE);
ASSERT_STR_EQUALS(event->leaderboard->tracker_value, "000017");
ASSERT_PTR_EQUALS(event->leaderboard, rc_client_get_leaderboard_info(g_client, 44));

event = find_event(RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE, 1);
ASSERT_PTR_NOT_NULL(event);
ASSERT_NUM_EQUALS(event->leaderboard_tracker->id, 1);
ASSERT_STR_EQUALS(event->leaderboard_tracker->display, "000017");

/* but make sure the server wasn't called */
assert_api_not_called(api_call);

event_count = 0;
rc_client_do_frame(g_client);
ASSERT_NUM_EQUALS(event_count, 0);

g_client->state.hardcore = 1;

/* restart the leaderboard - will immediately submit */
memory[0x0B] = 1;
rc_client_do_frame(g_client);
ASSERT_NUM_EQUALS(event_count, 2);
ASSERT_PTR_NOT_NULL(find_event(RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED, 44));
ASSERT_PTR_NOT_NULL(find_event(RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD, 44));

/* make sure the server was called */
assert_api_called(api_call);

rc_client_destroy(g_client);
Expand Down Expand Up @@ -8729,6 +8814,7 @@ void test_client(void) {
TEST(test_do_frame_leaderboard_submit_immediate);
TEST(test_do_frame_leaderboard_submit_hidden);
TEST(test_do_frame_leaderboard_submit_blocked);
TEST(test_do_frame_leaderboard_submit_softcore);
TEST(test_do_frame_leaderboard_tracker_sharing);
TEST(test_do_frame_leaderboard_tracker_sharing_hits);
TEST(test_do_frame_leaderboard_submit_automatic_retry);
Expand Down
Loading