From 9a57216fd029910bc20ac94885302d3f61241be0 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Sat, 15 Apr 2023 11:03:53 -0400 Subject: [PATCH] Added AwardAchievement to AchievementManager AwardAchievement performs the API call to notify the site that an achievement has been unlocked. As one of the parameters is the game hash (something I overlooked previously; I thought it was the game ID) this change also moves the game hash into a member field. --- Source/Core/Core/AchievementManager.cpp | 26 ++++++++++++++++++++----- Source/Core/Core/AchievementManager.h | 5 ++++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 2b6015f382..f1a6d3a763 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -5,7 +5,6 @@ #include "Core/AchievementManager.h" -#include #include #include "Common/HttpRequest.h" @@ -113,11 +112,10 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, }, .close = [](void* file_handle) { delete reinterpret_cast(file_handle); }}; rc_hash_init_custom_filereader(&volume_reader); - std::array game_hash; - if (!rc_hash_generate_from_file(game_hash.data(), RC_CONSOLE_GAMECUBE, iso_path.c_str())) + if (!rc_hash_generate_from_file(m_game_hash.data(), RC_CONSOLE_GAMECUBE, iso_path.c_str())) return; - m_queue.EmplaceItem([this, callback, game_hash] { - const auto resolve_hash_response = ResolveHash(game_hash); + m_queue.EmplaceItem([this, callback] { + const auto resolve_hash_response = ResolveHash(this->m_game_hash); if (resolve_hash_response != ResponseType::SUCCESS || m_game_id == 0) { callback(resolve_hash_response); @@ -366,6 +364,24 @@ void AchievementManager::ActivateDeactivateAchievement(AchievementId id, bool en rc_runtime_deactivate_achievement(&m_runtime, id); } +AchievementManager::ResponseType AchievementManager::AwardAchievement(AchievementId achievement_id) +{ + std::string username = Config::Get(Config::RA_USERNAME); + std::string api_token = Config::Get(Config::RA_API_TOKEN); + rc_api_award_achievement_request_t award_request = {.username = username.c_str(), + .api_token = api_token.c_str(), + .achievement_id = achievement_id, + .hardcore = hardcore_mode_enabled, + .game_hash = m_game_hash.data()}; + rc_api_award_achievement_response_t award_response = {}; + ResponseType r_type = + Request( + award_request, &award_response, rc_api_init_award_achievement_request, + rc_api_process_award_achievement_response); + rc_api_destroy_award_achievement_response(&award_response); + return r_type; +} + // Every RetroAchievements API call, with only a partial exception for fetch_image, follows // the same design pattern (here, X is the name of the call): // Create a specific rc_api_X_request_t struct and populate with the necessary values diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index b5cf465915..96e000344d 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -4,6 +4,7 @@ #pragma once #ifdef USE_RETRO_ACHIEVEMENTS +#include #include #include #include @@ -62,6 +63,7 @@ private: void ActivateDeactivateAchievement(AchievementId id, bool enabled, bool unofficial, bool encore); + ResponseType AwardAchievement(AchievementId achievement_id); template ResponseType Request(RcRequest rc_request, RcResponse* rc_response, const std::function& init_request, @@ -69,7 +71,8 @@ private: rc_runtime_t m_runtime{}; bool m_is_runtime_initialized = false; - unsigned int m_game_id = 0; + std::array m_game_hash{}; + u32 m_game_id = 0; rc_api_fetch_game_data_response_t m_game_data{}; bool m_is_game_loaded = false;