mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-02 19:08:03 -06:00
* Log filters cleanup * Clearer dialog options for config update * Smaller button labels These don't auto-resize, and I don't want to read SDL's docs for something so small.
110 lines
3.4 KiB
C++
110 lines
3.4 KiB
C++
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include <algorithm>
|
|
#include <fstream>
|
|
#include <iomanip>
|
|
#include <map>
|
|
#include <common/path_util.h>
|
|
#include <common/scm_rev.h>
|
|
#include "common/logging/log.h"
|
|
#include "user_settings.h"
|
|
|
|
using json = nlohmann::json;
|
|
|
|
// Singleton storage
|
|
std::shared_ptr<UserSettingsImpl> UserSettingsImpl::s_instance = nullptr;
|
|
std::mutex UserSettingsImpl::s_mutex;
|
|
|
|
// Singleton
|
|
UserSettingsImpl::UserSettingsImpl() = default;
|
|
|
|
UserSettingsImpl::~UserSettingsImpl() {
|
|
Save();
|
|
}
|
|
|
|
std::shared_ptr<UserSettingsImpl> UserSettingsImpl::GetInstance() {
|
|
std::lock_guard lock(s_mutex);
|
|
if (!s_instance)
|
|
s_instance = std::make_shared<UserSettingsImpl>();
|
|
return s_instance;
|
|
}
|
|
|
|
void UserSettingsImpl::SetInstance(std::shared_ptr<UserSettingsImpl> instance) {
|
|
std::lock_guard lock(s_mutex);
|
|
s_instance = std::move(instance);
|
|
}
|
|
|
|
bool UserSettingsImpl::Save() const {
|
|
const auto path = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "users.json";
|
|
try {
|
|
json j;
|
|
j["Users"] = m_userManager.GetUsers();
|
|
j["Users"]["commit_hash"] = std::string(Common::g_scm_rev);
|
|
|
|
std::ofstream out(path);
|
|
if (!out) {
|
|
LOG_ERROR(Config, "Failed to open user settings for writing: {}", path.string());
|
|
return false;
|
|
}
|
|
out << std::setw(2) << j;
|
|
return !out.fail();
|
|
} catch (const std::exception& e) {
|
|
LOG_ERROR(Config, "Error saving user settings: {}", e.what());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool UserSettingsImpl::Load() {
|
|
const auto path = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "users.json";
|
|
try {
|
|
if (!std::filesystem::exists(path)) {
|
|
LOG_DEBUG(Config, "User settings file not found: {}", path.string());
|
|
// Create default user if no file exists
|
|
if (m_userManager.GetUsers().user.empty()) {
|
|
m_userManager.GetUsers() = m_userManager.CreateDefaultUsers();
|
|
}
|
|
Save(); // Save default users
|
|
return false;
|
|
}
|
|
|
|
std::ifstream in(path);
|
|
if (!in) {
|
|
LOG_ERROR(Config, "Failed to open user settings: {}", path.string());
|
|
return false;
|
|
}
|
|
|
|
json j;
|
|
in >> j;
|
|
|
|
// Create a default Users object
|
|
auto default_users = m_userManager.CreateDefaultUsers();
|
|
|
|
// Convert default_users to json for merging
|
|
json default_json;
|
|
default_json["Users"] = default_users;
|
|
|
|
// Merge the loaded json with defaults (preserves existing data, adds missing fields)
|
|
if (j.contains("Users")) {
|
|
json current = default_json["Users"];
|
|
current.update(j["Users"]);
|
|
m_userManager.GetUsers() = current.get<Users>();
|
|
} else {
|
|
m_userManager.GetUsers() = default_users;
|
|
}
|
|
|
|
if (m_userManager.GetUsers().commit_hash != Common::g_scm_rev) {
|
|
Save();
|
|
}
|
|
|
|
LOG_DEBUG(Config, "User settings loaded successfully");
|
|
return true;
|
|
} catch (const std::exception& e) {
|
|
LOG_ERROR(Config, "Error loading user settings: {}", e.what());
|
|
// Fall back to defaults
|
|
if (m_userManager.GetUsers().user.empty()) {
|
|
m_userManager.GetUsers() = m_userManager.CreateDefaultUsers();
|
|
}
|
|
return false;
|
|
}
|
|
} |