瀏覽代碼

UI: Fix collision of existing backup files for new scene collections

The new Scene Collection code uses the lazy creation behaviour of
OBSBasic::Load, which itself uses obs_data_create_from_json_file_safe.

The internal implementation will create a new scene collection with the
contents of an existing backup file with the same name however, thus
users would end up with a nominally "new" scene collection that
contains contents of an old backup.

This update will remove any existing backup file colliding with the
name of the new, duplicated, or renamed, scene collection and remove it
before activating it (and having OBSBasic::Load create a new one).
PatTheMav 11 月之前
父節點
當前提交
b285a849b9
共有 1 個文件被更改,包括 18 次插入0 次删除
  1. 18 0
      UI/window-basic-main-scene-collections.cpp

+ 18 - 0
UI/window-basic-main-scene-collections.cpp

@@ -56,6 +56,21 @@ void updateSortedSceneCollections(const OBSSceneCollectionCache &collections)
 
 	sortedSceneCollections.swap(newList);
 }
+
+void cleanBackupCollision(const OBSSceneCollection &collection)
+{
+	std::filesystem::path backupFilePath = collection.collectionFile;
+	backupFilePath.replace_extension(".json.bak");
+
+	if (std::filesystem::exists(backupFilePath)) {
+		try {
+			std::filesystem::remove(backupFilePath);
+		} catch (std::filesystem::filesystem_error &) {
+			throw std::logic_error("Failed to remove pre-existing scene collection backup file: " +
+					       backupFilePath.u8string());
+		}
+	}
+}
 } // namespace
 
 // MARK: - Main Scene Collection Management Functions
@@ -66,6 +81,7 @@ void OBSBasic::SetupNewSceneCollection(const std::string &collectionName)
 
 	OnEvent(OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGING);
 
+	cleanBackupCollision(newCollection);
 	ActivateSceneCollection(newCollection);
 
 	blog(LOG_INFO, "Created scene collection '%s' (clean, %s)", newCollection.name.c_str(),
@@ -114,6 +130,7 @@ void OBSBasic::SetupDuplicateSceneCollection(const std::string &collectionName)
 
 	obs_data_save_json_safe(collection, newCollection.collectionFile.u8string().c_str(), "tmp", nullptr);
 
+	cleanBackupCollision(newCollection);
 	ActivateSceneCollection(newCollection);
 
 	blog(LOG_INFO, "Created scene collection '%s' (duplicate, %s)", newCollection.name.c_str(),
@@ -145,6 +162,7 @@ void OBSBasic::SetupRenameSceneCollection(const std::string &collectionName)
 
 	obs_data_save_json_safe(collection, newCollection.collectionFile.u8string().c_str(), "tmp", nullptr);
 
+	cleanBackupCollision(newCollection);
 	ActivateSceneCollection(newCollection);
 	RemoveSceneCollection(currentCollection);