mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-06 19:45:33 +00:00
Achievements: Add 'Refresh Progress' option
Manually refreshes the all progress database if you have completed unlocks on other devices/machines.
This commit is contained in:
parent
0a0379f31f
commit
d54077e345
@ -140,6 +140,7 @@ static bool TryLoggingInWithToken();
|
||||
static void EnableHardcodeMode(bool display_message, bool display_game_summary);
|
||||
static void OnHardcoreModeChanged(bool enabled, bool display_message, bool display_game_summary);
|
||||
static bool IsRAIntegrationInitializing();
|
||||
static bool IsLoggedIn();
|
||||
static bool IsLoggedInOrLoggingIn();
|
||||
static void FinishInitialize();
|
||||
static void FinishLogin(const rc_client_t* client);
|
||||
@ -220,6 +221,8 @@ static void FetchHashLibraryCallback(int result, const char* error_message, rc_c
|
||||
rc_client_t* client, void* callback_userdata);
|
||||
static void FetchAllProgressCallback(int result, const char* error_message, rc_client_all_user_progress_t* list,
|
||||
rc_client_t* client, void* callback_userdata);
|
||||
static void RefreshAllProgressCallback(int result, const char* error_message, rc_client_all_user_progress_t* list,
|
||||
rc_client_t* client, void* callback_userdata);
|
||||
|
||||
static void BuildHashDatabase(const rc_client_hash_library_t* hashlib, const rc_client_all_user_progress_t* allprog);
|
||||
static bool SortAndSaveHashDatabase(Error* error);
|
||||
@ -296,6 +299,7 @@ struct State
|
||||
rc_client_hash_library_t* fetch_hash_library_result = nullptr;
|
||||
rc_client_async_handle_t* fetch_all_progress_request = nullptr;
|
||||
rc_client_all_user_progress_t* fetch_all_progress_result = nullptr;
|
||||
rc_client_async_handle_t* refresh_all_progress_request = nullptr;
|
||||
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
rc_client_async_handle_t* load_raintegration_request = nullptr;
|
||||
@ -696,6 +700,8 @@ void Achievements::FinishInitialize()
|
||||
if (IsLoggedInOrLoggingIn() && g_settings.achievements_hardcore_mode)
|
||||
DisplayHardcoreDeferredMessage();
|
||||
}
|
||||
|
||||
Host::OnAchievementsActiveChanged(true);
|
||||
}
|
||||
|
||||
bool Achievements::CreateClient(rc_client_t** client, std::unique_ptr<HTTPDownloader>* http)
|
||||
@ -865,6 +871,7 @@ void Achievements::Shutdown()
|
||||
#endif
|
||||
|
||||
DestroyClient(&s_state.client, &s_state.http_downloader);
|
||||
Host::OnAchievementsActiveChanged(false);
|
||||
}
|
||||
|
||||
void Achievements::ClientMessageCallback(const char* message, const rc_client_t* client)
|
||||
@ -2085,9 +2092,14 @@ std::string Achievements::GetLeaderboardUserBadgePath(const rc_client_leaderboar
|
||||
return path;
|
||||
}
|
||||
|
||||
bool Achievements::IsLoggedIn()
|
||||
{
|
||||
return (rc_client_get_user_info(s_state.client) != nullptr);
|
||||
}
|
||||
|
||||
bool Achievements::IsLoggedInOrLoggingIn()
|
||||
{
|
||||
return (rc_client_get_user_info(s_state.client) != nullptr || s_state.login_request);
|
||||
return (IsLoggedIn() || s_state.login_request);
|
||||
}
|
||||
|
||||
bool Achievements::Login(const char* username, const char* password, Error* error)
|
||||
@ -4055,6 +4067,62 @@ void Achievements::FinishRefreshHashDatabase()
|
||||
|
||||
// update game list, we might have some new games that weren't in the seed database
|
||||
GameList::UpdateAllAchievementData();
|
||||
|
||||
Host::OnAchievementsAllProgressRefreshed();
|
||||
}
|
||||
|
||||
bool Achievements::RefreshAllProgressDatabase(Error* error)
|
||||
{
|
||||
if (!IsLoggedIn())
|
||||
{
|
||||
Error::SetStringView(error, TRANSLATE_SV("Achievements", "User is not logged in."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_state.fetch_hash_library_request || s_state.fetch_all_progress_request || s_state.refresh_all_progress_request)
|
||||
{
|
||||
Error::SetStringView(error, TRANSLATE_SV("Achievements", "Progress is already being updated."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// refresh in progress
|
||||
s_state.refresh_all_progress_request = rc_client_begin_fetch_all_user_progress(s_state.client, RC_CONSOLE_PLAYSTATION,
|
||||
RefreshAllProgressCallback, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Achievements::RefreshAllProgressCallback(int result, const char* error_message,
|
||||
rc_client_all_user_progress_t* list, rc_client_t* client,
|
||||
void* callback_userdata)
|
||||
{
|
||||
s_state.refresh_all_progress_request = nullptr;
|
||||
|
||||
if (result != RC_OK)
|
||||
{
|
||||
Host::ReportErrorAsync(TRANSLATE_SV("Achievements", "Error"),
|
||||
fmt::format("{}: {}\n{}", TRANSLATE_SV("Achievements", "Refresh all progress failed"),
|
||||
rc_error_str(result), error_message));
|
||||
return;
|
||||
}
|
||||
|
||||
BuildProgressDatabase(list);
|
||||
rc_client_destroy_all_user_progress(list);
|
||||
|
||||
GameList::UpdateAllAchievementData();
|
||||
|
||||
Host::OnAchievementsAllProgressRefreshed();
|
||||
|
||||
if (FullscreenUI::IsInitialized())
|
||||
{
|
||||
GPUThread::RunOnThread([]() {
|
||||
if (!FullscreenUI::IsInitialized())
|
||||
return;
|
||||
|
||||
ImGuiFullscreen::ShowToast({}, TRANSLATE_STR("Achievements", "Updated achievement progress database."),
|
||||
Host::OSD_INFO_DURATION);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Achievements::BuildHashDatabase(const rc_client_hash_library_t* hashlib,
|
||||
|
@ -80,6 +80,9 @@ void UpdateSettings(const Settings& old_config);
|
||||
/// Shuts down the RetroAchievements client.
|
||||
void Shutdown();
|
||||
|
||||
/// Call to refresh the all-progress database.
|
||||
bool RefreshAllProgressDatabase(Error* error);
|
||||
|
||||
/// Called when the system is start. Engages hardcore mode if enabled.
|
||||
void OnSystemStarting(CDImage* image, bool disable_hardcore_mode);
|
||||
|
||||
@ -217,9 +220,15 @@ void OnAchievementsLoginSuccess(const char* display_name, u32 points, u32 sc_poi
|
||||
/// Implementers can assume the lock is held when this is called.
|
||||
void OnAchievementsRefreshed();
|
||||
|
||||
/// Called when achievements login completes or they are disabled.
|
||||
void OnAchievementsActiveChanged(bool active);
|
||||
|
||||
/// Called whenever hardcore mode is toggled.
|
||||
void OnAchievementsHardcoreModeChanged(bool enabled);
|
||||
|
||||
/// Called whenever all progress is manually refreshed and completed.
|
||||
void OnAchievementsAllProgressRefreshed();
|
||||
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
|
||||
/// Called when the RAIntegration menu changes.
|
||||
|
@ -6350,10 +6350,19 @@ void FullscreenUI::DrawAchievementsSettingsPage()
|
||||
false);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (MenuButton(FSUI_ICONVSTR(ICON_FA_KEY, "Logout"), FSUI_VSTR("Logs out of RetroAchievements.")))
|
||||
if (MenuButton(FSUI_ICONVSTR(ICON_FA_LIST_OL, "Update Progress"),
|
||||
FSUI_VSTR("Updates the progress database for achievements shown in the game list.")))
|
||||
{
|
||||
Host::RunOnCPUThread(&Achievements::Logout);
|
||||
Host::RunOnCPUThread([]() {
|
||||
Error error;
|
||||
if (!Achievements::RefreshAllProgressDatabase(&error))
|
||||
ImGuiFullscreen::ShowToast(FSUI_STR("Failed to update progress database"), error.TakeDescription(),
|
||||
Host::OSD_ERROR_DURATION);
|
||||
});
|
||||
}
|
||||
|
||||
if (MenuButton(FSUI_ICONVSTR(ICON_FA_KEY, "Logout"), FSUI_VSTR("Logs out of RetroAchievements.")))
|
||||
Host::RunOnCPUThread(&Achievements::Logout);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -9365,6 +9374,7 @@ TRANSLATE_NOOP("FullscreenUI", "Failed to delete {}.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to load '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to load shader {}. It may be invalid.\nError was:");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to save controller preset '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Failed to update progress database");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Fast Boot");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Fast Forward Boot");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Fast Forward Memory Card Access");
|
||||
@ -9769,6 +9779,8 @@ TRANSLATE_NOOP("FullscreenUI", "Ungrouped");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Unknown");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Unknown File Size");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Unlimited");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Update Progress");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Updates the progress database for achievements shown in the game list.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Upscales the game's rendering by the specified multiplier.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Blit Swap Chain");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Debug GPU Device");
|
||||
|
@ -745,6 +745,8 @@ void GameList::PopulateEntryAchievements(Entry* entry, const Achievements::Progr
|
||||
|
||||
entry->achievements_game_id = hentry->game_id;
|
||||
entry->num_achievements = Truncate16(hentry->num_achievements);
|
||||
entry->unlocked_achievements = 0;
|
||||
entry->unlocked_achievements_hc = 0;
|
||||
if (entry->num_achievements > 0)
|
||||
{
|
||||
const Achievements::ProgressDatabase::Entry* apd_entry = achievements_progress.LookupGame(hentry->game_id);
|
||||
|
@ -1113,11 +1113,21 @@ void Host::OnAchievementsRefreshed()
|
||||
// noop
|
||||
}
|
||||
|
||||
void Host::OnAchievementsActiveChanged(bool active)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void Host::OnAchievementsHardcoreModeChanged(bool enabled)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void Host::OnAchievementsAllProgressRefreshed()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
|
||||
void Host::OnRAIntegrationMenuChanged()
|
||||
|
@ -2100,6 +2100,8 @@ void MainWindow::connectSignals()
|
||||
connect(m_ui.actionGridViewZoomOut, &QAction::triggered, this, &MainWindow::onViewGameGridZoomOutActionTriggered);
|
||||
connect(m_ui.actionGridViewRefreshCovers, &QAction::triggered, m_game_list_widget,
|
||||
&GameListWidget::refreshGridCovers);
|
||||
connect(m_ui.actionViewRefreshAchievementProgress, &QAction::triggered, g_emu_thread,
|
||||
&EmuThread::refreshAchievementsAllProgress);
|
||||
connect(m_ui.actionChangeGameListBackground, &QAction::triggered, this,
|
||||
&MainWindow::onViewChangeGameListBackgroundTriggered);
|
||||
connect(m_ui.actionClearGameListBackground, &QAction::triggered, this,
|
||||
@ -2128,8 +2130,11 @@ void MainWindow::connectSignals()
|
||||
connect(g_emu_thread, &EmuThread::fullscreenUIStartedOrStopped, this, &MainWindow::onFullscreenUIStartedOrStopped);
|
||||
connect(g_emu_thread, &EmuThread::achievementsLoginRequested, this, &MainWindow::onAchievementsLoginRequested);
|
||||
connect(g_emu_thread, &EmuThread::achievementsLoginSuccess, this, &MainWindow::onAchievementsLoginSuccess);
|
||||
connect(g_emu_thread, &EmuThread::achievementsActiveChanged, this, &MainWindow::onAchievementsActiveChanged);
|
||||
connect(g_emu_thread, &EmuThread::achievementsHardcoreModeChanged, this,
|
||||
&MainWindow::onAchievementsHardcoreModeChanged);
|
||||
connect(g_emu_thread, &EmuThread::achievementsAllProgressRefreshed, this,
|
||||
&MainWindow::onAchievementsAllProgressRefreshed);
|
||||
connect(g_emu_thread, &EmuThread::onCoverDownloaderOpenRequested, this, &MainWindow::onToolsCoverDownloaderTriggered);
|
||||
connect(g_emu_thread, &EmuThread::onCreateAuxiliaryRenderWindow, this, &MainWindow::onCreateAuxiliaryRenderWindow,
|
||||
Qt::BlockingQueuedConnection);
|
||||
@ -2758,6 +2763,11 @@ void MainWindow::onAchievementsLoginSuccess(const QString& username, quint32 poi
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onAchievementsActiveChanged(bool active)
|
||||
{
|
||||
m_ui.actionViewRefreshAchievementProgress->setEnabled(active);
|
||||
}
|
||||
|
||||
void MainWindow::onAchievementsHardcoreModeChanged(bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
@ -2770,6 +2780,11 @@ void MainWindow::onAchievementsHardcoreModeChanged(bool enabled)
|
||||
updateEmulationActions(s_system_starting, s_system_valid, enabled);
|
||||
}
|
||||
|
||||
void MainWindow::onAchievementsAllProgressRefreshed()
|
||||
{
|
||||
m_ui.statusBar->showMessage(tr("RA: Updated achievement progress database."));
|
||||
}
|
||||
|
||||
bool MainWindow::onCreateAuxiliaryRenderWindow(RenderAPI render_api, qint32 x, qint32 y, quint32 width, quint32 height,
|
||||
const QString& title, const QString& icon_name,
|
||||
Host::AuxiliaryRenderWindowUserData userdata,
|
||||
|
@ -151,7 +151,9 @@ private Q_SLOTS:
|
||||
void onMediaCaptureStopped();
|
||||
void onAchievementsLoginRequested(Achievements::LoginRequestReason reason);
|
||||
void onAchievementsLoginSuccess(const QString& username, quint32 points, quint32 sc_points, quint32 unread_messages);
|
||||
void onAchievementsActiveChanged(bool active);
|
||||
void onAchievementsHardcoreModeChanged(bool enabled);
|
||||
void onAchievementsAllProgressRefreshed();
|
||||
bool onCreateAuxiliaryRenderWindow(RenderAPI render_api, qint32 x, qint32 y, quint32 width, quint32 height,
|
||||
const QString& title, const QString& icon_name,
|
||||
Host::AuxiliaryRenderWindowUserData userdata,
|
||||
|
@ -213,6 +213,7 @@
|
||||
<addaction name="actionGridViewZoomIn"/>
|
||||
<addaction name="actionGridViewZoomOut"/>
|
||||
<addaction name="actionGridViewRefreshCovers"/>
|
||||
<addaction name="actionViewRefreshAchievementProgress"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionChangeGameListBackground"/>
|
||||
<addaction name="actionClearGameListBackground"/>
|
||||
@ -987,6 +988,14 @@
|
||||
<string>Clear List Background</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewRefreshAchievementProgress">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Refresh Achievement &Progress</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/duckstation-qt.qrc"/>
|
||||
|
@ -1631,6 +1631,22 @@ void EmuThread::saveScreenshot()
|
||||
System::SaveScreenshot();
|
||||
}
|
||||
|
||||
void EmuThread::refreshAchievementsAllProgress()
|
||||
{
|
||||
if (!isCurrentThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::refreshAchievementsAllProgress, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
Error error;
|
||||
if (!Achievements::RefreshAllProgressDatabase(&error))
|
||||
{
|
||||
emit errorReported(tr("Error"), QString::fromStdString(error.GetDescription()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason)
|
||||
{
|
||||
emit g_emu_thread->achievementsLoginRequested(reason);
|
||||
@ -1669,11 +1685,21 @@ void Host::OnAchievementsRefreshed()
|
||||
emit g_emu_thread->achievementsRefreshed(game_id, game_info);
|
||||
}
|
||||
|
||||
void Host::OnAchievementsActiveChanged(bool active)
|
||||
{
|
||||
emit g_emu_thread->achievementsActiveChanged(active);
|
||||
}
|
||||
|
||||
void Host::OnAchievementsHardcoreModeChanged(bool enabled)
|
||||
{
|
||||
emit g_emu_thread->achievementsHardcoreModeChanged(enabled);
|
||||
}
|
||||
|
||||
void Host::OnAchievementsAllProgressRefreshed()
|
||||
{
|
||||
emit g_emu_thread->achievementsAllProgressRefreshed();
|
||||
}
|
||||
|
||||
void Host::OnCoverDownloaderOpenRequested()
|
||||
{
|
||||
emit g_emu_thread->onCoverDownloaderOpenRequested();
|
||||
|
@ -155,7 +155,9 @@ Q_SIGNALS:
|
||||
void achievementsLoginRequested(Achievements::LoginRequestReason reason);
|
||||
void achievementsLoginSuccess(const QString& username, quint32 points, quint32 sc_points, quint32 unread_messages);
|
||||
void achievementsRefreshed(quint32 id, const QString& game_info_string);
|
||||
void achievementsActiveChanged(bool active);
|
||||
void achievementsHardcoreModeChanged(bool enabled);
|
||||
void achievementsAllProgressRefreshed();
|
||||
void cheatEnabled(quint32 index, bool enabled);
|
||||
void mediaCaptureStarted();
|
||||
void mediaCaptureStopped();
|
||||
@ -183,6 +185,7 @@ public Q_SLOTS:
|
||||
void closeInputSources();
|
||||
void startFullscreenUI();
|
||||
void stopFullscreenUI();
|
||||
void refreshAchievementsAllProgress();
|
||||
void bootSystem(std::shared_ptr<SystemBootParameters> params);
|
||||
void resumeSystemFromMostRecentState();
|
||||
void shutdownSystem(bool save_state, bool check_memcard_busy);
|
||||
|
@ -576,11 +576,21 @@ void Host::OnAchievementsRefreshed()
|
||||
// noop
|
||||
}
|
||||
|
||||
void Host::OnAchievementsActiveChanged(bool active)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void Host::OnAchievementsHardcoreModeChanged(bool enabled)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void Host::OnAchievementsAllProgressRefreshed()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION
|
||||
|
||||
void Host::OnRAIntegrationMenuChanged()
|
||||
|
Loading…
x
Reference in New Issue
Block a user