mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Don't load RAIntegration from an install we can't write to
RAIntegration keeps its cache and local achievement data next to the executable. If PPSSPP is installed somewhere that needs elevation to write - Program Files being the obvious case - that write fails and takes the emulator down as soon as a set or code notes are loaded, with no log to show for it since the log can't be written either. Check whether the exe directory is writable before handing the DLL to rcheevos, and if it isn't, say so and point at the portable .zip instead. Achievements themselves still work, so carry on to the normal login. Fixes #21260 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01GgACRqkQNpfJQ4fjwyoEup
This commit is contained in:
1 parent
fefdf21db5
commit
afeab27186
4 files changed
+33
No files matched your search
@@ -1068,6 +1068,18 @@ bool CreateEmptyFile(const Path &filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsDirectoryWritable(const Path &path) {
|
||||
// There's no portable way to ask, so just try it and clean up after ourselves.
|
||||
const Path probe = path / ".ppsspp_write_test";
|
||||
FILE *file = OpenCFile(probe, "wb");
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
fclose(file);
|
||||
Delete(probe, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Deletes an empty directory, returns true on success
|
||||
// WARNING: On Android with content URIs, it will delete recursively!
|
||||
bool DeleteDir(const Path &path) {
|
||||
|
||||
@@ -123,6 +123,10 @@ bool MoveIfFast(const Path &srcFilename, const Path &destFilename);
|
||||
// creates an empty file filename, returns true on success
|
||||
bool CreateEmptyFile(const Path &filename);
|
||||
|
||||
// Can we actually create files in this directory? Checks by trying, since permission bits
|
||||
// don't tell the whole story (Windows ACLs, read-only mounts, ...).
|
||||
bool IsDirectoryWritable(const Path &path);
|
||||
|
||||
// Opens ini file (cheats, texture replacements etc.)
|
||||
// TODO: Belongs in System or something.
|
||||
bool OpenFileInEditor(const Path &fileName);
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "Common/Crypto/md5.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/File/Path.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/Net/HTTPRequest.h"
|
||||
#include "Common/Net/HTTPClient.h"
|
||||
#include "Common/System/OSD.h"
|
||||
@@ -704,6 +705,21 @@ void InitializeRAIntegration(void *windowHandle) {
|
||||
ERROR_LOG(Log::Achievements, "RAIntegration is enabled, but no main window handle was found.");
|
||||
return;
|
||||
}
|
||||
|
||||
// RAIntegration writes its cache and local achievement data next to the executable. If we
|
||||
// can't write there - the usual case being an install under Program Files - it takes the
|
||||
// emulator down with it as soon as it loads a set, so refuse to load it at all. See #21260.
|
||||
const Path &exeDir = File::GetExeDirectory();
|
||||
if (!File::IsDirectoryWritable(exeDir)) {
|
||||
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
|
||||
ERROR_LOG(Log::Achievements, "Not loading RAIntegration, '%s' is not writable", exeDir.c_str());
|
||||
g_OSD.Show(OSDType::MESSAGE_ERROR, ac->T("RAIntegrationNotWritable",
|
||||
"RAIntegration needs to write next to PPSSPP.exe, which this install doesn't allow. Use the portable .zip version instead."), "", g_RAImageID, 10.0f);
|
||||
// Carry on without the toolkit - plain achievements still work.
|
||||
TryLoginByToken(true);
|
||||
return;
|
||||
}
|
||||
|
||||
rc_client_begin_load_raintegration(g_rcClient, szFilePath, hWnd, "PPSSPP", PPSSPP_GIT_VERSION, &load_integration_callback, hWnd);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ Missable = Missable
|
||||
Notifications = Notifications
|
||||
Progression = Progression
|
||||
RAIntegration is enabled, but %1 was not found. = RAIntegration is enabled, but %1 was not found.
|
||||
RAIntegrationNotWritable = RAIntegration needs to write next to PPSSPP.exe, which this install doesn't allow. Use the portable .zip version instead.
|
||||
Recently unlocked = Recently unlocked
|
||||
Reconnected to RetroAchievements. = Reconnected to RetroAchievements.
|
||||
Register on www.retroachievements.org = Register on www.retroachievements.org
|
||||
|
||||
Reference in new issue
Block a user