profile_manager: Create save data if it doesn't exist on use

This commit is contained in:
Zach Hilman 2018-10-14 14:49:32 -04:00
parent 45f2a2fe29
commit bfad41b0c1
4 changed files with 43 additions and 19 deletions

View file

@ -30,22 +30,20 @@ constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, -1);
constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, -2); constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, -2);
constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20);
constexpr const char* ACC_SAVE_AVATORS_BASE_PATH = "/system/save/8000000000000010/su/avators/"; constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/avators/";
const UUID& UUID::Generate() { UUID UUID::Generate() {
std::random_device device; std::random_device device;
std::mt19937 gen(device()); std::mt19937 gen(device());
std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max()); std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max());
uuid[0] = distribution(gen); return UUID{distribution(gen), distribution(gen)};
uuid[1] = distribution(gen);
return *this;
} }
ProfileManager::ProfileManager() { ProfileManager::ProfileManager() {
ParseUserSaveFile(); ParseUserSaveFile();
if (user_count == 0) if (user_count == 0)
CreateNewUser(UUID{}.Generate(), "yuzu"); CreateNewUser(UUID::Generate(), "yuzu");
auto current = std::clamp<int>(Settings::values.current_user, 0, MAX_USERS - 1); auto current = std::clamp<int>(Settings::values.current_user, 0, MAX_USERS - 1);
if (UserExistsIndex(current)) if (UserExistsIndex(current))
@ -309,10 +307,18 @@ void ProfileManager::ParseUserSaveFile() {
ACC_SAVE_AVATORS_BASE_PATH + "profiles.dat", ACC_SAVE_AVATORS_BASE_PATH + "profiles.dat",
"rb"); "rb");
ProfileDataRaw data; if (!save.IsOpen()) {
save.Seek(0, SEEK_SET); LOG_WARNING(Service_ACC, "Failed to load profile data from save data... Generating new "
if (save.ReadBytes(&data, sizeof(ProfileDataRaw)) != sizeof(ProfileDataRaw)) "user 'yuzu' with random UUID.");
return; return;
}
ProfileDataRaw data;
if (save.ReadBytes(&data, sizeof(ProfileDataRaw)) != sizeof(ProfileDataRaw)) {
LOG_WARNING(Service_ACC, "profiles.dat is smaller than expected... Generating new user "
"'yuzu' with random UUID.");
return;
}
for (std::size_t i = 0; i < MAX_USERS; ++i) { for (std::size_t i = 0; i < MAX_USERS; ++i) {
const auto& user = data.users[i]; const auto& user = data.users[i];
@ -335,12 +341,30 @@ void ProfileManager::WriteUserSaveFile() {
raw.users[i].timestamp = profiles[i].creation_time; raw.users[i].timestamp = profiles[i].creation_time;
} }
FileUtil::IOFile save(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + const auto raw_path =
ACC_SAVE_AVATORS_BASE_PATH + "profiles.dat", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + "/system/save/8000000000000010";
"wb"); if (FileUtil::Exists(raw_path) && !FileUtil::IsDirectory(raw_path))
FileUtil::Delete(raw_path);
const auto path = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
ACC_SAVE_AVATORS_BASE_PATH + "profiles.dat";
if (!FileUtil::CreateFullPath(path)) {
LOG_WARNING(Service_ACC, "Failed to create full path of profiles.dat. Create the directory "
"nand/system/save/8000000000000010/su/avators to mitigate this "
"issue.");
return;
}
FileUtil::IOFile save(path, "wb");
if (!save.IsOpen()) {
LOG_WARNING(Service_ACC, "Failed to write save data to file... No changes to user data "
"made in current session will be saved.");
return;
}
save.Resize(sizeof(ProfileDataRaw)); save.Resize(sizeof(ProfileDataRaw));
save.Seek(0, SEEK_SET);
save.WriteBytes(&raw, sizeof(ProfileDataRaw)); save.WriteBytes(&raw, sizeof(ProfileDataRaw));
} }

View file

@ -36,7 +36,7 @@ struct UUID {
} }
// TODO(ogniK): Properly generate uuids based on RFC-4122 // TODO(ogniK): Properly generate uuids based on RFC-4122
const UUID& Generate(); static UUID Generate();
// Set the UUID to {0,0} to be considered an invalid user // Set the UUID to {0,0} to be considered an invalid user
void Invalidate() { void Invalidate() {

View file

@ -163,7 +163,7 @@ void ConfigureSystem::UpdateCurrentUser() {
void ConfigureSystem::ReadSystemSettings() {} void ConfigureSystem::ReadSystemSettings() {}
std::string ConfigureSystem::GetAccountUsername(Service::Account::UUID uuid) { std::string ConfigureSystem::GetAccountUsername(Service::Account::UUID uuid) const {
Service::Account::ProfileBase profile; Service::Account::ProfileBase profile;
if (!profile_manager->GetProfileBase(uuid, profile)) if (!profile_manager->GetProfileBase(uuid, profile))
return ""; return "";

View file

@ -10,11 +10,11 @@
#include <QWidget> #include <QWidget>
#include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/acc/profile_manager.h"
class QVBoxLayout;
class QTreeView;
class QStandardItemModel;
class QGraphicsScene; class QGraphicsScene;
class QStandardItem; class QStandardItem;
class QStandardItemModel;
class QTreeView;
class QVBoxLayout;
namespace Ui { namespace Ui {
class ConfigureSystem; class ConfigureSystem;
@ -45,7 +45,7 @@ public slots:
private: private:
void ReadSystemSettings(); void ReadSystemSettings();
std::string GetAccountUsername(Service::Account::UUID uuid); std::string GetAccountUsername(Service::Account::UUID uuid) const;
QVBoxLayout* layout; QVBoxLayout* layout;
QTreeView* tree_view; QTreeView* tree_view;