From e361212bbfdb02d859c226b6a17b37ceed461823 Mon Sep 17 00:00:00 2001 From: Silent Date: Thu, 17 Jun 2021 20:43:50 +0200 Subject: [PATCH] Basic leaderboard integration No UI yet, only sends unlocks to the server. --- src/frontend-common/cheevos.cpp | 59 +++++++++++++++++++++++++++++++++ src/frontend-common/cheevos.h | 9 +++++ 2 files changed, 68 insertions(+) diff --git a/src/frontend-common/cheevos.cpp b/src/frontend-common/cheevos.cpp index 4ae030a36..feec63480 100644 --- a/src/frontend-common/cheevos.cpp +++ b/src/frontend-common/cheevos.cpp @@ -73,6 +73,7 @@ static std::string s_game_publisher; static std::string s_game_release_date; static std::string s_game_icon; static std::vector s_achievements; +static std::vector s_leaderboards; static bool s_has_rich_presence = false; static std::string s_rich_presence_string; @@ -721,6 +722,44 @@ static void GetPatchesCallback(s32 status_code, const FrontendCommon::HTTPDownlo } } + // parse leaderboards + if (patch_data.HasMember("Leaderboards") && patch_data["Leaderboards"].IsArray()) + { + const auto leaderboards(patch_data["Leaderboards"].GetArray()); + for (const auto& leaderboard : leaderboards) + { + if (!leaderboard.HasMember("ID") || !leaderboard["ID"].IsNumber() || !leaderboard.HasMember("Mem") || + !leaderboard["Mem"].IsString() || !leaderboard.HasMember("Title") || !leaderboard["Title"].IsString() || + !leaderboard.HasMember("Format") || !leaderboard["Format"].IsString()) + { + continue; + } + + const unsigned int id = leaderboard["ID"].GetUint(); + const char* title = leaderboard["Title"].GetString(); + const char* memaddr = leaderboard["Mem"].GetString(); + const char* format = leaderboard["Format"].GetString(); + std::string description = GetOptionalString(leaderboard, "Description"); + + Leaderboard lboard; + lboard.id = id; + lboard.title = title; + lboard.description = std::move(description); + lboard.format = format; + s_leaderboards.push_back(std::move(lboard)); + + const int err = rc_runtime_activate_lboard(&s_rcheevos_runtime, id, memaddr, nullptr, 0); + if (err != RC_OK) + { + Log_ErrorPrintf("Leaderboard %u memaddr parse error: %s", id, rc_error_str(err)); + } + else + { + Log_DevPrintf("Activated leaderboard %s (%u)", title, id); + } + } + } + // parse rich presence if (s_rich_presence_enabled && patch_data.HasMember("RichPresencePatch") && patch_data["RichPresencePatch"].IsString()) @@ -1083,6 +1122,11 @@ static void UnlockAchievementCallback(s32 status_code, const FrontendCommon::HTT // we don't really need to do anything here } +static void SubmitLeaderboardCallback(s32 status_code, const FrontendCommon::HTTPDownloader::Request::Data& data) +{ + // Do nothing (for now?) +} + void UnlockAchievement(u32 achievement_id, bool add_notification /* = true*/) { Achievement* achievement = GetAchievementByID(achievement_id); @@ -1138,6 +1182,19 @@ void UnlockAchievement(u32 achievement_id, bool add_notification /* = true*/) s_http_downloader->CreateRequest(url, UnlockAchievementCallback); } +void SubmitLeaderboard(u32 leaderboard_id, int value) +{ + if (s_test_mode) + { + Log_WarningPrintf("Skipping sending leaderboard %u result to server because of test mode.", leaderboard_id); + return; + } + + char url[512]; + rc_url_submit_lboard(url, sizeof(url), s_username.c_str(), s_login_token.c_str(), leaderboard_id, value); + s_http_downloader->CreateRequest(url, SubmitLeaderboardCallback); +} + void CheevosEventHandler(const rc_runtime_event_t* runtime_event) { static const char* events[] = {"RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED", "RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED", @@ -1152,6 +1209,8 @@ void CheevosEventHandler(const rc_runtime_event_t* runtime_event) if (runtime_event->type == RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED) UnlockAchievement(runtime_event->id); + else if (runtime_event->type == RC_RUNTIME_EVENT_LBOARD_TRIGGERED) + SubmitLeaderboard(runtime_event->id, runtime_event->value); } // from cheats.cpp - do we want to move this somewhere else? diff --git a/src/frontend-common/cheevos.h b/src/frontend-common/cheevos.h index 39231a8cb..b7b033d32 100644 --- a/src/frontend-common/cheevos.h +++ b/src/frontend-common/cheevos.h @@ -28,6 +28,14 @@ struct Achievement bool active; }; +struct Leaderboard +{ + u32 id; + std::string title; + std::string description; + std::string format; +}; + extern bool g_active; extern bool g_challenge_mode; extern u32 g_game_id; @@ -91,5 +99,6 @@ u32 GetMaximumPointsForGame(); u32 GetCurrentPointsForGame(); void UnlockAchievement(u32 achievement_id, bool add_notification = true); +void SubmitLeaderboard(u32 leaderboard_id, int value); } // namespace Cheevos