提交 ebf3abf0 编写于 作者: J jp9000

UI: Use saving functions for profiles/scenes

Replaces all the json/config loading/saving functions with safe
variants to reduce the chance of potential file corruption as much as
possible.

Also does a minor refactor of json writing by using
obs_data_save_json_safe for writing json files instead of manually using
obs_data_get_json and os_quick_write_utf8 each time.
上级 e479d4d0
...@@ -225,7 +225,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, ...@@ -225,7 +225,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
newDir.c_str()); newDir.c_str());
config_set_string(config, "General", "Name", newName.c_str()); config_set_string(config, "General", "Name", newName.c_str());
config.Save(); config.SaveSafe("tmp");
config.Swap(basicConfig); config.Swap(basicConfig);
InitBasicConfigDefaults(); InitBasicConfigDefaults();
RefreshProfiles(); RefreshProfiles();
...@@ -237,7 +237,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, ...@@ -237,7 +237,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
create_new ? "clean" : "duplicate", newDir.c_str()); create_new ? "clean" : "duplicate", newDir.c_str());
blog(LOG_INFO, "------------------------------------------------"); blog(LOG_INFO, "------------------------------------------------");
config_save(App()->GlobalConfig()); config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
UpdateTitleBar(); UpdateTitleBar();
return true; return true;
} }
...@@ -424,7 +424,7 @@ void OBSBasic::on_actionRemoveProfile_triggered() ...@@ -424,7 +424,7 @@ void OBSBasic::on_actionRemoveProfile_triggered()
ResetProfileData(); ResetProfileData();
DeleteProfile(oldName.c_str(), oldDir.c_str()); DeleteProfile(oldName.c_str(), oldDir.c_str());
RefreshProfiles(); RefreshProfiles();
config_save(App()->GlobalConfig()); config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
blog(LOG_INFO, "Switched to profile '%s' (%s)", blog(LOG_INFO, "Switched to profile '%s' (%s)",
newName.c_str(), newDir); newName.c_str(), newDir);
...@@ -475,7 +475,7 @@ void OBSBasic::ChangeProfile() ...@@ -475,7 +475,7 @@ void OBSBasic::ChangeProfile()
InitBasicConfigDefaults(); InitBasicConfigDefaults();
ResetProfileData(); ResetProfileData();
RefreshProfiles(); RefreshProfiles();
config_save(App()->GlobalConfig()); config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
UpdateTitleBar(); UpdateTitleBar();
blog(LOG_INFO, "Switched to profile '%s' (%s)", blog(LOG_INFO, "Switched to profile '%s' (%s)",
......
...@@ -48,11 +48,8 @@ template <typename Func> static void EnumSceneCollections(Func &&cb) ...@@ -48,11 +48,8 @@ template <typename Func> static void EnumSceneCollections(Func &&cb)
if (glob->gl_pathv[i].directory) if (glob->gl_pathv[i].directory)
continue; continue;
BPtr<char> fileData = os_quick_read_utf8_file(filePath); obs_data_t *data = obs_data_create_from_json_file_safe(filePath,
if (!fileData) "bak");
continue;
obs_data_t *data = obs_data_create_from_json(fileData);
std::string name = obs_data_get_string(data, "name"); std::string name = obs_data_get_string(data, "name");
/* if no name found, use the file name as the name /* if no name found, use the file name as the name
......
...@@ -308,16 +308,9 @@ void OBSBasic::Save(const char *file) ...@@ -308,16 +308,9 @@ void OBSBasic::Save(const char *file)
{ {
obs_data_array_t *sceneOrder = SaveSceneListOrder(); obs_data_array_t *sceneOrder = SaveSceneListOrder();
obs_data_t *saveData = GenerateSaveData(sceneOrder); obs_data_t *saveData = GenerateSaveData(sceneOrder);
const char *jsonData = obs_data_get_json(saveData);
if (!!jsonData) { if (!obs_data_save_json_safe(saveData, file, "tmp", "bak"))
/* TODO: maybe a message box here? */ blog(LOG_ERROR, "Could not save scene data to %s", file);
bool success = os_quick_write_utf8_file(file, jsonData,
strlen(jsonData), false);
if (!success)
blog(LOG_ERROR, "Could not save scene data to %s",
file);
}
obs_data_release(saveData); obs_data_release(saveData);
obs_data_array_release(sceneOrder); obs_data_array_release(sceneOrder);
...@@ -450,23 +443,23 @@ void OBSBasic::CleanupUnusedSources() ...@@ -450,23 +443,23 @@ void OBSBasic::CleanupUnusedSources()
void OBSBasic::Load(const char *file) void OBSBasic::Load(const char *file)
{ {
if (!file) { if (!file || !os_file_exists(file)) {
blog(LOG_ERROR, "Could not find file %s", file); blog(LOG_ERROR, "Could not find file %s", file);
return; return;
} }
BPtr<char> jsonData = os_quick_read_utf8_file(file); disableSaving++;
if (!jsonData) {
obs_data_t *data = obs_data_create_from_json_file_safe(file, "bak");
if (!data) {
disableSaving--;
CreateDefaultScene(); CreateDefaultScene();
SaveProject(); SaveProject();
return; return;
} }
disableSaving++;
ClearSceneData(); ClearSceneData();
obs_data_t *data = obs_data_create_from_json(jsonData);
obs_data_array_t *sceneOrder = obs_data_get_array(data, "scene_order"); obs_data_array_t *sceneOrder = obs_data_get_array(data, "scene_order");
obs_data_array_t *sources = obs_data_get_array(data, "sources"); obs_data_array_t *sources = obs_data_get_array(data, "sources");
const char *sceneName = obs_data_get_string(data, const char *sceneName = obs_data_get_string(data,
...@@ -535,9 +528,8 @@ void OBSBasic::SaveService() ...@@ -535,9 +528,8 @@ void OBSBasic::SaveService()
obs_data_set_string(data, "type", obs_service_get_type(service)); obs_data_set_string(data, "type", obs_service_get_type(service));
obs_data_set_obj(data, "settings", settings); obs_data_set_obj(data, "settings", settings);
const char *json = obs_data_get_json(data); if (!obs_data_save_json_safe(data, serviceJsonPath, "tmp", "bak"))
blog(LOG_WARNING, "Failed to save service");
os_quick_write_utf8_file(serviceJsonPath, json, strlen(json), false);
obs_data_release(settings); obs_data_release(settings);
obs_data_release(data); obs_data_release(data);
...@@ -553,11 +545,8 @@ bool OBSBasic::LoadService() ...@@ -553,11 +545,8 @@ bool OBSBasic::LoadService()
if (ret <= 0) if (ret <= 0)
return false; return false;
BPtr<char> jsonText = os_quick_read_utf8_file(serviceJsonPath); obs_data_t *data = obs_data_create_from_json_file_safe(serviceJsonPath,
if (!jsonText) "bak");
return false;
obs_data_t *data = obs_data_create_from_json(jsonText);
obs_data_set_default_string(data, "type", "rtmp_common"); obs_data_set_default_string(data, "type", "rtmp_common");
type = obs_data_get_string(data, "type"); type = obs_data_get_string(data, "type");
...@@ -632,7 +621,7 @@ bool OBSBasic::InitBasicConfigDefaults() ...@@ -632,7 +621,7 @@ bool OBSBasic::InitBasicConfigDefaults()
track = 1ULL << (track - 1); track = 1ULL << (track - 1);
config_set_uint(basicConfig, "AdvOut", "RecTracks", track); config_set_uint(basicConfig, "AdvOut", "RecTracks", track);
config_remove_value(basicConfig, "AdvOut", "RecTrackIndex"); config_remove_value(basicConfig, "AdvOut", "RecTrackIndex");
config_save(basicConfig); config_save_safe(basicConfig, "tmp", nullptr);
} }
/* ----------------------------------------------------- */ /* ----------------------------------------------------- */
...@@ -768,7 +757,7 @@ bool OBSBasic::InitBasicConfig() ...@@ -768,7 +757,7 @@ bool OBSBasic::InitBasicConfig()
"Basic", "Profile"); "Basic", "Profile");
config_set_string(basicConfig, "General", "Name", curName); config_set_string(basicConfig, "General", "Name", curName);
basicConfig.Save(); basicConfig.SaveSafe("tmp");
} }
return InitBasicConfigDefaults(); return InitBasicConfigDefaults();
...@@ -1152,7 +1141,7 @@ OBSBasic::~OBSBasic() ...@@ -1152,7 +1141,7 @@ OBSBasic::~OBSBasic()
lastGeom.y()); lastGeom.y());
config_set_bool(App()->GlobalConfig(), "BasicWindow", "PreviewEnabled", config_set_bool(App()->GlobalConfig(), "BasicWindow", "PreviewEnabled",
previewEnabled); previewEnabled);
config_save(App()->GlobalConfig()); config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
#ifdef _WIN32 #ifdef _WIN32
uint32_t winVer = GetWindowsVersion(); uint32_t winVer = GetWindowsVersion();
...@@ -1669,7 +1658,7 @@ void OBSBasic::updateFileFinished(const QString &text, const QString &error) ...@@ -1669,7 +1658,7 @@ void OBSBasic::updateFileFinished(const QString &text, const QString &error)
long long t = (long long)time(nullptr); long long t = (long long)time(nullptr);
config_set_int(App()->GlobalConfig(), "General", config_set_int(App()->GlobalConfig(), "General",
"LastUpdateCheck", t); "LastUpdateCheck", t);
config_save(App()->GlobalConfig()); config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
} }
} else { } else {
blog(LOG_WARNING, "Bad JSON file received from server"); blog(LOG_WARNING, "Bad JSON file received from server");
......
...@@ -1069,12 +1069,10 @@ OBSPropertiesView *OBSBasicSettings::CreateEncoderPropertyView( ...@@ -1069,12 +1069,10 @@ OBSPropertiesView *OBSBasicSettings::CreateEncoderPropertyView(
int ret = GetProfilePath(encoderJsonPath, sizeof(encoderJsonPath), int ret = GetProfilePath(encoderJsonPath, sizeof(encoderJsonPath),
path); path);
if (ret > 0) { if (ret > 0) {
BPtr<char> jsonData = os_quick_read_utf8_file(encoderJsonPath); obs_data_t *data = obs_data_create_from_json_file_safe(
if (!!jsonData) { encoderJsonPath, "bak");
obs_data_t *data = obs_data_create_from_json(jsonData); obs_data_apply(settings, data);
obs_data_apply(settings, data); obs_data_release(data);
obs_data_release(data);
}
} }
view = new OBSPropertiesView(settings, encoder, view = new OBSPropertiesView(settings, encoder,
...@@ -1985,11 +1983,8 @@ static void WriteJsonData(OBSPropertiesView *view, const char *path) ...@@ -1985,11 +1983,8 @@ static void WriteJsonData(OBSPropertiesView *view, const char *path)
if (ret > 0) { if (ret > 0) {
obs_data_t *settings = view->GetSettings(); obs_data_t *settings = view->GetSettings();
if (settings) { if (settings) {
const char *json = obs_data_get_json(settings); obs_data_save_json_safe(settings, full_path,
if (json && *json) { "tmp", "bak");
os_quick_write_utf8_file(full_path, json,
strlen(json), false);
}
} }
} }
} }
...@@ -2247,8 +2242,8 @@ void OBSBasicSettings::SaveSettings() ...@@ -2247,8 +2242,8 @@ void OBSBasicSettings::SaveSettings()
if (videoChanged || advancedChanged) if (videoChanged || advancedChanged)
main->ResetVideo(); main->ResetVideo();
config_save(main->Config()); config_save_safe(main->Config(), "tmp", nullptr);
config_save(GetGlobalConfig()); config_save_safe(GetGlobalConfig(), "tmp", nullptr);
main->SaveProject(); main->SaveProject();
if (Changed()) { if (Changed()) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册