mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-07 05:03:35 +02:00
Re-check hardcore mode when a savestate op is actually applied
The check lived only in Enqueue, but operations don't run there - they're queued and applied later by Process(). During boot, HardcoreModeActive() reads false even when hardcore is on, since it requires rc_client_is_processing_required(), which only becomes true once RetroAchievements has finished identifying the game asynchronously. Anything queued in that window passed the check, and was then applied by Process() after identification completed and hardcore came up. Auto-load wasn't even a race: EmuScreen::bootComplete() calls Achievements::SetGame(), which starts the identify, and then checks HardcoreModeActive() a few lines below - always false at that point. So "Auto load savestate" quietly worked in hardcore mode. --state and a load-state hotkey pressed during boot got through the same way. Re-checking per operation in Process() covers every entry point at once, and by then identification has finished, so the answer is authoritative. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GgACRqkQNpfJQ4fjwyoEup
This commit is contained in:
co-authored by
Claude Opus 5
parent
b7258cab12
commit
255896e89f
+22
-10
@@ -196,17 +196,18 @@ int g_screenshotFailures;
|
||||
pspFileSystem.DoState(p);
|
||||
}
|
||||
|
||||
void Enqueue(const SaveState::Operation &op) {
|
||||
if (!NetworkAllowSaveState()) {
|
||||
return;
|
||||
// Hardcore mode bans loading savestates outright, and saving too unless the user opted
|
||||
// back into that.
|
||||
bool BannedInHardcoreMode(OperationType type) {
|
||||
if (!Achievements::HardcoreModeActive()) {
|
||||
return false;
|
||||
}
|
||||
if (Achievements::HardcoreModeActive()) {
|
||||
if (g_Config.bAchievementsSaveStateInHardcoreMode && ((op.type == SaveState::OperationType::Save))) {
|
||||
// We allow saving in hardcore mode if this setting is on.
|
||||
} else {
|
||||
// Operation not allowed
|
||||
return;
|
||||
}
|
||||
return !(g_Config.bAchievementsSaveStateInHardcoreMode && type == OperationType::Save);
|
||||
}
|
||||
|
||||
void Enqueue(const SaveState::Operation &op) {
|
||||
if (!NetworkAllowSaveState() || BannedInHardcoreMode(op.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex);
|
||||
@@ -810,6 +811,17 @@ int g_screenshotFailures;
|
||||
SaveStart state;
|
||||
|
||||
for (const auto &op : operations) {
|
||||
// Re-check here, and not just in Enqueue: during boot, RetroAchievements is still
|
||||
// identifying the game asynchronously, and until it's done hardcore mode doesn't
|
||||
// read as active yet. An operation queued in that window (a hotkey press, --state,
|
||||
// auto-load) passed the check in Enqueue and would otherwise be applied here, after
|
||||
// identification has finished and hardcore mode has come up.
|
||||
if (BannedInHardcoreMode(op.type)) {
|
||||
WARN_LOG(Log::SaveState, "Dropping queued savestate operation - hardcore mode is active");
|
||||
Achievements::WarnUserIfHardcoreModeActive(op.type == OperationType::Save);
|
||||
continue;
|
||||
}
|
||||
|
||||
CChunkFileReader::Error result;
|
||||
Status callbackResult;
|
||||
std::string callbackMessage;
|
||||
|
||||
Reference in New Issue
Block a user