From 3995b4662df0a6047ff0b5175a86dfb104cb31b9 Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Thu, 10 Oct 2024 14:02:54 +0200 Subject: [PATCH] UI: Fix crash when providing scene collection or profile via CLI When a starting scene collection or profile is provided, current code would crash as the corresponding collections and management functions do not exist yet (they are tied to OBSBasic, which is not initialized that early in the program execution). This change moves the checks for command line arguments into OBSBasic into the parts responsible for initializing profiles and scene collections and check for arguments provided via command line there. --- UI/obs-app.cpp | 42 ++++-------------------------- UI/obs-app.hpp | 2 +- UI/window-basic-main.cpp | 55 ++++++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 63 deletions(-) diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp index 7f670ff79..76308af35 100644 --- a/UI/obs-app.cpp +++ b/UI/obs-app.cpp @@ -677,8 +677,6 @@ bool OBSApp::InitGlobalConfig() bool OBSApp::InitUserConfig(std::filesystem::path &userConfigLocation, uint32_t lastVersion) { - bool hasChanges = false; - const std::string userConfigFile = userConfigLocation.u8string() + "/obs-studio/user.ini"; int errorCode = userConfig.Open(userConfigFile.c_str(), CONFIG_OPEN_ALWAYS); @@ -688,45 +686,13 @@ bool OBSApp::InitUserConfig(std::filesystem::path &userConfigLocation, uint32_t return false; } - hasChanges = MigrateLegacySettings(lastVersion); - - if (!opt_starting_collection.empty()) { - const OBSBasic *basic = reinterpret_cast(GetMainWindow()); - const std::optional foundCollection = - basic->GetSceneCollectionByName(opt_starting_collection); - - if (foundCollection) { - config_set_string(userConfig, "Basic", "SceneCollection", foundCollection.value().name.c_str()); - config_set_string(userConfig, "Basic", "SceneCollectionFile", - foundCollection.value().fileName.c_str()); - hasChanges = true; - } - } - - if (!opt_starting_profile.empty()) { - const OBSBasic *basic = reinterpret_cast(GetMainWindow()); - - const std::optional foundProfile = basic->GetProfileByName(opt_starting_profile); - - if (foundProfile) { - config_set_string(userConfig, "Basic", "Profile", foundProfile.value().name.c_str()); - config_set_string(userConfig, "Basic", "ProfileDir", - foundProfile.value().directoryName.c_str()); - - hasChanges = true; - } - } - - if (hasChanges) { - config_save_safe(userConfig, "tmp", nullptr); - } - + MigrateLegacySettings(lastVersion); InitUserConfigDefaults(); return true; } -bool OBSApp::MigrateLegacySettings(const uint32_t lastVersion) +void OBSApp::MigrateLegacySettings(const uint32_t lastVersion) { bool hasChanges = false; @@ -766,7 +732,9 @@ bool OBSApp::MigrateLegacySettings(const uint32_t lastVersion) hasChanges = true; } - return hasChanges; + if (hasChanges) { + userConfig.SaveSafe("tmp"); + } } static constexpr string_view OBSGlobalIniPath = "/obs-studio/global.ini"; diff --git a/UI/obs-app.hpp b/UI/obs-app.hpp index 203eacd39..dea5e530b 100644 --- a/UI/obs-app.hpp +++ b/UI/obs-app.hpp @@ -113,7 +113,7 @@ private: bool InitGlobalLocationDefaults(); bool MigrateGlobalSettings(); - bool MigrateLegacySettings(uint32_t lastVersion); + void MigrateLegacySettings(uint32_t lastVersion); bool InitUserConfig(std::filesystem::path &userConfigLocation, uint32_t lastVersion); void InitUserConfigDefaults(); diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index 280efa9dc..04fa93fc1 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -121,6 +121,9 @@ QCef *cef = nullptr; QCefCookieManager *panel_cookies = nullptr; bool cef_js_avail = false; +extern std::string opt_starting_profile; +extern std::string opt_starting_collection; + void DestroyPanelCookieManager(); namespace { @@ -1876,22 +1879,21 @@ bool OBSBasic::InitBasicConfig() RefreshProfiles(true); - std::string currentProfileName{config_get_string(App()->GetUserConfig(), "Basic", "Profile")}; + const std::string currentProfileName{config_get_string(App()->GetUserConfig(), "Basic", "Profile")}; + const std::optional currentProfile = GetProfileByName(currentProfileName); + const std::optional foundProfile = GetProfileByName(opt_starting_profile); - auto foundProfile = GetProfileByName(currentProfileName); - - if (!foundProfile) { - const OBSProfile &newProfile = CreateProfile(currentProfileName); - - ActivateProfile(newProfile); - } else { - // TODO: Remove duplicate code from OBS initialization and just use ActivateProfile here instead - int code = activeConfiguration.Open(foundProfile.value().profileFile.u8string().c_str(), - CONFIG_OPEN_ALWAYS); - if (code != CONFIG_SUCCESS) { - OBSErrorBox(NULL, "Failed to open basic.ini: %d", code); - return false; + try { + if (foundProfile) { + ActivateProfile(foundProfile.value()); + } else if (currentProfile) { + ActivateProfile(currentProfile.value()); + } else { + SetupNewProfile(currentProfileName); } + } catch (const std::logic_error &) { + OBSErrorBox(NULL, "Failed to open basic.ini: %d", -1); + return false; } return InitBasicConfigDefaults(); @@ -2170,19 +2172,22 @@ void OBSBasic::OBSInit() { ProfileScope("OBSBasic::Load"); - disableSaving--; + const std::string sceneCollectionName{ + config_get_string(App()->GetUserConfig(), "Basic", "SceneCollection")}; + const std::optional configuredCollection = + GetSceneCollectionByName(sceneCollectionName); + const std::optional foundCollection = + GetSceneCollectionByName(opt_starting_collection); - try { - const OBSSceneCollection ¤tCollection = GetCurrentSceneCollection(); - ActivateSceneCollection(currentCollection); - } catch (const std::invalid_argument &) { - const std::string collectionName = - config_get_string(App()->GetUserConfig(), "Basic", "SceneCollection"); - - SetupNewSceneCollection(collectionName); + if (foundCollection) { + ActivateSceneCollection(foundCollection.value()); + } else if (configuredCollection) { + ActivateSceneCollection(configuredCollection.value()); + } else { + disableSaving--; + SetupNewSceneCollection(sceneCollectionName); + disableSaving++; } - - disableSaving++; } loaded = true;