[Kernel] Store earned achievements in-memory to prevent achievements spam
This doesn't store them externally so after restarting they will unlock again
This commit is contained in:
parent
2509b03b81
commit
ebdea6b02a
|
@ -22,10 +22,14 @@ DECLARE_int32(user_language);
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
AchievementManager::AchievementManager(){};
|
AchievementManager::AchievementManager() { unlocked_achievements.clear(); };
|
||||||
|
|
||||||
void AchievementManager::EarnAchievement(uint64_t xuid, uint32_t title_id,
|
void AchievementManager::EarnAchievement(uint64_t xuid, uint32_t title_id,
|
||||||
uint32_t achievement_id) {
|
uint32_t achievement_id) {
|
||||||
|
if (IsAchievementUnlocked(achievement_id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const Emulator* emulator = kernel_state()->emulator();
|
const Emulator* emulator = kernel_state()->emulator();
|
||||||
ui::WindowedAppContext& app_context =
|
ui::WindowedAppContext& app_context =
|
||||||
kernel_state()->emulator()->display_window()->app_context();
|
kernel_state()->emulator()->display_window()->app_context();
|
||||||
|
@ -48,6 +52,7 @@ void AchievementManager::EarnAchievement(uint64_t xuid, uint32_t title_id,
|
||||||
const std::string description =
|
const std::string description =
|
||||||
fmt::format("{}G - {}", entry.gamerscore, label);
|
fmt::format("{}G - {}", entry.gamerscore, label);
|
||||||
|
|
||||||
|
unlocked_achievements[achievement_id] = Clock::QueryHostSystemTime();
|
||||||
// Even if we disable popup we still should store info that this
|
// Even if we disable popup we still should store info that this
|
||||||
// achievement was earned.
|
// achievement was earned.
|
||||||
if (!cvars::show_achievement_notification) {
|
if (!cvars::show_achievement_notification) {
|
||||||
|
@ -63,5 +68,20 @@ void AchievementManager::EarnAchievement(uint64_t xuid, uint32_t title_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AchievementManager::IsAchievementUnlocked(uint32_t achievement_id) {
|
||||||
|
auto itr = unlocked_achievements.find(achievement_id);
|
||||||
|
|
||||||
|
return itr != unlocked_achievements.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t AchievementManager::GetAchievementUnlockTime(uint32_t achievement_id) {
|
||||||
|
auto itr = unlocked_achievements.find(achievement_id);
|
||||||
|
if (itr == unlocked_achievements.cend()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#ifndef XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
|
#ifndef XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
|
||||||
#define XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
|
#define XENIA_KERNEL_ACHIEVEMENT_MANAGER_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -25,7 +26,11 @@ class AchievementManager {
|
||||||
void EarnAchievement(uint64_t xuid, uint32_t title_id,
|
void EarnAchievement(uint64_t xuid, uint32_t title_id,
|
||||||
uint32_t achievement_id);
|
uint32_t achievement_id);
|
||||||
|
|
||||||
|
bool IsAchievementUnlocked(uint32_t achievement_id);
|
||||||
|
uint64_t GetAchievementUnlockTime(uint32_t achievement_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::map<uint32_t, uint64_t> unlocked_achievements;
|
||||||
// void Load();
|
// void Load();
|
||||||
// void Save();
|
// void Save();
|
||||||
};
|
};
|
||||||
|
|
|
@ -728,6 +728,13 @@ dword_result_t XamUserCreateAchievementEnumerator_entry(
|
||||||
db.GetAchievements();
|
db.GetAchievements();
|
||||||
|
|
||||||
for (const util::XdbfAchievementTableEntry& entry : achievement_list) {
|
for (const util::XdbfAchievementTableEntry& entry : achievement_list) {
|
||||||
|
auto is_unlocked =
|
||||||
|
kernel_state()->achievement_manager()->IsAchievementUnlocked(
|
||||||
|
entry.id);
|
||||||
|
auto unlock_time =
|
||||||
|
kernel_state()->achievement_manager()->GetAchievementUnlockTime(
|
||||||
|
entry.id);
|
||||||
|
|
||||||
auto item = XStaticAchievementEnumerator::AchievementDetails{
|
auto item = XStaticAchievementEnumerator::AchievementDetails{
|
||||||
entry.id,
|
entry.id,
|
||||||
xe::to_utf16(db.GetStringTableEntry(language, entry.label_id)),
|
xe::to_utf16(db.GetStringTableEntry(language, entry.label_id)),
|
||||||
|
@ -735,8 +742,9 @@ dword_result_t XamUserCreateAchievementEnumerator_entry(
|
||||||
xe::to_utf16(db.GetStringTableEntry(language, entry.unachieved_id)),
|
xe::to_utf16(db.GetStringTableEntry(language, entry.unachieved_id)),
|
||||||
entry.image_id,
|
entry.image_id,
|
||||||
entry.gamerscore,
|
entry.gamerscore,
|
||||||
{0, 0},
|
(uint32_t)(unlock_time << 31),
|
||||||
entry.flags};
|
(uint32_t)unlock_time,
|
||||||
|
is_unlocked ? entry.flags | 0x20000 : entry.flags};
|
||||||
|
|
||||||
e->AppendItem(item);
|
e->AppendItem(item);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue