From 6b0bfbfc0980717dac8f937dfe1a56c8c559b2e8 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Fri, 15 Dec 2023 22:35:28 +0100 Subject: [PATCH] Changed to a new application data directory structure --- es-app/src/main.cpp | 202 ++++++++++++------ .../scrapers/GamesDBJSONScraperResources.cpp | 6 +- es-core/src/InputManager.cpp | 33 ++- es-core/src/Log.cpp | 7 +- es-core/src/Settings.cpp | 31 ++- es-core/src/utils/FileSystemUtil.cpp | 16 +- es-core/src/utils/FileSystemUtil.h | 6 + 7 files changed, 218 insertions(+), 83 deletions(-) diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 446d66c6f..c26cf6d5d 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -594,6 +594,32 @@ int main(int argc, char* argv[]) if (!checkApplicationDataDirectory()) return 1; + { + if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + // Create the logs folder in the application data directory. + const std::filesystem::path logsDir { + Utils::FileSystem::getAppDataDirectory().append("logs")}; + if (!Utils::FileSystem::isDirectorySTD(logsDir)) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_VERBOSE, ANDROID_APPLICATION_ID, + "Creating logs directory \"%s\"...", logsDir.string().c_str()); +#else + std::cout << "Creating logs directory \"" << logsDir.string() << "\"..." + << std::endl; +#endif + Utils::FileSystem::createDirectory(logsDir.string()); + if (!Utils::FileSystem::isDirectorySTD(logsDir)) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Couldn't create directory, permission problems?"); +#else + std::cerr << "Couldn't create directory, permission problems?" << std::endl; +#endif + } + } + } + } + // Start the logger. Log::init(); Log::open(); @@ -630,90 +656,138 @@ int main(int argc, char* argv[]) Settings::getInstance()->setInt("ScreenHeight", 720); #endif - // Check if the configuration file exists, and if not, create it. - // This should only happen on first application startup. - if (!Utils::FileSystem::existsSTD( - Utils::FileSystem::getAppDataDirectory().append("es_settings.xml"))) { - LOG(LogInfo) << "Settings file es_settings.xml does not exist, creating it..."; - Settings::getInstance()->saveFile(); - } - else if (settingsNeedSaving) { - LOG(LogInfo) << "Saving settings that were modified by command line options..."; - Settings::getInstance()->saveFile(); + { + if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + // Create the settings folder in the application data directory. + const std::filesystem::path settingsDir { + Utils::FileSystem::getAppDataDirectory().append("settings")}; + if (!Utils::FileSystem::isDirectorySTD(settingsDir)) { + LOG(LogInfo) << "Creating settings directory \"" << settingsDir.string() << "\"..."; + Utils::FileSystem::createDirectory(settingsDir.string()); + if (!Utils::FileSystem::isDirectorySTD(settingsDir)) { + LOG(LogError) << "Couldn't create directory, permission problems?"; + } + } + } } - // Check if the application release number has changed, which would normally mean that the - // user has upgraded to a new version. - int applicationRelease; - if ((applicationRelease = Settings::getInstance()->getInt("ApplicationRelease")) != - PROGRAM_RELEASE_NUMBER) { - if (applicationRelease != 0) { - LOG(LogInfo) << "Application release number changed from previous startup, from \"" - << applicationRelease << "\" to \"" << PROGRAM_RELEASE_NUMBER << "\""; + { + // Check if the configuration file exists, and if not, create it. + std::filesystem::path settingsPath; + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) + settingsPath = Utils::FileSystem::getAppDataDirectory().append("es_settings.xml"); + else + settingsPath = Utils::FileSystem::getAppDataDirectory() + .append("settings") + .append("es_settings.xml"); + + if (!Utils::FileSystem::existsSTD(settingsPath)) { + LOG(LogInfo) << "Settings file es_settings.xml does not exist, creating it..."; + Settings::getInstance()->saveFile(); } - else { - LOG(LogInfo) << "Application release number setting is blank, changing it to \"" - << PROGRAM_RELEASE_NUMBER << "\""; + else if (settingsNeedSaving) { + LOG(LogInfo) << "Saving settings that were modified by command line options..."; + Settings::getInstance()->saveFile(); } - Settings::getInstance()->setInt("ApplicationRelease", PROGRAM_RELEASE_NUMBER); - Settings::getInstance()->saveFile(); } - // Create the gamelists folder in the application data directory. - const std::filesystem::path gamelistsDir { - Utils::FileSystem::getAppDataDirectory().append("gamelists")}; - if (!Utils::FileSystem::existsSTD(gamelistsDir)) { - LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir.string() << "\"..."; - Utils::FileSystem::createDirectory(gamelistsDir.string()); + { + // Check if the application release number has changed, which would normally mean that the + // user has upgraded to a new version. + int applicationRelease; + if ((applicationRelease = Settings::getInstance()->getInt("ApplicationRelease")) != + PROGRAM_RELEASE_NUMBER) { + if (applicationRelease != 0) { + LOG(LogInfo) << "Application release number changed from previous startup, from \"" + << applicationRelease << "\" to \"" << PROGRAM_RELEASE_NUMBER << "\""; + } + else { + LOG(LogInfo) << "Application release number setting is blank, changing it to \"" + << PROGRAM_RELEASE_NUMBER << "\""; + } + Settings::getInstance()->setInt("ApplicationRelease", PROGRAM_RELEASE_NUMBER); + Settings::getInstance()->saveFile(); + } + } + + { + // Create the gamelists folder in the application data directory. + const std::filesystem::path gamelistsDir { + Utils::FileSystem::getAppDataDirectory().append("gamelists")}; if (!Utils::FileSystem::existsSTD(gamelistsDir)) { - LOG(LogWarning) << "Couldn't create directory, permission problems?\n"; + LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir.string() << "\"..."; + Utils::FileSystem::createDirectory(gamelistsDir.string()); + if (!Utils::FileSystem::existsSTD(gamelistsDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } } } + { #if defined(__ANDROID__) - const std::filesystem::path themeDir { - Utils::FileSystem::getAppDataDirectory().append("themes")}; - if (!Utils::FileSystem::existsSTD(themeDir)) { - LOG(LogInfo) << "Creating themes directory \"" << themeDir.string() << "\"..."; - - Utils::FileSystem::createDirectory(themeDir.string()); + const std::filesystem::path themeDir { + Utils::FileSystem::getAppDataDirectory().append("themes")}; if (!Utils::FileSystem::existsSTD(themeDir)) { - LOG(LogWarning) << "Couldn't create directory, permission problems?"; + LOG(LogInfo) << "Creating themes directory \"" << themeDir.string() << "\"..."; + + Utils::FileSystem::createDirectory(themeDir.string()); + if (!Utils::FileSystem::existsSTD(themeDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } } - } #else - // Create the themes folder in the application data directory (or elsewhere if the - // UserThemeDirectory setting has been defined). - const std::filesystem::path defaultUserThemeDir { - Utils::FileSystem::getAppDataDirectory().append("themes")}; - std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath( - Settings::getInstance()->getString("UserThemeDirectory"))}; - std::filesystem::path userThemeDirectory; + // Create the themes folder in the application data directory (or elsewhere if the + // UserThemeDirectory setting has been defined). + const std::filesystem::path defaultUserThemeDir { + Utils::FileSystem::getAppDataDirectory().append("themes")}; + std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath( + Settings::getInstance()->getString("UserThemeDirectory"))}; + std::filesystem::path userThemeDirectory; - if (userThemeDirSetting.empty()) - userThemeDirectory = defaultUserThemeDir; - else - userThemeDirectory = userThemeDirSetting; + if (userThemeDirSetting.empty()) + userThemeDirectory = defaultUserThemeDir; + else + userThemeDirectory = userThemeDirSetting; - if (!Utils::FileSystem::existsSTD(userThemeDirectory)) { - LOG(LogInfo) << "Creating themes directory \"" << userThemeDirectory.string() << "\"..."; - - Utils::FileSystem::createDirectory(userThemeDirectory.string()); if (!Utils::FileSystem::existsSTD(userThemeDirectory)) { - LOG(LogWarning) << "Couldn't create directory, permission problems?"; + LOG(LogInfo) << "Creating themes directory \"" << userThemeDirectory.string() + << "\"..."; + + Utils::FileSystem::createDirectory(userThemeDirectory.string()); + if (!Utils::FileSystem::existsSTD(userThemeDirectory)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } + } +#endif + } + + { + // Create the scripts folder in the application data directory. This is only required + // for custom event scripts so it's also created as a convenience. + const std::filesystem::path scriptsDir { + Utils::FileSystem::getAppDataDirectory().append("scripts")}; + if (!Utils::FileSystem::existsSTD(scriptsDir)) { + LOG(LogInfo) << "Creating scripts directory \"" << scriptsDir.string() << "\"..."; + Utils::FileSystem::createDirectory(scriptsDir.string()); + if (!Utils::FileSystem::existsSTD(scriptsDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } } } -#endif - // Create the scripts folder in the application data directory. This is only required - // for custom event scripts so it's also created as a convenience. - const std::filesystem::path scriptsDir { - Utils::FileSystem::getAppDataDirectory().append("scripts")}; - if (!Utils::FileSystem::existsSTD(scriptsDir)) { - LOG(LogInfo) << "Creating scripts directory \"" << scriptsDir.string() << "\"..."; - Utils::FileSystem::createDirectory(scriptsDir.string()); - if (!Utils::FileSystem::existsSTD(scriptsDir)) { - LOG(LogWarning) << "Couldn't create directory, permission problems?\n"; + { + if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + // Create the controllers folder in the application data directory. + const std::filesystem::path controllersDir { + Utils::FileSystem::getAppDataDirectory().append("controllers")}; + if (!Utils::FileSystem::existsSTD(controllersDir)) { + LOG(LogInfo) << "Creating controllers directory \"" << controllersDir.string() + << "\"..."; + Utils::FileSystem::createDirectory(controllersDir.string()); + if (!Utils::FileSystem::existsSTD(controllersDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } + } } } diff --git a/es-app/src/scrapers/GamesDBJSONScraperResources.cpp b/es-app/src/scrapers/GamesDBJSONScraperResources.cpp index e68198344..8477b23c8 100644 --- a/es-app/src/scrapers/GamesDBJSONScraperResources.cpp +++ b/es-app/src/scrapers/GamesDBJSONScraperResources.cpp @@ -41,9 +41,9 @@ namespace constexpr int MAX_WAIT_ITER {MAX_WAIT_MS / POLL_TIME_MS}; constexpr char SCRAPER_RESOURCES_DIR[] {"scrapers"}; - constexpr char DEVELOPERS_JSON_FILE[] {"gamesdb_developers.json"}; - constexpr char PUBLISHERS_JSON_FILE[] {"gamesdb_publishers.json"}; - constexpr char GENRES_JSON_FILE[] {"gamesdb_genres.json"}; + constexpr char DEVELOPERS_JSON_FILE[] {"thegamesdb_developers.json"}; + constexpr char PUBLISHERS_JSON_FILE[] {"thegamesdb_publishers.json"}; + constexpr char GENRES_JSON_FILE[] {"thegamesdb_genres.json"}; constexpr char DEVELOPERS_ENDPOINT[] {"/Developers"}; constexpr char PUBLISHERS_ENDPOINT[] {"/Publishers"}; constexpr char GENRES_ENDPOINT[] {"/Genres"}; diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index a9c38f176..cb859a773 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -86,8 +86,17 @@ void InputManager::init() // the bundled mapping is incorrect, or the SDL version is a bit older, it makes sense to be // able to customize this. If a controller GUID is present in the mappings file that is // already present inside SDL, the custom mapping will overwrite the bundled one. - std::filesystem::path mappingsFile { - Utils::FileSystem::getAppDataDirectory().append("es_controller_mappings.cfg")}; + std::filesystem::path mappingsFile; + + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + mappingsFile = + Utils::FileSystem::getAppDataDirectory().append("es_controller_mappings.cfg"); + } + else { + mappingsFile = Utils::FileSystem::getAppDataDirectory() + .append("controllers") + .append("es_controller_mappings.cfg"); + } if (!Utils::FileSystem::existsSTD(mappingsFile)) mappingsFile = ResourceManager::getInstance().getResourcePath( @@ -255,12 +264,28 @@ void InputManager::doOnFinish() std::string InputManager::getConfigPath() { - return Utils::FileSystem::getAppDataDirectory().append("es_input.xml").string(); + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + return Utils::FileSystem::getAppDataDirectory().append("es_input.xml").string(); + } + else { + return Utils::FileSystem::getAppDataDirectory() + .append("settings") + .append("es_input.xml") + .string(); + } } std::string InputManager::getTemporaryConfigPath() { - return Utils::FileSystem::getAppDataDirectory().append("es_temporaryinput.xml").string(); + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + return Utils::FileSystem::getAppDataDirectory().append("es_temporaryinput.xml").string(); + } + else { + return Utils::FileSystem::getAppDataDirectory() + .append("settings") + .append("es_temporaryinput.xml") + .string(); + } } int InputManager::getNumConfiguredDevices() diff --git a/es-core/src/Log.cpp b/es-core/src/Log.cpp index fe0ae4eff..e26e76f08 100644 --- a/es-core/src/Log.cpp +++ b/es-core/src/Log.cpp @@ -8,6 +8,7 @@ // #include "Log.h" +#include "Settings.h" #include "utils/StringUtil.h" LogLevel Log::getReportingLevel() @@ -24,7 +25,11 @@ void Log::setReportingLevel(LogLevel level) void Log::init() { - sLogPath = Utils::FileSystem::getAppDataDirectory().append("es_log.txt"); + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) + sLogPath = Utils::FileSystem::getAppDataDirectory().append("es_log.txt"); + else + sLogPath = Utils::FileSystem::getAppDataDirectory().append("logs").append("es_log.txt"); + Utils::FileSystem::removeFile(sLogPath.string() + ".bak"); // Rename the previous log file. Utils::FileSystem::renameFile(sLogPath.string(), sLogPath.string() + ".bak", true); diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 0874f607d..853468a24 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -46,6 +46,7 @@ namespace "DebugGrid", "DebugText", "DebugImage", + "LegacyAppDataDirectory", "ScraperFilter", "TransitionsSystemToSystem", "TransitionsSystemToGamelist", @@ -77,6 +78,8 @@ Settings::Settings() { mWasChanged = false; setDefaults(); + if (Utils::FileSystem::getAppDataDirectory().filename().string() == ".emulationstation") + mBoolMap["LegacyAppDataDirectory"] = std::make_pair(true, true); loadFile(); } @@ -347,6 +350,7 @@ void Settings::setDefaults() mBoolMap["DebugGrid"] = {false, false}; mBoolMap["DebugText"] = {false, false}; mBoolMap["DebugImage"] = {false, false}; + mBoolMap["LegacyAppDataDirectory"] = {false, false}; mIntMap["ScraperFilter"] = {0, 0}; mIntMap["TransitionsSystemToSystem"] = {ViewTransitionAnimation::INSTANT, ViewTransitionAnimation::INSTANT}; @@ -364,9 +368,14 @@ void Settings::setDefaults() void Settings::saveFile() { - LOG(LogDebug) << "Settings::saveFile(): Saving settings to es_settings.xml"; - const std::filesystem::path path { - Utils::FileSystem::getAppDataDirectory().append("es_settings.xml")}; + std::filesystem::path path; + if (mBoolMap["LegacyAppDataDirectory"].second == true) { + path = Utils::FileSystem::getAppDataDirectory().append("es_settings.xml"); + } + else { + path = + Utils::FileSystem::getAppDataDirectory().append("settings").append("es_settings.xml"); + } pugi::xml_document doc; @@ -396,18 +405,24 @@ void Settings::saveFile() void Settings::loadFile() { - std::filesystem::path configFile { - Utils::FileSystem::getAppDataDirectory().append("es_settings.xml")}; + std::filesystem::path path; + if (mBoolMap["LegacyAppDataDirectory"].second == true) { + path = Utils::FileSystem::getAppDataDirectory().append("es_settings.xml"); + } + else { + path = + Utils::FileSystem::getAppDataDirectory().append("settings").append("es_settings.xml"); + } - if (!Utils::FileSystem::existsSTD(configFile)) + if (!Utils::FileSystem::existsSTD(path)) return; pugi::xml_document doc; #if defined(_WIN64) pugi::xml_parse_result result { - doc.load_file(Utils::String::stringToWideString(configFile.string()).c_str())}; + doc.load_file(Utils::String::stringToWideString(path.string()).c_str())}; #else - pugi::xml_parse_result result {doc.load_file(configFile.string().c_str())}; + pugi::xml_parse_result result {doc.load_file(path.string().c_str())}; #endif if (!result) { LOG(LogError) << "Couldn't parse the es_settings.xml file: " << result.description(); diff --git a/es-core/src/utils/FileSystemUtil.cpp b/es-core/src/utils/FileSystemUtil.cpp index 2f305df31..e09353bad 100644 --- a/es-core/src/utils/FileSystemUtil.cpp +++ b/es-core/src/utils/FileSystemUtil.cpp @@ -199,7 +199,7 @@ namespace Utils return homePath; #if defined(__ANDROID__) - homePath = AndroidVariables::sAppDataDirectory; + homePath = FileSystemVariables::sAppDataDirectory; return homePath; #endif @@ -248,7 +248,7 @@ namespace Utils #if defined(__ANDROID__) homePathSTD = - std::filesystem::path {getGenericPath(AndroidVariables::sAppDataDirectory)}; + std::filesystem::path {getGenericPath(FileSystemVariables::sAppDataDirectory)}; return homePathSTD; #endif #if defined(_WIN64) @@ -318,7 +318,17 @@ namespace Utils #if defined(__ANDROID__) return getHomePathSTD(); #else - return getHomePathSTD().append(".emulationstation"); + if (FileSystemVariables::sAppDataDirectory.empty()) { + if (Utils::FileSystem::existsSTD(getHomePathSTD().append(".emulationstation"))) { + FileSystemVariables::sAppDataDirectory = + getHomePathSTD().append(".emulationstation"); + } + else { + FileSystemVariables::sAppDataDirectory = getHomePathSTD().append("ES-DE"); + } + } + + return FileSystemVariables::sAppDataDirectory; #endif } diff --git a/es-core/src/utils/FileSystemUtil.h b/es-core/src/utils/FileSystemUtil.h index eb382c6d6..90a5f819b 100644 --- a/es-core/src/utils/FileSystemUtil.h +++ b/es-core/src/utils/FileSystemUtil.h @@ -15,6 +15,12 @@ #include #include +class FileSystemVariables +{ +public: + static inline std::filesystem::path sAppDataDirectory; +}; + namespace Utils { namespace FileSystem