mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 07:09:48 -06:00
Added FetchBadges to AchievementManager
FetchBadges fetches all available badges (player, game, achievements) and stores them in AchievementManager's memory. New fields and accessors have been added as necessary. Badges for individual achievements are stored in the UnlockStatus map. The method is public so that the settings dialog can call it if badges are turned on after a game is started. Badges are deleted at game close and logout.
This commit is contained in:
@ -35,6 +35,8 @@ void AchievementManager::Init()
|
|||||||
rc_runtime_init(&m_runtime);
|
rc_runtime_init(&m_runtime);
|
||||||
m_is_runtime_initialized = true;
|
m_is_runtime_initialized = true;
|
||||||
m_queue.Reset("AchievementManagerQueue", [](const std::function<void()>& func) { func(); });
|
m_queue.Reset("AchievementManagerQueue", [](const std::function<void()>& func) { func(); });
|
||||||
|
m_image_queue.Reset("AchievementManagerImageQueue",
|
||||||
|
[](const std::function<void()>& func) { func(); });
|
||||||
LoginAsync("", [](ResponseType r_type) {});
|
LoginAsync("", [](ResponseType r_type) {});
|
||||||
INFO_LOG_FMT(ACHIEVEMENTS, "Achievement Manager Initialized");
|
INFO_LOG_FMT(ACHIEVEMENTS, "Achievement Manager Initialized");
|
||||||
}
|
}
|
||||||
@ -55,6 +57,7 @@ AchievementManager::ResponseType AchievementManager::Login(const std::string& pa
|
|||||||
return AchievementManager::ResponseType::MANAGER_NOT_INITIALIZED;
|
return AchievementManager::ResponseType::MANAGER_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
AchievementManager::ResponseType r_type = VerifyCredentials(password);
|
AchievementManager::ResponseType r_type = VerifyCredentials(password);
|
||||||
|
FetchBadges();
|
||||||
if (m_update_callback)
|
if (m_update_callback)
|
||||||
m_update_callback();
|
m_update_callback();
|
||||||
return r_type;
|
return r_type;
|
||||||
@ -71,6 +74,7 @@ void AchievementManager::LoginAsync(const std::string& password, const ResponseC
|
|||||||
}
|
}
|
||||||
m_queue.EmplaceItem([this, password, callback] {
|
m_queue.EmplaceItem([this, password, callback] {
|
||||||
callback(VerifyCredentials(password));
|
callback(VerifyCredentials(password));
|
||||||
|
FetchBadges();
|
||||||
if (m_update_callback)
|
if (m_update_callback)
|
||||||
m_update_callback();
|
m_update_callback();
|
||||||
});
|
});
|
||||||
@ -207,6 +211,7 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path,
|
|||||||
}
|
}
|
||||||
ActivateDeactivateLeaderboards();
|
ActivateDeactivateLeaderboards();
|
||||||
ActivateDeactivateRichPresence();
|
ActivateDeactivateRichPresence();
|
||||||
|
FetchBadges();
|
||||||
// Reset this to zero so that RP immediately triggers on the first frame
|
// Reset this to zero so that RP immediately triggers on the first frame
|
||||||
m_last_ping_time = 0;
|
m_last_ping_time = 0;
|
||||||
INFO_LOG_FMT(ACHIEVEMENTS, "RetroAchievements successfully loaded for {}.", m_game_data.title);
|
INFO_LOG_FMT(ACHIEVEMENTS, "RetroAchievements successfully loaded for {}.", m_game_data.title);
|
||||||
@ -286,6 +291,256 @@ void AchievementManager::ActivateDeactivateRichPresence()
|
|||||||
INFO_LOG_FMT(ACHIEVEMENTS, "Rich presence (de)activated.");
|
INFO_LOG_FMT(ACHIEVEMENTS, "Rich presence (de)activated.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AchievementManager::FetchBadges()
|
||||||
|
{
|
||||||
|
if (!m_is_runtime_initialized || !IsLoggedIn() || !Config::Get(Config::RA_BADGES_ENABLED))
|
||||||
|
{
|
||||||
|
if (m_update_callback)
|
||||||
|
m_update_callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_image_queue.Cancel();
|
||||||
|
|
||||||
|
if (m_player_badge.name != m_display_name)
|
||||||
|
{
|
||||||
|
m_image_queue.EmplaceItem([this] {
|
||||||
|
std::string name_to_fetch;
|
||||||
|
{
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
if (m_display_name == m_player_badge.name)
|
||||||
|
return;
|
||||||
|
name_to_fetch = m_display_name;
|
||||||
|
}
|
||||||
|
rc_api_fetch_image_request_t icon_request = {.image_name = name_to_fetch.c_str(),
|
||||||
|
.image_type = RC_IMAGE_TYPE_USER};
|
||||||
|
Badge fetched_badge;
|
||||||
|
if (RequestImage(icon_request, &fetched_badge) == ResponseType::SUCCESS)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS, "Successfully downloaded player badge id {}.", name_to_fetch);
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
if (name_to_fetch != m_display_name)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS, "Requested outdated badge id {} for player id {}.",
|
||||||
|
name_to_fetch, m_display_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_player_badge.badge = std::move(fetched_badge);
|
||||||
|
m_player_badge.name = std::move(name_to_fetch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to download player badge id {}.", name_to_fetch);
|
||||||
|
}
|
||||||
|
if (m_update_callback)
|
||||||
|
m_update_callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsGameLoaded())
|
||||||
|
{
|
||||||
|
if (m_update_callback)
|
||||||
|
m_update_callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int badgematch = 0;
|
||||||
|
{
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
badgematch = m_game_badge.name.compare(m_game_data.image_name);
|
||||||
|
}
|
||||||
|
if (badgematch != 0)
|
||||||
|
{
|
||||||
|
m_image_queue.EmplaceItem([this] {
|
||||||
|
std::string name_to_fetch;
|
||||||
|
{
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
if (m_game_badge.name.compare(m_game_data.image_name) == 0)
|
||||||
|
return;
|
||||||
|
name_to_fetch.assign(m_game_data.image_name);
|
||||||
|
}
|
||||||
|
rc_api_fetch_image_request_t icon_request = {.image_name = name_to_fetch.c_str(),
|
||||||
|
.image_type = RC_IMAGE_TYPE_GAME};
|
||||||
|
Badge fetched_badge;
|
||||||
|
if (RequestImage(icon_request, &fetched_badge) == ResponseType::SUCCESS)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS, "Successfully downloaded game badge id {}.", name_to_fetch);
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
if (name_to_fetch.compare(m_game_data.image_name) != 0)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS, "Requested outdated badge id {} for game id {}.",
|
||||||
|
name_to_fetch, m_game_data.image_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_game_badge.badge = std::move(fetched_badge);
|
||||||
|
m_game_badge.name = std::move(name_to_fetch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to download game badge id {}.", name_to_fetch);
|
||||||
|
}
|
||||||
|
if (m_update_callback)
|
||||||
|
m_update_callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned num_achievements = m_game_data.num_achievements;
|
||||||
|
for (size_t index = 0; index < num_achievements; index++)
|
||||||
|
{
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
// In case the number of achievements changes since the loop started; I just don't want
|
||||||
|
// to lock for the ENTIRE loop so instead I reclaim the lock each cycle
|
||||||
|
if (num_achievements != m_game_data.num_achievements)
|
||||||
|
break;
|
||||||
|
rc_api_achievement_definition_t& achievement = m_game_data.achievements[index];
|
||||||
|
std::string name_to_fetch(achievement.badge_name);
|
||||||
|
const UnlockStatus& unlock_status = m_unlock_map[achievement.id];
|
||||||
|
if (unlock_status.unlocked_badge.name != name_to_fetch)
|
||||||
|
{
|
||||||
|
m_image_queue.EmplaceItem([this, index] {
|
||||||
|
std::string current_name, name_to_fetch;
|
||||||
|
{
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
if (m_game_data.num_achievements <= index)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(
|
||||||
|
ACHIEVEMENTS,
|
||||||
|
"Attempted to fetch unlocked badge for index {} after achievement list cleared.",
|
||||||
|
index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rc_api_achievement_definition_t& achievement = m_game_data.achievements[index];
|
||||||
|
auto unlock_itr = m_unlock_map.find(achievement.id);
|
||||||
|
if (unlock_itr == m_unlock_map.end())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(
|
||||||
|
ACHIEVEMENTS,
|
||||||
|
"Attempted to fetch unlocked badge for achievement id {} not in unlock map.",
|
||||||
|
index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
name_to_fetch.assign(achievement.badge_name);
|
||||||
|
current_name = unlock_itr->second.unlocked_badge.name;
|
||||||
|
}
|
||||||
|
if (current_name == name_to_fetch)
|
||||||
|
return;
|
||||||
|
rc_api_fetch_image_request_t icon_request = {.image_name = name_to_fetch.c_str(),
|
||||||
|
.image_type = RC_IMAGE_TYPE_ACHIEVEMENT};
|
||||||
|
Badge fetched_badge;
|
||||||
|
if (RequestImage(icon_request, &fetched_badge) == ResponseType::SUCCESS)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS, "Successfully downloaded unlocked achievement badge id {}.",
|
||||||
|
name_to_fetch);
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
if (m_game_data.num_achievements <= index)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS,
|
||||||
|
"Fetched unlocked badge for index {} after achievement list cleared.",
|
||||||
|
index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rc_api_achievement_definition_t& achievement = m_game_data.achievements[index];
|
||||||
|
auto unlock_itr = m_unlock_map.find(achievement.id);
|
||||||
|
if (unlock_itr == m_unlock_map.end())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(ACHIEVEMENTS,
|
||||||
|
"Fetched unlocked badge for achievement id {} not in unlock map.", index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (name_to_fetch.compare(achievement.badge_name) != 0)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(
|
||||||
|
ACHIEVEMENTS,
|
||||||
|
"Requested outdated unlocked achievement badge id {} for achievement id {}.",
|
||||||
|
name_to_fetch, current_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unlock_itr->second.unlocked_badge.badge = std::move(fetched_badge);
|
||||||
|
unlock_itr->second.unlocked_badge.name = std::move(name_to_fetch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to download unlocked achievement badge id {}.",
|
||||||
|
name_to_fetch);
|
||||||
|
}
|
||||||
|
if (m_update_callback)
|
||||||
|
m_update_callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (unlock_status.locked_badge.name != name_to_fetch)
|
||||||
|
{
|
||||||
|
m_image_queue.EmplaceItem([this, index] {
|
||||||
|
std::string current_name, name_to_fetch;
|
||||||
|
{
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
if (m_game_data.num_achievements <= index)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(
|
||||||
|
ACHIEVEMENTS,
|
||||||
|
"Attempted to fetch locked badge for index {} after achievement list cleared.",
|
||||||
|
index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rc_api_achievement_definition_t& achievement = m_game_data.achievements[index];
|
||||||
|
auto unlock_itr = m_unlock_map.find(achievement.id);
|
||||||
|
if (unlock_itr == m_unlock_map.end())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(
|
||||||
|
ACHIEVEMENTS,
|
||||||
|
"Attempted to fetch locked badge for achievement id {} not in unlock map.", index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
name_to_fetch.assign(achievement.badge_name);
|
||||||
|
current_name = unlock_itr->second.locked_badge.name;
|
||||||
|
}
|
||||||
|
if (current_name == name_to_fetch)
|
||||||
|
return;
|
||||||
|
rc_api_fetch_image_request_t icon_request = {
|
||||||
|
.image_name = name_to_fetch.c_str(), .image_type = RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED};
|
||||||
|
Badge fetched_badge;
|
||||||
|
if (RequestImage(icon_request, &fetched_badge) == ResponseType::SUCCESS)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS, "Successfully downloaded locked achievement badge id {}.",
|
||||||
|
name_to_fetch);
|
||||||
|
std::lock_guard lg{m_lock};
|
||||||
|
if (m_game_data.num_achievements <= index)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS,
|
||||||
|
"Fetched locked badge for index {} after achievement list cleared.",
|
||||||
|
index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rc_api_achievement_definition_t& achievement = m_game_data.achievements[index];
|
||||||
|
auto unlock_itr = m_unlock_map.find(achievement.id);
|
||||||
|
if (unlock_itr == m_unlock_map.end())
|
||||||
|
{
|
||||||
|
ERROR_LOG_FMT(ACHIEVEMENTS,
|
||||||
|
"Fetched locked badge for achievement id {} not in unlock map.", index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (name_to_fetch.compare(achievement.badge_name) != 0)
|
||||||
|
{
|
||||||
|
INFO_LOG_FMT(ACHIEVEMENTS,
|
||||||
|
"Requested outdated locked achievement badge id {} for achievement id {}.",
|
||||||
|
name_to_fetch, current_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unlock_itr->second.locked_badge.badge = std::move(fetched_badge);
|
||||||
|
unlock_itr->second.locked_badge.name = std::move(name_to_fetch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_LOG_FMT(ACHIEVEMENTS, "Failed to download locked achievement badge id {}.",
|
||||||
|
name_to_fetch);
|
||||||
|
}
|
||||||
|
if (m_update_callback)
|
||||||
|
m_update_callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_update_callback)
|
||||||
|
m_update_callback();
|
||||||
|
}
|
||||||
|
|
||||||
void AchievementManager::DoFrame()
|
void AchievementManager::DoFrame()
|
||||||
{
|
{
|
||||||
if (!m_is_game_loaded)
|
if (!m_is_game_loaded)
|
||||||
@ -381,6 +636,11 @@ u32 AchievementManager::GetPlayerScore() const
|
|||||||
return IsLoggedIn() ? m_player_score : 0;
|
return IsLoggedIn() ? m_player_score : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AchievementManager::BadgeStatus& AchievementManager::GetPlayerBadge() const
|
||||||
|
{
|
||||||
|
return m_player_badge;
|
||||||
|
}
|
||||||
|
|
||||||
std::string AchievementManager::GetGameDisplayName() const
|
std::string AchievementManager::GetGameDisplayName() const
|
||||||
{
|
{
|
||||||
return IsGameLoaded() ? m_game_data.title : "";
|
return IsGameLoaded() ? m_game_data.title : "";
|
||||||
@ -417,7 +677,12 @@ rc_api_fetch_game_data_response_t* AchievementManager::GetGameData()
|
|||||||
return &m_game_data;
|
return &m_game_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
AchievementManager::UnlockStatus
|
const AchievementManager::BadgeStatus& AchievementManager::GetGameBadge() const
|
||||||
|
{
|
||||||
|
return m_game_badge;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AchievementManager::UnlockStatus&
|
||||||
AchievementManager::GetUnlockStatus(AchievementId achievement_id) const
|
AchievementManager::GetUnlockStatus(AchievementId achievement_id) const
|
||||||
{
|
{
|
||||||
return m_unlock_map.at(achievement_id);
|
return m_unlock_map.at(achievement_id);
|
||||||
@ -447,10 +712,12 @@ void AchievementManager::CloseGame()
|
|||||||
ActivateDeactivateLeaderboards();
|
ActivateDeactivateLeaderboards();
|
||||||
ActivateDeactivateRichPresence();
|
ActivateDeactivateRichPresence();
|
||||||
m_game_id = 0;
|
m_game_id = 0;
|
||||||
|
m_game_badge.name = "";
|
||||||
m_unlock_map.clear();
|
m_unlock_map.clear();
|
||||||
rc_api_destroy_fetch_game_data_response(&m_game_data);
|
rc_api_destroy_fetch_game_data_response(&m_game_data);
|
||||||
std::memset(&m_game_data, 0, sizeof(m_game_data));
|
std::memset(&m_game_data, 0, sizeof(m_game_data));
|
||||||
m_queue.Cancel();
|
m_queue.Cancel();
|
||||||
|
m_image_queue.Cancel();
|
||||||
m_system = nullptr;
|
m_system = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -461,8 +728,12 @@ void AchievementManager::CloseGame()
|
|||||||
|
|
||||||
void AchievementManager::Logout()
|
void AchievementManager::Logout()
|
||||||
{
|
{
|
||||||
CloseGame();
|
{
|
||||||
Config::SetBaseOrCurrent(Config::RA_API_TOKEN, "");
|
std::lock_guard lg{m_lock};
|
||||||
|
CloseGame();
|
||||||
|
m_player_badge.name = "";
|
||||||
|
Config::SetBaseOrCurrent(Config::RA_API_TOKEN, "");
|
||||||
|
}
|
||||||
if (m_update_callback)
|
if (m_update_callback)
|
||||||
m_update_callback();
|
m_update_callback();
|
||||||
INFO_LOG_FMT(ACHIEVEMENTS, "Logged out from server.");
|
INFO_LOG_FMT(ACHIEVEMENTS, "Logged out from server.");
|
||||||
|
@ -58,6 +58,12 @@ public:
|
|||||||
using RichPresence = std::array<char, RP_SIZE>;
|
using RichPresence = std::array<char, RP_SIZE>;
|
||||||
using Badge = std::vector<u8>;
|
using Badge = std::vector<u8>;
|
||||||
|
|
||||||
|
struct BadgeStatus
|
||||||
|
{
|
||||||
|
std::string name = "";
|
||||||
|
Badge badge{};
|
||||||
|
};
|
||||||
|
|
||||||
struct UnlockStatus
|
struct UnlockStatus
|
||||||
{
|
{
|
||||||
AchievementId game_data_index = 0;
|
AchievementId game_data_index = 0;
|
||||||
@ -69,6 +75,8 @@ public:
|
|||||||
} remote_unlock_status = UnlockType::LOCKED;
|
} remote_unlock_status = UnlockType::LOCKED;
|
||||||
u32 session_unlock_count = 0;
|
u32 session_unlock_count = 0;
|
||||||
u32 points = 0;
|
u32 points = 0;
|
||||||
|
BadgeStatus locked_badge;
|
||||||
|
BadgeStatus unlocked_badge;
|
||||||
};
|
};
|
||||||
|
|
||||||
static AchievementManager* GetInstance();
|
static AchievementManager* GetInstance();
|
||||||
@ -84,6 +92,7 @@ public:
|
|||||||
void ActivateDeactivateAchievements();
|
void ActivateDeactivateAchievements();
|
||||||
void ActivateDeactivateLeaderboards();
|
void ActivateDeactivateLeaderboards();
|
||||||
void ActivateDeactivateRichPresence();
|
void ActivateDeactivateRichPresence();
|
||||||
|
void FetchBadges();
|
||||||
|
|
||||||
void DoFrame();
|
void DoFrame();
|
||||||
u32 MemoryPeeker(u32 address, u32 num_bytes, void* ud);
|
u32 MemoryPeeker(u32 address, u32 num_bytes, void* ud);
|
||||||
@ -92,10 +101,12 @@ public:
|
|||||||
std::recursive_mutex* GetLock();
|
std::recursive_mutex* GetLock();
|
||||||
std::string GetPlayerDisplayName() const;
|
std::string GetPlayerDisplayName() const;
|
||||||
u32 GetPlayerScore() const;
|
u32 GetPlayerScore() const;
|
||||||
|
const BadgeStatus& GetPlayerBadge() const;
|
||||||
std::string GetGameDisplayName() const;
|
std::string GetGameDisplayName() const;
|
||||||
PointSpread TallyScore() const;
|
PointSpread TallyScore() const;
|
||||||
rc_api_fetch_game_data_response_t* GetGameData();
|
rc_api_fetch_game_data_response_t* GetGameData();
|
||||||
UnlockStatus GetUnlockStatus(AchievementId achievement_id) const;
|
const BadgeStatus& GetGameBadge() const;
|
||||||
|
const UnlockStatus& GetUnlockStatus(AchievementId achievement_id) const;
|
||||||
void GetAchievementProgress(AchievementId achievement_id, u32* value, u32* target);
|
void GetAchievementProgress(AchievementId achievement_id, u32* value, u32* target);
|
||||||
RichPresence GetRichPresence();
|
RichPresence GetRichPresence();
|
||||||
|
|
||||||
@ -138,16 +149,19 @@ private:
|
|||||||
UpdateCallback m_update_callback;
|
UpdateCallback m_update_callback;
|
||||||
std::string m_display_name;
|
std::string m_display_name;
|
||||||
u32 m_player_score = 0;
|
u32 m_player_score = 0;
|
||||||
|
BadgeStatus m_player_badge;
|
||||||
std::array<char, HASH_LENGTH> m_game_hash{};
|
std::array<char, HASH_LENGTH> m_game_hash{};
|
||||||
u32 m_game_id = 0;
|
u32 m_game_id = 0;
|
||||||
rc_api_fetch_game_data_response_t m_game_data{};
|
rc_api_fetch_game_data_response_t m_game_data{};
|
||||||
bool m_is_game_loaded = false;
|
bool m_is_game_loaded = false;
|
||||||
|
BadgeStatus m_game_badge;
|
||||||
RichPresence m_rich_presence;
|
RichPresence m_rich_presence;
|
||||||
time_t m_last_ping_time = 0;
|
time_t m_last_ping_time = 0;
|
||||||
|
|
||||||
std::unordered_map<AchievementId, UnlockStatus> m_unlock_map;
|
std::unordered_map<AchievementId, UnlockStatus> m_unlock_map;
|
||||||
|
|
||||||
Common::WorkQueueThread<std::function<void()>> m_queue;
|
Common::WorkQueueThread<std::function<void()>> m_queue;
|
||||||
|
Common::WorkQueueThread<std::function<void()>> m_image_queue;
|
||||||
std::recursive_mutex m_lock;
|
std::recursive_mutex m_lock;
|
||||||
}; // class AchievementManager
|
}; // class AchievementManager
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ const Info<bool> RA_LEADERBOARDS_ENABLED{
|
|||||||
{System::Achievements, "Achievements", "LeaderboardsEnabled"}, false};
|
{System::Achievements, "Achievements", "LeaderboardsEnabled"}, false};
|
||||||
const Info<bool> RA_RICH_PRESENCE_ENABLED{
|
const Info<bool> RA_RICH_PRESENCE_ENABLED{
|
||||||
{System::Achievements, "Achievements", "RichPresenceEnabled"}, false};
|
{System::Achievements, "Achievements", "RichPresenceEnabled"}, false};
|
||||||
|
const Info<bool> RA_BADGES_ENABLED{{System::Achievements, "Achievements", "BadgesEnabled"}, false};
|
||||||
const Info<bool> RA_UNOFFICIAL_ENABLED{{System::Achievements, "Achievements", "UnofficialEnabled"},
|
const Info<bool> RA_UNOFFICIAL_ENABLED{{System::Achievements, "Achievements", "UnofficialEnabled"},
|
||||||
false};
|
false};
|
||||||
const Info<bool> RA_ENCORE_ENABLED{{System::Achievements, "Achievements", "EncoreEnabled"}, false};
|
const Info<bool> RA_ENCORE_ENABLED{{System::Achievements, "Achievements", "EncoreEnabled"}, false};
|
||||||
|
@ -14,6 +14,7 @@ extern const Info<std::string> RA_API_TOKEN;
|
|||||||
extern const Info<bool> RA_ACHIEVEMENTS_ENABLED;
|
extern const Info<bool> RA_ACHIEVEMENTS_ENABLED;
|
||||||
extern const Info<bool> RA_LEADERBOARDS_ENABLED;
|
extern const Info<bool> RA_LEADERBOARDS_ENABLED;
|
||||||
extern const Info<bool> RA_RICH_PRESENCE_ENABLED;
|
extern const Info<bool> RA_RICH_PRESENCE_ENABLED;
|
||||||
|
extern const Info<bool> RA_BADGES_ENABLED;
|
||||||
extern const Info<bool> RA_UNOFFICIAL_ENABLED;
|
extern const Info<bool> RA_UNOFFICIAL_ENABLED;
|
||||||
extern const Info<bool> RA_ENCORE_ENABLED;
|
extern const Info<bool> RA_ENCORE_ENABLED;
|
||||||
} // namespace Config
|
} // namespace Config
|
||||||
|
@ -47,6 +47,7 @@ bool IsSettingSaveable(const Config::Location& config_location)
|
|||||||
&Config::RA_ACHIEVEMENTS_ENABLED.GetLocation(),
|
&Config::RA_ACHIEVEMENTS_ENABLED.GetLocation(),
|
||||||
&Config::RA_LEADERBOARDS_ENABLED.GetLocation(),
|
&Config::RA_LEADERBOARDS_ENABLED.GetLocation(),
|
||||||
&Config::RA_RICH_PRESENCE_ENABLED.GetLocation(),
|
&Config::RA_RICH_PRESENCE_ENABLED.GetLocation(),
|
||||||
|
&Config::RA_BADGES_ENABLED.GetLocation(),
|
||||||
&Config::RA_UNOFFICIAL_ENABLED.GetLocation(),
|
&Config::RA_UNOFFICIAL_ENABLED.GetLocation(),
|
||||||
&Config::RA_ENCORE_ENABLED.GetLocation(),
|
&Config::RA_ENCORE_ENABLED.GetLocation(),
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user