From 5f8d253ce0a940cdb668861c2c96749c7b9ce626 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Wed, 8 Aug 2018 21:09:45 +1000 Subject: [PATCH 01/21] Switched uuids from u128 to new UUID struct --- src/core/hle/service/acc/acc.cpp | 22 ++++++++++--------- src/core/hle/service/acc/acc.h | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index e952b0518..1fb3d96f6 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -3,7 +3,10 @@ // Refer to the license.txt file included. #include +#include "common/common_types.h" #include "common/logging/log.h" +#include "common/swap.h" +#include "core/core_timing.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/acc/acc.h" #include "core/hle/service/acc/acc_aa.h" @@ -13,7 +16,6 @@ #include "core/settings.h" namespace Service::Account { - // TODO: RE this structure struct UserData { INSERT_PADDING_WORDS(1); @@ -33,11 +35,11 @@ struct ProfileBase { static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); // TODO(ogniK): Generate a real user id based on username, md5(username) maybe? -static constexpr u128 DEFAULT_USER_ID{1ull, 0ull}; +static UUID DEFAULT_USER_ID{1ull, 0ull}; class IProfile final : public ServiceFramework { public: - explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) { + explicit IProfile(UUID user_id) : ServiceFramework("IProfile"), user_id(user_id) { static const FunctionInfo functions[] = { {0, &IProfile::Get, "Get"}, {1, &IProfile::GetBase, "GetBase"}, @@ -51,7 +53,7 @@ private: void Get(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); ProfileBase profile_base{}; - profile_base.user_id = user_id; + profile_base.user_id = user_id.uuid; if (Settings::values.username.size() > profile_base.username.size()) { std::copy_n(Settings::values.username.begin(), profile_base.username.size(), profile_base.username.begin()); @@ -70,7 +72,7 @@ private: // TODO(Subv): Retrieve this information from somewhere. ProfileBase profile_base{}; - profile_base.user_id = user_id; + profile_base.user_id = user_id.uuid; if (Settings::values.username.size() > profile_base.username.size()) { std::copy_n(Settings::values.username.begin(), profile_base.username.size(), profile_base.username.begin()); @@ -83,7 +85,7 @@ private: rb.PushRaw(profile_base); } - u128 user_id; ///< The user id this profile refers to. + UUID user_id; ///< The user id this profile refers to. }; class IManagerForApplication final : public ServiceFramework { @@ -136,7 +138,7 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); // TODO(Subv): There is only one user for now. - const std::vector user_ids = {DEFAULT_USER_ID}; + const std::vector user_ids = {DEFAULT_USER_ID}; ctx.WriteBuffer(user_ids); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -145,7 +147,7 @@ void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); // TODO(Subv): There is only one user for now. - const std::vector user_ids = {DEFAULT_USER_ID}; + const std::vector user_ids = {DEFAULT_USER_ID}; ctx.WriteBuffer(user_ids); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -153,11 +155,11 @@ void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - u128 user_id = rp.PopRaw(); + UUID user_id = rp.PopRaw(); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface(user_id); - LOG_DEBUG(Service_ACC, "called user_id=0x{:016X}{:016X}", user_id[1], user_id[0]); + LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); } void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index 88cabaa01..e392b3557 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -8,6 +8,43 @@ namespace Service::Account { +struct UUID { + // UUIDs which are 0 are considered invalid! + u128 uuid{0, 0}; + UUID() = default; + explicit UUID(const u128& id) { + uuid[0] = id[0]; + uuid[1] = id[1]; + }; + explicit UUID(const u64& lo, const u64& hi) { + uuid[0] = lo; + uuid[1] = hi; + }; + operator bool() const { + return uuid[0] != 0x0 && uuid[1] != 0x0; + } + + bool operator==(const UUID& rhs) { + return uuid[0] == rhs.uuid[0] && uuid[1] == rhs.uuid[1]; + } + + bool operator!=(const UUID& rhs) { + return uuid[0] != rhs.uuid[0] || uuid[1] != rhs.uuid[1]; + } + + // TODO(ogniK): Properly generate uuids based on RFC-4122 + const UUID& Generate() { + uuid[0] = (static_cast(std::rand()) << 32) | std::rand(); + uuid[1] = (static_cast(std::rand()) << 32) | std::rand(); + return *this; + } + + std::string Format() { + return fmt::format("0x{:016X}{:016X}", uuid[1], uuid[0]); + } +}; +static_assert(sizeof(UUID) == 16, "UUID is an invalid size!"); + class Module final { public: class Interface : public ServiceFramework { From 6f691e71bfa30de8789327a969cb7c2fdd1669f2 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Wed, 8 Aug 2018 22:26:42 +1000 Subject: [PATCH 02/21] began initial implementation of "ProfileManager" --- src/core/CMakeLists.txt | 2 + src/core/hle/service/acc/acc.cpp | 17 ++-- src/core/hle/service/acc/acc.h | 41 +-------- src/core/hle/service/acc/profile_manager.cpp | 89 ++++++++++++++++++ src/core/hle/service/acc/profile_manager.h | 97 ++++++++++++++++++++ 5 files changed, 202 insertions(+), 44 deletions(-) create mode 100644 src/core/hle/service/acc/profile_manager.cpp create mode 100644 src/core/hle/service/acc/profile_manager.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index cceb1564b..4d39ba409 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -114,6 +114,8 @@ add_library(core STATIC hle/service/acc/acc_u0.h hle/service/acc/acc_u1.cpp hle/service/acc/acc_u1.h + hle/service/acc/profile_manager.cpp + hle/service/acc/profile_manager.h hle/service/am/am.cpp hle/service/am/am.h hle/service/am/applet_ae.cpp diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 1fb3d96f6..8efaf6171 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -28,7 +28,7 @@ struct UserData { static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); struct ProfileBase { - u128 user_id; + UUID user_id; u64 timestamp; std::array username; }; @@ -53,7 +53,7 @@ private: void Get(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); ProfileBase profile_base{}; - profile_base.user_id = user_id.uuid; + profile_base.user_id = user_id; if (Settings::values.username.size() > profile_base.username.size()) { std::copy_n(Settings::values.username.begin(), profile_base.username.size(), profile_base.username.begin()); @@ -72,7 +72,7 @@ private: // TODO(Subv): Retrieve this information from somewhere. ProfileBase profile_base{}; - profile_base.user_id = user_id.uuid; + profile_base.user_id = user_id; if (Settings::values.username.size() > profile_base.username.size()) { std::copy_n(Settings::values.username.begin(), profile_base.username.size(), profile_base.username.begin()); @@ -122,17 +122,20 @@ private: }; void Module::Interface::GetUserCount(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + LOG_INFO(Service_ACC, "called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(1); + rb.Push(static_cast(profile_manager->GetUserCount())); } void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + UUID user_id = rp.PopRaw(); + LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(true); // TODO: Check when this is supposed to return true and when not + rb.Push(profile_manager->UserExists(user_id)); } void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index e392b3557..a9bea77ce 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -5,46 +5,10 @@ #pragma once #include "core/hle/service/service.h" +#include "profile_manager.h" namespace Service::Account { -struct UUID { - // UUIDs which are 0 are considered invalid! - u128 uuid{0, 0}; - UUID() = default; - explicit UUID(const u128& id) { - uuid[0] = id[0]; - uuid[1] = id[1]; - }; - explicit UUID(const u64& lo, const u64& hi) { - uuid[0] = lo; - uuid[1] = hi; - }; - operator bool() const { - return uuid[0] != 0x0 && uuid[1] != 0x0; - } - - bool operator==(const UUID& rhs) { - return uuid[0] == rhs.uuid[0] && uuid[1] == rhs.uuid[1]; - } - - bool operator!=(const UUID& rhs) { - return uuid[0] != rhs.uuid[0] || uuid[1] != rhs.uuid[1]; - } - - // TODO(ogniK): Properly generate uuids based on RFC-4122 - const UUID& Generate() { - uuid[0] = (static_cast(std::rand()) << 32) | std::rand(); - uuid[1] = (static_cast(std::rand()) << 32) | std::rand(); - return *this; - } - - std::string Format() { - return fmt::format("0x{:016X}{:016X}", uuid[1], uuid[0]); - } -}; -static_assert(sizeof(UUID) == 16, "UUID is an invalid size!"); - class Module final { public: class Interface : public ServiceFramework { @@ -60,6 +24,9 @@ public: void InitializeApplicationInfo(Kernel::HLERequestContext& ctx); void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx); + private: + std::unique_ptr profile_manager{}; + protected: std::shared_ptr module; }; diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp new file mode 100644 index 000000000..8819c5703 --- /dev/null +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -0,0 +1,89 @@ +#include "profile_manager.h" + +namespace Service::Account { +// TODO(ogniK): Get actual error codes +constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, -1); +constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); + +size_t ProfileManager::AddToProfiles(const ProfileInfo& user) { + if (user_count >= MAX_USERS) { + return -1; + } + profiles[user_count] = std::move(user); + return user_count++; +} + +bool ProfileManager::RemoveProfileAtIdx(size_t index) { + if (index >= MAX_USERS || index < 0 || index >= user_count) + return false; + profiles[index] = ProfileInfo{}; + if (index < user_count - 1) + for (size_t i = index; i < user_count - 1; i++) + profiles[i] = profiles[i + 1]; // Shift upper profiles down + user_count--; + return true; +} + +ResultCode ProfileManager::AddUser(ProfileInfo user) { + if (AddToProfiles(user) == -1) { + return ERROR_TOO_MANY_USERS; + } + return RESULT_SUCCESS; +} + +ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array username) { + if (user_count == MAX_USERS) + return ERROR_TOO_MANY_USERS; + if (!uuid) + return ERROR_ARGUMENT_IS_NULL; + if (username[0] == 0x0) + return ERROR_ARGUMENT_IS_NULL; + ProfileInfo prof_inf; + prof_inf.user_uuid = uuid; + prof_inf.username = username; + prof_inf.data = std::array(); + prof_inf.creation_time = 0x0; + return AddUser(prof_inf); +} + +size_t ProfileManager::GetUserIndex(UUID uuid) { + for (unsigned i = 0; i < user_count; i++) + if (profiles[i].user_uuid == uuid) + return i; + return -1; +} + +size_t ProfileManager::GetUserIndex(ProfileInfo user) { + return GetUserIndex(user.user_uuid); +} + +bool ProfileManager::GetProfileBase(size_t index, ProfileBase& profile) { + if (index >= MAX_USERS) { + profile.Invalidate(); + return false; + } + auto prof_info = profiles[index]; + profile.user_uuid = prof_info.user_uuid; + profile.username = prof_info.username; + profile.timestamp = prof_info.creation_time; + return true; +} + +bool ProfileManager::GetProfileBase(UUID uuid, ProfileBase& profile) { + auto idx = GetUserIndex(uuid); + return GetProfileBase(idx, profile); +} + +bool ProfileManager::GetProfileBase(ProfileInfo user, ProfileBase& profile) { + return GetProfileBase(user.user_uuid, profile); +} + +size_t ProfileManager::GetUserCount() { + return user_count; +} + +bool ProfileManager::UserExists(UUID uuid) { + return (GetUserIndex(uuid) != -1); +} + +}; // namespace Service::Account diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h new file mode 100644 index 000000000..5aa73a030 --- /dev/null +++ b/src/core/hle/service/acc/profile_manager.h @@ -0,0 +1,97 @@ +#pragma once +#include +#include "common/common_types.h" +#include "common/swap.h" +#include "core/hle/result.h" + +namespace Service::Account { +constexpr size_t MAX_USERS = 8; +constexpr size_t MAX_DATA = 128; + +struct UUID { + // UUIDs which are 0 are considered invalid! + u128 uuid{0, 0}; + UUID() = default; + explicit UUID(const u128& id) { + uuid[0] = id[0]; + uuid[1] = id[1]; + }; + explicit UUID(const u64& lo, const u64& hi) { + uuid[0] = lo; + uuid[1] = hi; + }; + operator bool() const { + return uuid[0] != 0x0 && uuid[1] != 0x0; + } + + bool operator==(const UUID& rhs) { + return uuid[0] == rhs.uuid[0] && uuid[1] == rhs.uuid[1]; + } + + bool operator!=(const UUID& rhs) { + return uuid[0] != rhs.uuid[0] || uuid[1] != rhs.uuid[1]; + } + + // TODO(ogniK): Properly generate uuids based on RFC-4122 + const UUID& Generate() { + uuid[0] = (static_cast(std::rand()) << 32) | std::rand(); + uuid[1] = (static_cast(std::rand()) << 32) | std::rand(); + return *this; + } + void Invalidate() { + uuid[0] = 0; + uuid[1] = 0; + } + std::string Format() { + return fmt::format("0x{:016X}{:016X}", uuid[1], uuid[0]); + } +}; +static_assert(sizeof(UUID) == 16, "UUID is an invalid size!"); + +/// This holds general information about a users profile. This is where we store all the information +/// based on a specific user +struct ProfileInfo { + UUID user_uuid; + std::array username; + u64 creation_time; + std::array data; +}; + +struct ProfileBase { + UUID user_uuid; + u64_le timestamp; + std::array username; + + const void Invalidate() { + user_uuid.Invalidate(); + timestamp = 0; + username.fill(0); + } +}; +static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase is an invalid size"); + +/// The profile manager is used for handling multiple user profiles at once. It keeps track of open +/// users, all the accounts registered on the "system" as well as fetching individual "ProfileInfo" +/// objects +class ProfileManager { +public: + ProfileManager() = default; // TODO(ogniK): Load from system save + ResultCode AddUser(ProfileInfo user); + ResultCode CreateNewUser(UUID uuid, std::array username); + size_t GetUserIndex(UUID uuid); + size_t GetUserIndex(ProfileInfo user); + bool GetProfileBase(size_t index, ProfileBase& profile); + bool GetProfileBase(UUID uuid, ProfileBase& profile); + bool GetProfileBase(ProfileInfo user, ProfileBase& profile); + size_t GetUserCount(); + bool UserExists(UUID uuid); + +private: + std::array profiles{}; + size_t user_count = 0; + size_t AddToProfiles(const ProfileInfo& profile); + bool RemoveProfileAtIdx(size_t index); +}; +using ProfileManagerPtr = std::unique_ptr; + +}; // namespace Service::Account From 03d7faf58390216729eb828b08be7e5f0ef82727 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Wed, 8 Aug 2018 23:41:12 +1000 Subject: [PATCH 03/21] GetProfileBase and GetProfileBaseAndData added --- src/core/hle/service/acc/acc.cpp | 77 +++++++++----------- src/core/hle/service/acc/profile_manager.cpp | 60 +++++++++++++++ src/core/hle/service/acc/profile_manager.h | 13 +++- 3 files changed, 106 insertions(+), 44 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 8efaf6171..92141f61c 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -27,19 +27,13 @@ struct UserData { }; static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); -struct ProfileBase { - UUID user_id; - u64 timestamp; - std::array username; -}; -static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); - // TODO(ogniK): Generate a real user id based on username, md5(username) maybe? static UUID DEFAULT_USER_ID{1ull, 0ull}; class IProfile final : public ServiceFramework { public: - explicit IProfile(UUID user_id) : ServiceFramework("IProfile"), user_id(user_id) { + explicit IProfile(UUID user_id, ProfileManager& profile_manager) + : ServiceFramework("IProfile"), user_id(user_id), profile_manager(profile_manager) { static const FunctionInfo functions[] = { {0, &IProfile::Get, "Get"}, {1, &IProfile::GetBase, "GetBase"}, @@ -51,40 +45,41 @@ public: private: void Get(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); + LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); ProfileBase profile_base{}; - profile_base.user_id = user_id; - if (Settings::values.username.size() > profile_base.username.size()) { + std::array data{}; + /*if (Settings::values.username.size() > profile_base.username.size()) { std::copy_n(Settings::values.username.begin(), profile_base.username.size(), profile_base.username.begin()); } else { std::copy(Settings::values.username.begin(), Settings::values.username.end(), profile_base.username.begin()); + }*/ + if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { + ctx.WriteBuffer(data); + IPC::ResponseBuilder rb{ctx, 16}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_base); + } else { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code } - - IPC::ResponseBuilder rb{ctx, 16}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(profile_base); } void GetBase(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - - // TODO(Subv): Retrieve this information from somewhere. + LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); ProfileBase profile_base{}; - profile_base.user_id = user_id; - if (Settings::values.username.size() > profile_base.username.size()) { - std::copy_n(Settings::values.username.begin(), profile_base.username.size(), - profile_base.username.begin()); + if (profile_manager.GetProfileBase(user_id, profile_base)) { + IPC::ResponseBuilder rb{ctx, 16}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_base); } else { - std::copy(Settings::values.username.begin(), Settings::values.username.end(), - profile_base.username.begin()); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code } - IPC::ResponseBuilder rb{ctx, 16}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(profile_base); } + ProfileManager& profile_manager; UUID user_id; ///< The user id this profile refers to. }; @@ -139,29 +134,32 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { } void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - // TODO(Subv): There is only one user for now. - const std::vector user_ids = {DEFAULT_USER_ID}; - ctx.WriteBuffer(user_ids); + LOG_INFO(Service_ACC, "called"); + ctx.WriteBuffer(profile_manager->GetAllUsers()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - // TODO(Subv): There is only one user for now. - const std::vector user_ids = {DEFAULT_USER_ID}; - ctx.WriteBuffer(user_ids); + LOG_INFO(Service_ACC, "called"); + ctx.WriteBuffer(profile_manager->GetOpenUsers()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } +void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { + LOG_INFO(Service_ACC, "called"); + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_manager->GetLastOpennedUser()); +} + void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; UUID user_id = rp.PopRaw(); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface(user_id); + rb.PushIpcInterface(user_id, *profile_manager); LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); } @@ -178,13 +176,6 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo LOG_DEBUG(Service_ACC, "called"); } -void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_ACC, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(RESULT_SUCCESS); - rb.PushRaw(DEFAULT_USER_ID); -} - Module::Interface::Interface(std::shared_ptr module, const char* name) : ServiceFramework(name), module(std::move(module)) {} diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 8819c5703..925022018 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -43,10 +43,13 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array usernam prof_inf.username = username; prof_inf.data = std::array(); prof_inf.creation_time = 0x0; + prof_inf.is_open = false; return AddUser(prof_inf); } size_t ProfileManager::GetUserIndex(UUID uuid) { + if (!uuid) + return -1; for (unsigned i = 0; i < user_count; i++) if (profiles[i].user_uuid == uuid) return i; @@ -86,4 +89,61 @@ bool ProfileManager::UserExists(UUID uuid) { return (GetUserIndex(uuid) != -1); } +void ProfileManager::OpenUser(UUID uuid) { + auto idx = GetUserIndex(uuid); + if (idx == -1) + return; + profiles[idx].is_open = true; + last_openned_user = uuid; +} + +void ProfileManager::CloseUser(UUID uuid) { + auto idx = GetUserIndex(uuid); + if (idx == -1) + return; + profiles[idx].is_open = false; +} + +std::array ProfileManager::GetAllUsers() { + std::array output; + for (unsigned i = 0; i < user_count; i++) { + output[i] = profiles[i].user_uuid; + } + return output; +} + +std::array ProfileManager::GetOpenUsers() { + std::array output; + unsigned user_idx = 0; + for (unsigned i = 0; i < user_count; i++) { + if (profiles[i].is_open) { + output[i++] = profiles[i].user_uuid; + } + } + return output; +} + +const UUID& ProfileManager::GetLastOpennedUser() { + return last_openned_user; +} + +bool ProfileManager::GetProfileBaseAndData(size_t index, ProfileBase& profile, + std::array& data) { + if (GetProfileBase(index, profile)) { + std::memcpy(data.data(), profiles[index].data.data(), MAX_DATA); + return true; + } + return false; +} +bool ProfileManager::GetProfileBaseAndData(UUID uuid, ProfileBase& profile, + std::array& data) { + auto idx = GetUserIndex(uuid); + return GetProfileBaseAndData(idx, profile, data); +} + +bool ProfileManager::GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, + std::array& data) { + return GetProfileBaseAndData(user.user_uuid, profile, data); +} + }; // namespace Service::Account diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 5aa73a030..cb6239cc1 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -54,7 +54,8 @@ struct ProfileInfo { UUID user_uuid; std::array username; u64 creation_time; - std::array data; + std::array data; // TODO(ognik): Work out what this is + bool is_open; }; struct ProfileBase { @@ -83,14 +84,24 @@ public: bool GetProfileBase(size_t index, ProfileBase& profile); bool GetProfileBase(UUID uuid, ProfileBase& profile); bool GetProfileBase(ProfileInfo user, ProfileBase& profile); + bool GetProfileBaseAndData(size_t index, ProfileBase& profile, std::array& data); + bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, std::array& data); + bool GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, + std::array& data); size_t GetUserCount(); bool UserExists(UUID uuid); + void OpenUser(UUID uuid); + void CloseUser(UUID uuid); + std::array GetOpenUsers(); + std::array GetAllUsers(); + const UUID& GetLastOpennedUser(); private: std::array profiles{}; size_t user_count = 0; size_t AddToProfiles(const ProfileInfo& profile); bool RemoveProfileAtIdx(size_t index); + UUID last_openned_user{0, 0}; }; using ProfileManagerPtr = std::unique_ptr; From 75169c75708d9f54297537b387182bee10ada9ab Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 9 Aug 2018 01:09:12 +1000 Subject: [PATCH 04/21] Inital pass of account backend implementation This commit verified working on puyo --- src/core/hle/service/acc/acc.cpp | 11 +++-------- src/core/hle/service/acc/profile_manager.cpp | 18 ++++++++++++++++-- src/core/hle/service/acc/profile_manager.h | 5 +++-- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 92141f61c..7c62d99f6 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -48,13 +48,6 @@ private: LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); ProfileBase profile_base{}; std::array data{}; - /*if (Settings::values.username.size() > profile_base.username.size()) { - std::copy_n(Settings::values.username.begin(), profile_base.username.size(), - profile_base.username.begin()); - } else { - std::copy(Settings::values.username.begin(), Settings::values.username.end(), - profile_base.username.begin()); - }*/ if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { ctx.WriteBuffer(data); IPC::ResponseBuilder rb{ctx, 16}; @@ -177,7 +170,9 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo } Module::Interface::Interface(std::shared_ptr module, const char* name) - : ServiceFramework(name), module(std::move(module)) {} + : ServiceFramework(name), module(std::move(module)) { + profile_manager = std::make_unique(); +} void InstallInterfaces(SM::ServiceManager& service_manager) { auto module = std::make_shared(); diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 925022018..1633d5d48 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -1,3 +1,4 @@ +#include "core/settings.h" #include "profile_manager.h" namespace Service::Account { @@ -5,6 +6,10 @@ namespace Service::Account { constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, -1); constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); +ProfileManager::ProfileManager() { + CreateNewUser(UUID{1, 0}, Settings::values.username); +} + size_t ProfileManager::AddToProfiles(const ProfileInfo& user) { if (user_count >= MAX_USERS) { return -1; @@ -39,14 +44,23 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array usernam if (username[0] == 0x0) return ERROR_ARGUMENT_IS_NULL; ProfileInfo prof_inf; - prof_inf.user_uuid = uuid; - prof_inf.username = username; + prof_inf.user_uuid = std::move(uuid); + prof_inf.username = std::move(username); prof_inf.data = std::array(); prof_inf.creation_time = 0x0; prof_inf.is_open = false; return AddUser(prof_inf); } +ResultCode ProfileManager::CreateNewUser(UUID uuid, std::string username) { + std::array username_output; + if (username.size() > username_output.size()) + std::copy_n(username.begin(), username_output.size(), username_output.begin()); + else + std::copy(username.begin(), username.end(), username_output.begin()); + return CreateNewUser(uuid, std::move(username_output)); +} + size_t ProfileManager::GetUserIndex(UUID uuid) { if (!uuid) return -1; diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index cb6239cc1..130041994 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -21,7 +21,7 @@ struct UUID { uuid[1] = hi; }; operator bool() const { - return uuid[0] != 0x0 && uuid[1] != 0x0; + return uuid[0] != 0x0 || uuid[1] != 0x0; } bool operator==(const UUID& rhs) { @@ -76,9 +76,10 @@ static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase is an invalid size"); /// objects class ProfileManager { public: - ProfileManager() = default; // TODO(ogniK): Load from system save + ProfileManager(); // TODO(ogniK): Load from system save ResultCode AddUser(ProfileInfo user); ResultCode CreateNewUser(UUID uuid, std::array username); + ResultCode CreateNewUser(UUID uuid, std::string username); size_t GetUserIndex(UUID uuid); size_t GetUserIndex(ProfileInfo user); bool GetProfileBase(size_t index, ProfileBase& profile); From e9978fd4f55b34804154193e1a619d28896d5a59 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 9 Aug 2018 01:37:55 +1000 Subject: [PATCH 05/21] Open first user added --- src/core/hle/service/acc/profile_manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 1633d5d48..03021cb64 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -7,7 +7,9 @@ constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, -1); constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); ProfileManager::ProfileManager() { - CreateNewUser(UUID{1, 0}, Settings::values.username); + auto user_uuid = UUID{1, 0}; + CreateNewUser(user_uuid, Settings::values.username); + OpenUser(user_uuid); } size_t ProfileManager::AddToProfiles(const ProfileInfo& user) { From 4e1471ef219dc376b8aa637ae05ad43851b8e407 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Thu, 9 Aug 2018 13:30:58 +1000 Subject: [PATCH 06/21] Don't add user if the uuid already exists --- src/core/hle/service/acc/profile_manager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 03021cb64..ff2b71cce 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -4,6 +4,7 @@ namespace Service::Account { // TODO(ogniK): Get actual error codes constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, -1); +constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, -2); constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); ProfileManager::ProfileManager() { @@ -45,6 +46,9 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array usernam return ERROR_ARGUMENT_IS_NULL; if (username[0] == 0x0) return ERROR_ARGUMENT_IS_NULL; + for (unsigned i = 0; i < user_count; i++) + if (uuid == profiles[i].user_uuid) + return ERROR_USER_ALREADY_EXISTS; ProfileInfo prof_inf; prof_inf.user_uuid = std::move(uuid); prof_inf.username = std::move(username); From 2a3b335b156552515e28f62df2617d06c241a29a Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 10:33:11 +1000 Subject: [PATCH 07/21] Added IsUserRegistrationRequestPermitted --- src/core/hle/service/acc/acc.cpp | 7 +++++++ src/core/hle/service/acc/acc.h | 1 + src/core/hle/service/acc/acc_su.cpp | 2 +- src/core/hle/service/acc/acc_u0.cpp | 2 +- src/core/hle/service/acc/acc_u1.cpp | 2 +- src/core/hle/service/acc/profile_manager.cpp | 6 ++++++ src/core/hle/service/acc/profile_manager.h | 2 ++ 7 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 7c62d99f6..0a6cac5b7 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -156,6 +156,13 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); } +void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(profile_manager->CanSystemRegisterUser()); +} + void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index a9bea77ce..89d92c1c7 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -23,6 +23,7 @@ public: void GetProfile(Kernel::HLERequestContext& ctx); void InitializeApplicationInfo(Kernel::HLERequestContext& ctx); void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx); + void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx); private: std::unique_ptr profile_manager{}; diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp index 8b2a71f37..5973768be 100644 --- a/src/core/hle/service/acc/acc_su.cpp +++ b/src/core/hle/service/acc/acc_su.cpp @@ -15,7 +15,7 @@ ACC_SU::ACC_SU(std::shared_ptr module) : Module::Interface(std::move(mod {4, &ACC_SU::GetLastOpenedUser, "GetLastOpenedUser"}, {5, &ACC_SU::GetProfile, "GetProfile"}, {6, nullptr, "GetProfileDigest"}, - {50, nullptr, "IsUserRegistrationRequestPermitted"}, + {50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, {51, nullptr, "TrySelectUserWithoutInteraction"}, {60, nullptr, "ListOpenContextStoredUsers"}, {100, nullptr, "GetUserRegistrationNotifier"}, diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp index d84c8b2e1..b6fe45dd8 100644 --- a/src/core/hle/service/acc/acc_u0.cpp +++ b/src/core/hle/service/acc/acc_u0.cpp @@ -15,7 +15,7 @@ ACC_U0::ACC_U0(std::shared_ptr module) : Module::Interface(std::move(mod {4, &ACC_U0::GetLastOpenedUser, "GetLastOpenedUser"}, {5, &ACC_U0::GetProfile, "GetProfile"}, {6, nullptr, "GetProfileDigest"}, - {50, nullptr, "IsUserRegistrationRequestPermitted"}, + {50, &ACC_U0::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, {51, nullptr, "TrySelectUserWithoutInteraction"}, {60, nullptr, "ListOpenContextStoredUsers"}, {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"}, diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index 0ceaf06b5..99e3f1ef6 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp @@ -15,7 +15,7 @@ ACC_U1::ACC_U1(std::shared_ptr module) : Module::Interface(std::move(mod {4, &ACC_U1::GetLastOpenedUser, "GetLastOpenedUser"}, {5, &ACC_U1::GetProfile, "GetProfile"}, {6, nullptr, "GetProfileDigest"}, - {50, nullptr, "IsUserRegistrationRequestPermitted"}, + {50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, {51, nullptr, "TrySelectUserWithoutInteraction"}, {60, nullptr, "ListOpenContextStoredUsers"}, {100, nullptr, "GetUserRegistrationNotifier"}, diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index ff2b71cce..8e7d7194c 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -166,4 +166,10 @@ bool ProfileManager::GetProfileBaseAndData(ProfileInfo user, ProfileBase& profil return GetProfileBaseAndData(user.user_uuid, profile, data); } +bool ProfileManager::CanSystemRegisterUser() { + return false; // TODO(ogniK): Games shouldn't have + // access to user registration, when we + // emulate qlaunch. Update this to dynamically change. +} + }; // namespace Service::Account diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 130041994..64371ea16 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -97,6 +97,8 @@ public: std::array GetAllUsers(); const UUID& GetLastOpennedUser(); + bool CanSystemRegisterUser(); + private: std::array profiles{}; size_t user_count = 0; From 6aa8ee6943f6ae8b0ed1770b91355b36c2618a4c Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 13:17:06 +1000 Subject: [PATCH 08/21] Refactored profile manager sharing --- src/core/hle/service/acc/acc.cpp | 17 +++++++++-------- src/core/hle/service/acc/acc.h | 7 +++---- src/core/hle/service/acc/acc_aa.cpp | 3 ++- src/core/hle/service/acc/acc_aa.h | 3 ++- src/core/hle/service/acc/acc_su.cpp | 3 ++- src/core/hle/service/acc/acc_su.h | 3 ++- src/core/hle/service/acc/acc_u0.cpp | 3 ++- src/core/hle/service/acc/acc_u0.h | 3 ++- src/core/hle/service/acc/acc_u1.cpp | 3 ++- src/core/hle/service/acc/acc_u1.h | 3 ++- 10 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index e74379a24..22e44368a 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -197,17 +197,18 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo LOG_DEBUG(Service_ACC, "called"); } -Module::Interface::Interface(std::shared_ptr module, const char* name) - : ServiceFramework(name), module(std::move(module)) { - profile_manager = std::make_unique(); -} +Module::Interface::Interface(std::shared_ptr module, + std::shared_ptr profile_manager, const char* name) + : ServiceFramework(name), module(std::move(module)), + profile_manager(std::make_shared(*profile_manager)) {} void InstallInterfaces(SM::ServiceManager& service_manager) { auto module = std::make_shared(); - std::make_shared(module)->InstallAsService(service_manager); - std::make_shared(module)->InstallAsService(service_manager); - std::make_shared(module)->InstallAsService(service_manager); - std::make_shared(module)->InstallAsService(service_manager); + auto profile_manager = std::make_shared(); + std::make_shared(module, profile_manager)->InstallAsService(service_manager); + std::make_shared(module, profile_manager)->InstallAsService(service_manager); + std::make_shared(module, profile_manager)->InstallAsService(service_manager); + std::make_shared(module, profile_manager)->InstallAsService(service_manager); } } // namespace Service::Account diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index 89d92c1c7..a94e6f588 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -13,7 +13,8 @@ class Module final { public: class Interface : public ServiceFramework { public: - explicit Interface(std::shared_ptr module, const char* name); + explicit Interface(std::shared_ptr module, + std::shared_ptr profile_manager, const char* name); void GetUserCount(Kernel::HLERequestContext& ctx); void GetUserExistence(Kernel::HLERequestContext& ctx); @@ -25,11 +26,9 @@ public: void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx); void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx); - private: - std::unique_ptr profile_manager{}; - protected: std::shared_ptr module; + std::shared_ptr profile_manager; }; }; diff --git a/src/core/hle/service/acc/acc_aa.cpp b/src/core/hle/service/acc/acc_aa.cpp index 280b3e464..9bd595a37 100644 --- a/src/core/hle/service/acc/acc_aa.cpp +++ b/src/core/hle/service/acc/acc_aa.cpp @@ -6,7 +6,8 @@ namespace Service::Account { -ACC_AA::ACC_AA(std::shared_ptr module) : Module::Interface(std::move(module), "acc:aa") { +ACC_AA::ACC_AA(std::shared_ptr module, std::shared_ptr profile_manager) + : Module::Interface(std::move(module), std::move(profile_manager), "acc:aa") { static const FunctionInfo functions[] = { {0, nullptr, "EnsureCacheAsync"}, {1, nullptr, "LoadCache"}, diff --git a/src/core/hle/service/acc/acc_aa.h b/src/core/hle/service/acc/acc_aa.h index 796f7ef85..2e08c781a 100644 --- a/src/core/hle/service/acc/acc_aa.h +++ b/src/core/hle/service/acc/acc_aa.h @@ -10,7 +10,8 @@ namespace Service::Account { class ACC_AA final : public Module::Interface { public: - explicit ACC_AA(std::shared_ptr module); + explicit ACC_AA(std::shared_ptr module, + std::shared_ptr profile_manager); }; } // namespace Service::Account diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp index 5973768be..0218ee859 100644 --- a/src/core/hle/service/acc/acc_su.cpp +++ b/src/core/hle/service/acc/acc_su.cpp @@ -6,7 +6,8 @@ namespace Service::Account { -ACC_SU::ACC_SU(std::shared_ptr module) : Module::Interface(std::move(module), "acc:su") { +ACC_SU::ACC_SU(std::shared_ptr module, std::shared_ptr profile_manager) + : Module::Interface(std::move(module), std::move(profile_manager), "acc:su") { static const FunctionInfo functions[] = { {0, &ACC_SU::GetUserCount, "GetUserCount"}, {1, &ACC_SU::GetUserExistence, "GetUserExistence"}, diff --git a/src/core/hle/service/acc/acc_su.h b/src/core/hle/service/acc/acc_su.h index 3894a6991..79a47d88d 100644 --- a/src/core/hle/service/acc/acc_su.h +++ b/src/core/hle/service/acc/acc_su.h @@ -11,7 +11,8 @@ namespace Account { class ACC_SU final : public Module::Interface { public: - explicit ACC_SU(std::shared_ptr module); + explicit ACC_SU(std::shared_ptr module, + std::shared_ptr profile_manager); }; } // namespace Account diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp index b6fe45dd8..84a4d05b8 100644 --- a/src/core/hle/service/acc/acc_u0.cpp +++ b/src/core/hle/service/acc/acc_u0.cpp @@ -6,7 +6,8 @@ namespace Service::Account { -ACC_U0::ACC_U0(std::shared_ptr module) : Module::Interface(std::move(module), "acc:u0") { +ACC_U0::ACC_U0(std::shared_ptr module, std::shared_ptr profile_manager) + : Module::Interface(std::move(module), std::move(profile_manager), "acc:u0") { static const FunctionInfo functions[] = { {0, &ACC_U0::GetUserCount, "GetUserCount"}, {1, &ACC_U0::GetUserExistence, "GetUserExistence"}, diff --git a/src/core/hle/service/acc/acc_u0.h b/src/core/hle/service/acc/acc_u0.h index 6ded596b3..e8a114f99 100644 --- a/src/core/hle/service/acc/acc_u0.h +++ b/src/core/hle/service/acc/acc_u0.h @@ -10,7 +10,8 @@ namespace Service::Account { class ACC_U0 final : public Module::Interface { public: - explicit ACC_U0(std::shared_ptr module); + explicit ACC_U0(std::shared_ptr module, + std::shared_ptr profile_manager); }; } // namespace Service::Account diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index 99e3f1ef6..495693949 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp @@ -6,7 +6,8 @@ namespace Service::Account { -ACC_U1::ACC_U1(std::shared_ptr module) : Module::Interface(std::move(module), "acc:u1") { +ACC_U1::ACC_U1(std::shared_ptr module, std::shared_ptr profile_manager) + : Module::Interface(std::move(module), std::move(profile_manager), "acc:u1") { static const FunctionInfo functions[] = { {0, &ACC_U1::GetUserCount, "GetUserCount"}, {1, &ACC_U1::GetUserExistence, "GetUserExistence"}, diff --git a/src/core/hle/service/acc/acc_u1.h b/src/core/hle/service/acc/acc_u1.h index 5e3e7659b..a77520e6f 100644 --- a/src/core/hle/service/acc/acc_u1.h +++ b/src/core/hle/service/acc/acc_u1.h @@ -10,7 +10,8 @@ namespace Service::Account { class ACC_U1 final : public Module::Interface { public: - explicit ACC_U1(std::shared_ptr module); + explicit ACC_U1(std::shared_ptr module, + std::shared_ptr profile_manager); }; } // namespace Service::Account From 4fa4d80c682a6f73928c5fffa0a29957c1f50781 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 13:35:04 +1000 Subject: [PATCH 09/21] Rebase with dynarmic master --- externals/dynarmic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/dynarmic b/externals/dynarmic index 4f96c6302..0118ee04f 160000 --- a/externals/dynarmic +++ b/externals/dynarmic @@ -1 +1 @@ -Subproject commit 4f96c63025af34c1490c59f6729497b9866ffa35 +Subproject commit 0118ee04f90faaff951989f3c2494bc6ffb70cf1 From 82fa0bcea7c0231742716f7c79255eb107d4a933 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 16:47:33 +1000 Subject: [PATCH 10/21] First round of account changes --- src/core/hle/service/acc/acc.cpp | 2 +- src/core/hle/service/acc/profile_manager.cpp | 52 +++++++++++--------- src/core/hle/service/acc/profile_manager.h | 50 ++++++++++--------- 3 files changed, 55 insertions(+), 49 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 22e44368a..9a7c3b9f4 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -165,7 +165,7 @@ void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { LOG_INFO(Service_ACC, "called"); IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); - rb.PushRaw(profile_manager->GetLastOpennedUser()); + rb.PushRaw(profile_manager->GetLastOpenedUser()); } void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 8e7d7194c..fda796966 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -1,3 +1,7 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include "core/settings.h" #include "profile_manager.h" @@ -15,14 +19,14 @@ ProfileManager::ProfileManager() { size_t ProfileManager::AddToProfiles(const ProfileInfo& user) { if (user_count >= MAX_USERS) { - return -1; + return std::numeric_limits::max(); } profiles[user_count] = std::move(user); return user_count++; } bool ProfileManager::RemoveProfileAtIdx(size_t index) { - if (index >= MAX_USERS || index < 0 || index >= user_count) + if (index >= MAX_USERS || index >= user_count) return false; profiles[index] = ProfileInfo{}; if (index < user_count - 1) @@ -33,13 +37,13 @@ bool ProfileManager::RemoveProfileAtIdx(size_t index) { } ResultCode ProfileManager::AddUser(ProfileInfo user) { - if (AddToProfiles(user) == -1) { + if (AddToProfiles(user) == std::numeric_limits::max()) { return ERROR_TOO_MANY_USERS; } return RESULT_SUCCESS; } -ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array username) { +ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array& username) { if (user_count == MAX_USERS) return ERROR_TOO_MANY_USERS; if (!uuid) @@ -64,67 +68,67 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::string username) { std::copy_n(username.begin(), username_output.size(), username_output.begin()); else std::copy(username.begin(), username.end(), username_output.begin()); - return CreateNewUser(uuid, std::move(username_output)); + return CreateNewUser(uuid, username_output); } -size_t ProfileManager::GetUserIndex(UUID uuid) { +size_t ProfileManager::GetUserIndex(const UUID& uuid) const { if (!uuid) - return -1; + return std::numeric_limits::max(); for (unsigned i = 0; i < user_count; i++) if (profiles[i].user_uuid == uuid) return i; - return -1; + return std::numeric_limits::max(); } -size_t ProfileManager::GetUserIndex(ProfileInfo user) { +size_t ProfileManager::GetUserIndex(ProfileInfo user) const { return GetUserIndex(user.user_uuid); } -bool ProfileManager::GetProfileBase(size_t index, ProfileBase& profile) { +bool ProfileManager::GetProfileBase(size_t index, ProfileBase& profile) const { if (index >= MAX_USERS) { profile.Invalidate(); return false; } - auto prof_info = profiles[index]; + const auto& prof_info = profiles[index]; profile.user_uuid = prof_info.user_uuid; profile.username = prof_info.username; profile.timestamp = prof_info.creation_time; return true; } -bool ProfileManager::GetProfileBase(UUID uuid, ProfileBase& profile) { +bool ProfileManager::GetProfileBase(UUID uuid, ProfileBase& profile) const { auto idx = GetUserIndex(uuid); return GetProfileBase(idx, profile); } -bool ProfileManager::GetProfileBase(ProfileInfo user, ProfileBase& profile) { +bool ProfileManager::GetProfileBase(ProfileInfo user, ProfileBase& profile) const { return GetProfileBase(user.user_uuid, profile); } -size_t ProfileManager::GetUserCount() { +size_t ProfileManager::GetUserCount() const { return user_count; } -bool ProfileManager::UserExists(UUID uuid) { - return (GetUserIndex(uuid) != -1); +bool ProfileManager::UserExists(UUID uuid) const { + return (GetUserIndex(uuid) != std::numeric_limits::max()); } void ProfileManager::OpenUser(UUID uuid) { auto idx = GetUserIndex(uuid); - if (idx == -1) + if (idx == std::numeric_limits::max()) return; profiles[idx].is_open = true; - last_openned_user = uuid; + last_opened_user = uuid; } void ProfileManager::CloseUser(UUID uuid) { auto idx = GetUserIndex(uuid); - if (idx == -1) + if (idx == std::numeric_limits::max()) return; profiles[idx].is_open = false; } -std::array ProfileManager::GetAllUsers() { +std::array ProfileManager::GetAllUsers() const { std::array output; for (unsigned i = 0; i < user_count; i++) { output[i] = profiles[i].user_uuid; @@ -132,7 +136,7 @@ std::array ProfileManager::GetAllUsers() { return output; } -std::array ProfileManager::GetOpenUsers() { +std::array ProfileManager::GetOpenUsers() const { std::array output; unsigned user_idx = 0; for (unsigned i = 0; i < user_count; i++) { @@ -143,8 +147,8 @@ std::array ProfileManager::GetOpenUsers() { return output; } -const UUID& ProfileManager::GetLastOpennedUser() { - return last_openned_user; +UUID ProfileManager::GetLastOpenedUser() const { + return last_opened_user; } bool ProfileManager::GetProfileBaseAndData(size_t index, ProfileBase& profile, @@ -166,7 +170,7 @@ bool ProfileManager::GetProfileBaseAndData(ProfileInfo user, ProfileBase& profil return GetProfileBaseAndData(user.user_uuid, profile, data); } -bool ProfileManager::CanSystemRegisterUser() { +bool ProfileManager::CanSystemRegisterUser() const { return false; // TODO(ogniK): Games shouldn't have // access to user registration, when we // emulate qlaunch. Update this to dynamically change. diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 64371ea16..ad4c20db0 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -1,4 +1,9 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #pragma once + #include #include "common/common_types.h" #include "common/swap.h" @@ -12,24 +17,21 @@ struct UUID { // UUIDs which are 0 are considered invalid! u128 uuid{0, 0}; UUID() = default; - explicit UUID(const u128& id) { - uuid[0] = id[0]; - uuid[1] = id[1]; - }; - explicit UUID(const u64& lo, const u64& hi) { + explicit UUID(const u128& id) : uuid{id} {} + explicit UUID(const u64 lo, const u64 hi) { uuid[0] = lo; uuid[1] = hi; }; - operator bool() const { + explicit operator bool() const { return uuid[0] != 0x0 || uuid[1] != 0x0; } - bool operator==(const UUID& rhs) { - return uuid[0] == rhs.uuid[0] && uuid[1] == rhs.uuid[1]; + bool operator==(const UUID& rhs) const { + return std::tie(uuid[0], uuid[1]) == std::tie(rhs.uuid[0], rhs.uuid[1]); } - bool operator!=(const UUID& rhs) { - return uuid[0] != rhs.uuid[0] || uuid[1] != rhs.uuid[1]; + bool operator!=(const UUID& rhs) const { + return !operator==(rhs); } // TODO(ogniK): Properly generate uuids based on RFC-4122 @@ -42,7 +44,7 @@ struct UUID { uuid[0] = 0; uuid[1] = 0; } - std::string Format() { + std::string Format() const { return fmt::format("0x{:016X}{:016X}", uuid[1], uuid[0]); } }; @@ -78,33 +80,33 @@ class ProfileManager { public: ProfileManager(); // TODO(ogniK): Load from system save ResultCode AddUser(ProfileInfo user); - ResultCode CreateNewUser(UUID uuid, std::array username); + ResultCode CreateNewUser(UUID uuid, std::array& username); ResultCode CreateNewUser(UUID uuid, std::string username); - size_t GetUserIndex(UUID uuid); - size_t GetUserIndex(ProfileInfo user); - bool GetProfileBase(size_t index, ProfileBase& profile); - bool GetProfileBase(UUID uuid, ProfileBase& profile); - bool GetProfileBase(ProfileInfo user, ProfileBase& profile); + size_t GetUserIndex(const UUID& uuid) const; + size_t GetUserIndex(ProfileInfo user) const; + bool GetProfileBase(size_t index, ProfileBase& profile) const; + bool GetProfileBase(UUID uuid, ProfileBase& profile) const; + bool GetProfileBase(ProfileInfo user, ProfileBase& profile) const; bool GetProfileBaseAndData(size_t index, ProfileBase& profile, std::array& data); bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, std::array& data); bool GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, std::array& data); - size_t GetUserCount(); - bool UserExists(UUID uuid); + size_t GetUserCount() const; + bool UserExists(UUID uuid) const; void OpenUser(UUID uuid); void CloseUser(UUID uuid); - std::array GetOpenUsers(); - std::array GetAllUsers(); - const UUID& GetLastOpennedUser(); + std::array GetOpenUsers() const; + std::array GetAllUsers() const; + UUID GetLastOpenedUser() const; - bool CanSystemRegisterUser(); + bool CanSystemRegisterUser() const; private: std::array profiles{}; size_t user_count = 0; size_t AddToProfiles(const ProfileInfo& profile); bool RemoveProfileAtIdx(size_t index); - UUID last_openned_user{0, 0}; + UUID last_opened_user{0, 0}; }; using ProfileManagerPtr = std::unique_ptr; From dfea525cbe3a337d3a1fa30136029599ae47ee71 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 18:26:13 +1000 Subject: [PATCH 11/21] Second round of account changes --- src/core/hle/service/acc/acc.h | 2 +- src/core/hle/service/acc/profile_manager.cpp | 27 +++++++++++--------- src/core/hle/service/acc/profile_manager.h | 10 ++++---- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index a94e6f588..d7c6d2415 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -4,8 +4,8 @@ #pragma once +#include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/service.h" -#include "profile_manager.h" namespace Service::Account { diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index fda796966..14d65ff1b 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -2,8 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/service/acc/profile_manager.h" #include "core/settings.h" -#include "profile_manager.h" namespace Service::Account { // TODO(ogniK): Get actual error codes @@ -28,10 +28,9 @@ size_t ProfileManager::AddToProfiles(const ProfileInfo& user) { bool ProfileManager::RemoveProfileAtIdx(size_t index) { if (index >= MAX_USERS || index >= user_count) return false; - profiles[index] = ProfileInfo{}; if (index < user_count - 1) - for (size_t i = index; i < user_count - 1; i++) - profiles[i] = profiles[i + 1]; // Shift upper profiles down + std::rotate(profiles.begin() + index, profiles.begin() + index + 1, profiles.end()); + profiles.back() = {}; user_count--; return true; } @@ -50,9 +49,10 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array& userna return ERROR_ARGUMENT_IS_NULL; if (username[0] == 0x0) return ERROR_ARGUMENT_IS_NULL; - for (unsigned i = 0; i < user_count; i++) - if (uuid == profiles[i].user_uuid) - return ERROR_USER_ALREADY_EXISTS; + if (std::any_of(profiles.begin(), profiles.end(), + [&uuid](const ProfileInfo& profile) { return uuid == profile.user_uuid; })) { + return ERROR_USER_ALREADY_EXISTS; + } ProfileInfo prof_inf; prof_inf.user_uuid = std::move(uuid); prof_inf.username = std::move(username); @@ -62,7 +62,7 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array& userna return AddUser(prof_inf); } -ResultCode ProfileManager::CreateNewUser(UUID uuid, std::string username) { +ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) { std::array username_output; if (username.size() > username_output.size()) std::copy_n(username.begin(), username_output.size(), username_output.begin()); @@ -74,10 +74,13 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::string username) { size_t ProfileManager::GetUserIndex(const UUID& uuid) const { if (!uuid) return std::numeric_limits::max(); - for (unsigned i = 0; i < user_count; i++) - if (profiles[i].user_uuid == uuid) - return i; - return std::numeric_limits::max(); + + auto iter = std::find_if(profiles.begin(), profiles.end(), + [&uuid](const ProfileInfo& p) { return p.user_uuid == uuid; }); + if (iter == profiles.end()) { + return std::numeric_limits::max(); + } + return static_cast(std::distance(profiles.begin(), iter)); } size_t ProfileManager::GetUserIndex(ProfileInfo user) const { diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index ad4c20db0..121206954 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -12,10 +12,11 @@ namespace Service::Account { constexpr size_t MAX_USERS = 8; constexpr size_t MAX_DATA = 128; +static const u128 INVALID_UUID = {0, 0}; struct UUID { // UUIDs which are 0 are considered invalid! - u128 uuid{0, 0}; + u128 uuid = INVALID_UUID; UUID() = default; explicit UUID(const u128& id) : uuid{id} {} explicit UUID(const u64 lo, const u64 hi) { @@ -23,7 +24,7 @@ struct UUID { uuid[1] = hi; }; explicit operator bool() const { - return uuid[0] != 0x0 || uuid[1] != 0x0; + return uuid[0] != INVALID_UUID[0] && uuid[1] != INVALID_UUID[1]; } bool operator==(const UUID& rhs) const { @@ -41,8 +42,7 @@ struct UUID { return *this; } void Invalidate() { - uuid[0] = 0; - uuid[1] = 0; + uuid = INVALID_UUID; } std::string Format() const { return fmt::format("0x{:016X}{:016X}", uuid[1], uuid[0]); @@ -81,7 +81,7 @@ public: ProfileManager(); // TODO(ogniK): Load from system save ResultCode AddUser(ProfileInfo user); ResultCode CreateNewUser(UUID uuid, std::array& username); - ResultCode CreateNewUser(UUID uuid, std::string username); + ResultCode CreateNewUser(UUID uuid, const std::string& username); size_t GetUserIndex(const UUID& uuid) const; size_t GetUserIndex(ProfileInfo user) const; bool GetProfileBase(size_t index, ProfileBase& profile) const; From acff9227626ce0903efbcdf91d1a12b695889d59 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 18:46:42 +1000 Subject: [PATCH 12/21] If statement style change --- src/core/hle/service/acc/profile_manager.cpp | 30 +++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 14d65ff1b..8f3dab6a0 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -26,10 +26,12 @@ size_t ProfileManager::AddToProfiles(const ProfileInfo& user) { } bool ProfileManager::RemoveProfileAtIdx(size_t index) { - if (index >= MAX_USERS || index >= user_count) + if (index >= MAX_USERS || index >= user_count) { return false; - if (index < user_count - 1) + } + if (index < user_count - 1) { std::rotate(profiles.begin() + index, profiles.begin() + index + 1, profiles.end()); + } profiles.back() = {}; user_count--; return true; @@ -43,12 +45,15 @@ ResultCode ProfileManager::AddUser(ProfileInfo user) { } ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array& username) { - if (user_count == MAX_USERS) + if (user_count == MAX_USERS) { return ERROR_TOO_MANY_USERS; - if (!uuid) + } + if (!uuid) { return ERROR_ARGUMENT_IS_NULL; - if (username[0] == 0x0) + } + if (username[0] == 0x0) { return ERROR_ARGUMENT_IS_NULL; + } if (std::any_of(profiles.begin(), profiles.end(), [&uuid](const ProfileInfo& profile) { return uuid == profile.user_uuid; })) { return ERROR_USER_ALREADY_EXISTS; @@ -64,17 +69,18 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array& userna ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) { std::array username_output; - if (username.size() > username_output.size()) + if (username.size() > username_output.size()) { std::copy_n(username.begin(), username_output.size(), username_output.begin()); - else + } else { std::copy(username.begin(), username.end(), username_output.begin()); + } return CreateNewUser(uuid, username_output); } size_t ProfileManager::GetUserIndex(const UUID& uuid) const { - if (!uuid) + if (!uuid) { return std::numeric_limits::max(); - + } auto iter = std::find_if(profiles.begin(), profiles.end(), [&uuid](const ProfileInfo& p) { return p.user_uuid == uuid; }); if (iter == profiles.end()) { @@ -118,16 +124,18 @@ bool ProfileManager::UserExists(UUID uuid) const { void ProfileManager::OpenUser(UUID uuid) { auto idx = GetUserIndex(uuid); - if (idx == std::numeric_limits::max()) + if (idx == std::numeric_limits::max()) { return; + } profiles[idx].is_open = true; last_opened_user = uuid; } void ProfileManager::CloseUser(UUID uuid) { auto idx = GetUserIndex(uuid); - if (idx == std::numeric_limits::max()) + if (idx == std::numeric_limits::max()) { return; + } profiles[idx].is_open = false; } From c3013c7c9c4498ea0fc0d50dfe674fdff4c0e1c3 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 20:06:06 +1000 Subject: [PATCH 13/21] Added missing ListAllUsers count --- src/core/hle/service/acc/acc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 9a7c3b9f4..9a377e86d 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -150,8 +150,9 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { LOG_INFO(Service_ACC, "called"); ctx.WriteBuffer(profile_manager->GetAllUsers()); - IPC::ResponseBuilder rb{ctx, 2}; + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); + rb.Push(static_cast(profile_manager->GetUserCount())); } void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { From 662218e997de83fdcc7250f2348a750b1e5b3a51 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 20:15:59 +1000 Subject: [PATCH 14/21] Removed all for loops from the profile manager --- src/core/hle/service/acc/profile_manager.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index 8f3dab6a0..ef793b311 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -141,20 +141,15 @@ void ProfileManager::CloseUser(UUID uuid) { std::array ProfileManager::GetAllUsers() const { std::array output; - for (unsigned i = 0; i < user_count; i++) { - output[i] = profiles[i].user_uuid; - } + std::transform(profiles.begin(), profiles.end(), output.begin(), + [](const ProfileInfo& p) { return p.user_uuid; }); return output; } std::array ProfileManager::GetOpenUsers() const { std::array output; - unsigned user_idx = 0; - for (unsigned i = 0; i < user_count; i++) { - if (profiles[i].is_open) { - output[i++] = profiles[i].user_uuid; - } - } + std::copy_if(profiles.begin(), profiles.end(), output.begin(), + [](const ProfileInfo& p) { return p.is_open; }); return output; } From b8e70faa2df59086f04ad1d128c742ea23037dc3 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 20:45:06 +1000 Subject: [PATCH 15/21] Added GetOpenUserCount --- src/core/hle/service/acc/acc.cpp | 3 ++- src/core/hle/service/acc/profile_manager.cpp | 13 +++++++++++-- src/core/hle/service/acc/profile_manager.h | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 9a377e86d..c9ab8311e 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -158,8 +158,9 @@ void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { LOG_INFO(Service_ACC, "called"); ctx.WriteBuffer(profile_manager->GetOpenUsers()); - IPC::ResponseBuilder rb{ctx, 2}; + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); + rb.Push(static_cast(profile_manager->GetOpenUserCount())); } void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index ef793b311..e8f6884d1 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -118,6 +118,11 @@ size_t ProfileManager::GetUserCount() const { return user_count; } +size_t ProfileManager::GetOpenUserCount() const { + return std::count_if(profiles.begin(), profiles.end(), + [](const ProfileInfo& p) { return p.is_open; }); +} + bool ProfileManager::UserExists(UUID uuid) const { return (GetUserIndex(uuid) != std::numeric_limits::max()); } @@ -148,8 +153,12 @@ std::array ProfileManager::GetAllUsers() const { std::array ProfileManager::GetOpenUsers() const { std::array output; - std::copy_if(profiles.begin(), profiles.end(), output.begin(), - [](const ProfileInfo& p) { return p.is_open; }); + std::transform(profiles.begin(), profiles.end(), output.begin(), [](const ProfileInfo& p) { + if (p.is_open) + return p.user_uuid; + return UUID{}; + }); + std::stable_partition(output.begin(), output.end(), [](const UUID& uuid) { return uuid; }); return output; } diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 121206954..8ec1273e4 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -92,6 +92,7 @@ public: bool GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, std::array& data); size_t GetUserCount() const; + size_t GetOpenUserCount() const; bool UserExists(UUID uuid) const; void OpenUser(UUID uuid); void CloseUser(UUID uuid); From 42431d2aa6b67ea2e522fe2f4dbfc3205323cbac Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 11 Aug 2018 21:29:10 +1000 Subject: [PATCH 16/21] fixed invalid uuid bool operator --- src/core/hle/service/acc/profile_manager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 8ec1273e4..bbb917cb5 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -24,7 +24,7 @@ struct UUID { uuid[1] = hi; }; explicit operator bool() const { - return uuid[0] != INVALID_UUID[0] && uuid[1] != INVALID_UUID[1]; + return uuid[0] != INVALID_UUID[0] || uuid[1] != INVALID_UUID[1]; } bool operator==(const UUID& rhs) const { From d0b2950434b8da14f9903e918e568254c9b0b27d Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sun, 12 Aug 2018 00:41:17 +1000 Subject: [PATCH 17/21] Removed const from ProfileBase Invalidate --- src/core/hle/service/acc/profile_manager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index bbb917cb5..1815d520d 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -65,7 +65,7 @@ struct ProfileBase { u64_le timestamp; std::array username; - const void Invalidate() { + void Invalidate() { user_uuid.Invalidate(); timestamp = 0; username.fill(0); From 0b6f8ba51e61792ea23a55394a963d0961a9906f Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sun, 12 Aug 2018 01:34:22 +1000 Subject: [PATCH 18/21] Code cleanup for profile manager --- src/core/hle/service/acc/acc.cpp | 7 ++- src/core/hle/service/acc/profile_manager.cpp | 60 ++++++++++---------- src/core/hle/service/acc/profile_manager.h | 20 ++++--- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index c9ab8311e..b94dda9ea 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -54,6 +54,8 @@ private: rb.Push(RESULT_SUCCESS); rb.PushRaw(profile_base); } else { + LOG_ERROR(Service_ACC, "Failed to get profile base and data for user={}", + user_id.Format()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code } @@ -67,6 +69,7 @@ private: rb.Push(RESULT_SUCCESS); rb.PushRaw(profile_base); } else { + LOG_ERROR(Service_ACC, "Failed to get profile base for user={}", user_id.Format()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code } @@ -93,7 +96,7 @@ private: rb.Push(jpeg_size); } - ProfileManager& profile_manager; + const ProfileManager& profile_manager; UUID user_id; ///< The user id this profile refers to. }; @@ -202,7 +205,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo Module::Interface::Interface(std::shared_ptr module, std::shared_ptr profile_manager, const char* name) : ServiceFramework(name), module(std::move(module)), - profile_manager(std::make_shared(*profile_manager)) {} + profile_manager(std::move(profile_manager)) {} void InstallInterfaces(SM::ServiceManager& service_manager) { auto module = std::make_shared(); diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index e8f6884d1..ee13ae3cd 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include "core/hle/service/acc/profile_manager.h" #include "core/settings.h" @@ -12,20 +13,21 @@ constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, -2); constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); ProfileManager::ProfileManager() { + // TODO(ogniK): Create the default user we have for now until loading/saving users is added auto user_uuid = UUID{1, 0}; CreateNewUser(user_uuid, Settings::values.username); OpenUser(user_uuid); } -size_t ProfileManager::AddToProfiles(const ProfileInfo& user) { +boost::optional ProfileManager::AddToProfiles(const ProfileInfo& user) { if (user_count >= MAX_USERS) { - return std::numeric_limits::max(); + return boost::none; } profiles[user_count] = std::move(user); return user_count++; } -bool ProfileManager::RemoveProfileAtIdx(size_t index) { +bool ProfileManager::RemoveProfileAtIndex(size_t index) { if (index >= MAX_USERS || index >= user_count) { return false; } @@ -38,7 +40,7 @@ bool ProfileManager::RemoveProfileAtIdx(size_t index) { } ResultCode ProfileManager::AddUser(ProfileInfo user) { - if (AddToProfiles(user) == std::numeric_limits::max()) { + if (AddToProfiles(user) == boost::none) { return ERROR_TOO_MANY_USERS; } return RESULT_SUCCESS; @@ -58,13 +60,13 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array& userna [&uuid](const ProfileInfo& profile) { return uuid == profile.user_uuid; })) { return ERROR_USER_ALREADY_EXISTS; } - ProfileInfo prof_inf; - prof_inf.user_uuid = std::move(uuid); - prof_inf.username = std::move(username); - prof_inf.data = std::array(); - prof_inf.creation_time = 0x0; - prof_inf.is_open = false; - return AddUser(prof_inf); + ProfileInfo profile; + profile.user_uuid = std::move(uuid); + profile.username = std::move(username); + profile.data = {}; + profile.creation_time = 0x0; + profile.is_open = false; + return AddUser(profile); } ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) { @@ -77,28 +79,27 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) return CreateNewUser(uuid, username_output); } -size_t ProfileManager::GetUserIndex(const UUID& uuid) const { +boost::optional ProfileManager::GetUserIndex(const UUID& uuid) const { if (!uuid) { - return std::numeric_limits::max(); + return boost::none; } auto iter = std::find_if(profiles.begin(), profiles.end(), [&uuid](const ProfileInfo& p) { return p.user_uuid == uuid; }); if (iter == profiles.end()) { - return std::numeric_limits::max(); + return boost::none; } return static_cast(std::distance(profiles.begin(), iter)); } -size_t ProfileManager::GetUserIndex(ProfileInfo user) const { +boost::optional ProfileManager::GetUserIndex(ProfileInfo user) const { return GetUserIndex(user.user_uuid); } -bool ProfileManager::GetProfileBase(size_t index, ProfileBase& profile) const { - if (index >= MAX_USERS) { - profile.Invalidate(); +bool ProfileManager::GetProfileBase(boost::optional index, ProfileBase& profile) const { + if (index == boost::none || index >= MAX_USERS) { return false; } - const auto& prof_info = profiles[index]; + const auto& prof_info = profiles[index.get()]; profile.user_uuid = prof_info.user_uuid; profile.username = prof_info.username; profile.timestamp = prof_info.creation_time; @@ -124,24 +125,24 @@ size_t ProfileManager::GetOpenUserCount() const { } bool ProfileManager::UserExists(UUID uuid) const { - return (GetUserIndex(uuid) != std::numeric_limits::max()); + return (GetUserIndex(uuid) != boost::none); } void ProfileManager::OpenUser(UUID uuid) { auto idx = GetUserIndex(uuid); - if (idx == std::numeric_limits::max()) { + if (idx == boost::none) { return; } - profiles[idx].is_open = true; + profiles[idx.get()].is_open = true; last_opened_user = uuid; } void ProfileManager::CloseUser(UUID uuid) { auto idx = GetUserIndex(uuid); - if (idx == std::numeric_limits::max()) { + if (idx == boost::none) { return; } - profiles[idx].is_open = false; + profiles[idx.get()].is_open = false; } std::array ProfileManager::GetAllUsers() const { @@ -166,22 +167,23 @@ UUID ProfileManager::GetLastOpenedUser() const { return last_opened_user; } -bool ProfileManager::GetProfileBaseAndData(size_t index, ProfileBase& profile, - std::array& data) { +bool ProfileManager::GetProfileBaseAndData(boost::optional index, ProfileBase& profile, + std::array& data) const { if (GetProfileBase(index, profile)) { - std::memcpy(data.data(), profiles[index].data.data(), MAX_DATA); + std::memcpy(data.data(), profiles[index.get()].data.data(), MAX_DATA); return true; } return false; } + bool ProfileManager::GetProfileBaseAndData(UUID uuid, ProfileBase& profile, - std::array& data) { + std::array& data) const { auto idx = GetUserIndex(uuid); return GetProfileBaseAndData(idx, profile, data); } bool ProfileManager::GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, - std::array& data) { + std::array& data) const { return GetProfileBaseAndData(user.user_uuid, profile, data); } diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 1815d520d..d86a7a226 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -5,6 +5,7 @@ #pragma once #include +#include "boost/optional.hpp" #include "common/common_types.h" #include "common/swap.h" #include "core/hle/result.h" @@ -82,15 +83,17 @@ public: ResultCode AddUser(ProfileInfo user); ResultCode CreateNewUser(UUID uuid, std::array& username); ResultCode CreateNewUser(UUID uuid, const std::string& username); - size_t GetUserIndex(const UUID& uuid) const; - size_t GetUserIndex(ProfileInfo user) const; - bool GetProfileBase(size_t index, ProfileBase& profile) const; + boost::optional GetUserIndex(const UUID& uuid) const; + boost::optional GetUserIndex(ProfileInfo user) const; + bool GetProfileBase(boost::optional index, ProfileBase& profile) const; bool GetProfileBase(UUID uuid, ProfileBase& profile) const; bool GetProfileBase(ProfileInfo user, ProfileBase& profile) const; - bool GetProfileBaseAndData(size_t index, ProfileBase& profile, std::array& data); - bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, std::array& data); + bool GetProfileBaseAndData(boost::optional index, ProfileBase& profile, + std::array& data) const; + bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, + std::array& data) const; bool GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, - std::array& data); + std::array& data) const; size_t GetUserCount() const; size_t GetOpenUserCount() const; bool UserExists(UUID uuid) const; @@ -105,10 +108,9 @@ public: private: std::array profiles{}; size_t user_count = 0; - size_t AddToProfiles(const ProfileInfo& profile); - bool RemoveProfileAtIdx(size_t index); + boost::optional AddToProfiles(const ProfileInfo& profile); + bool RemoveProfileAtIndex(size_t index); UUID last_opened_user{0, 0}; }; -using ProfileManagerPtr = std::unique_ptr; }; // namespace Service::Account From 2592e41301b39db27730b148e7dbfd41d83864c2 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sun, 12 Aug 2018 01:51:31 +1000 Subject: [PATCH 19/21] Added better explanations in the profile manager --- src/core/hle/service/acc/profile_manager.cpp | 32 +++++++++++++++++++- src/core/hle/service/acc/profile_manager.h | 3 ++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index ee13ae3cd..62c2121fa 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -19,6 +19,8 @@ ProfileManager::ProfileManager() { OpenUser(user_uuid); } +/// After a users creation it needs to be "registered" to the system. AddToProfiles handles the +/// internal management of the users profiles boost::optional ProfileManager::AddToProfiles(const ProfileInfo& user) { if (user_count >= MAX_USERS) { return boost::none; @@ -27,6 +29,7 @@ boost::optional ProfileManager::AddToProfiles(const ProfileInfo& user) { return user_count++; } +/// Deletes a specific profile based on it's profile index bool ProfileManager::RemoveProfileAtIndex(size_t index) { if (index >= MAX_USERS || index >= user_count) { return false; @@ -39,6 +42,7 @@ bool ProfileManager::RemoveProfileAtIndex(size_t index) { return true; } +/// Helper function to register a user to the system ResultCode ProfileManager::AddUser(ProfileInfo user) { if (AddToProfiles(user) == boost::none) { return ERROR_TOO_MANY_USERS; @@ -46,6 +50,8 @@ ResultCode ProfileManager::AddUser(ProfileInfo user) { return RESULT_SUCCESS; } +/// Create a new user on the system. If the uuid of the user already exists, the user is not +/// created. ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array& username) { if (user_count == MAX_USERS) { return ERROR_TOO_MANY_USERS; @@ -62,13 +68,16 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array& userna } ProfileInfo profile; profile.user_uuid = std::move(uuid); - profile.username = std::move(username); + profile.username = username; profile.data = {}; profile.creation_time = 0x0; profile.is_open = false; return AddUser(profile); } +/// Creates a new user on the system. This function allows a much simpler method of registration +/// specifically by allowing an std::string for the username. This is required specifically since +/// we're loading a string straight from the config ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) { std::array username_output; if (username.size() > username_output.size()) { @@ -79,6 +88,7 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, const std::string& username) return CreateNewUser(uuid, username_output); } +/// Returns a users profile index based on their user id. boost::optional ProfileManager::GetUserIndex(const UUID& uuid) const { if (!uuid) { return boost::none; @@ -91,10 +101,12 @@ boost::optional ProfileManager::GetUserIndex(const UUID& uuid) const { return static_cast(std::distance(profiles.begin(), iter)); } +/// Returns a users profile index based on their profile boost::optional ProfileManager::GetUserIndex(ProfileInfo user) const { return GetUserIndex(user.user_uuid); } +/// Returns the data structure used by the switch when GetProfileBase is called on acc:* bool ProfileManager::GetProfileBase(boost::optional index, ProfileBase& profile) const { if (index == boost::none || index >= MAX_USERS) { return false; @@ -106,28 +118,37 @@ bool ProfileManager::GetProfileBase(boost::optional index, ProfileBase& return true; } +/// Returns the data structure used by the switch when GetProfileBase is called on acc:* bool ProfileManager::GetProfileBase(UUID uuid, ProfileBase& profile) const { auto idx = GetUserIndex(uuid); return GetProfileBase(idx, profile); } +/// Returns the data structure used by the switch when GetProfileBase is called on acc:* bool ProfileManager::GetProfileBase(ProfileInfo user, ProfileBase& profile) const { return GetProfileBase(user.user_uuid, profile); } +/// Returns the current user count on the system. We keep a variable which tracks the count so we +/// don't have to loop the internal profile array every call. size_t ProfileManager::GetUserCount() const { return user_count; } +/// Lists the current "opened" users on the system. Users are typically not open until they sign +/// into something or pick a profile. As of right now users should all be open until qlaunch is +/// booting size_t ProfileManager::GetOpenUserCount() const { return std::count_if(profiles.begin(), profiles.end(), [](const ProfileInfo& p) { return p.is_open; }); } +/// Checks if a user id exists in our profile manager bool ProfileManager::UserExists(UUID uuid) const { return (GetUserIndex(uuid) != boost::none); } +/// Opens a specific user void ProfileManager::OpenUser(UUID uuid) { auto idx = GetUserIndex(uuid); if (idx == boost::none) { @@ -137,6 +158,7 @@ void ProfileManager::OpenUser(UUID uuid) { last_opened_user = uuid; } +/// Closes a specific user void ProfileManager::CloseUser(UUID uuid) { auto idx = GetUserIndex(uuid); if (idx == boost::none) { @@ -145,6 +167,7 @@ void ProfileManager::CloseUser(UUID uuid) { profiles[idx.get()].is_open = false; } +/// Gets all valid user ids on the system std::array ProfileManager::GetAllUsers() const { std::array output; std::transform(profiles.begin(), profiles.end(), output.begin(), @@ -152,6 +175,8 @@ std::array ProfileManager::GetAllUsers() const { return output; } +/// Get all the open users on the system and zero out the rest of the data. This is specifically +/// needed for GetOpenUsers and we need to ensure the rest of the output buffer is zero'd out std::array ProfileManager::GetOpenUsers() const { std::array output; std::transform(profiles.begin(), profiles.end(), output.begin(), [](const ProfileInfo& p) { @@ -163,10 +188,12 @@ std::array ProfileManager::GetOpenUsers() const { return output; } +/// Returns the last user which was opened UUID ProfileManager::GetLastOpenedUser() const { return last_opened_user; } +/// Return the users profile base and the unknown arbitary data. bool ProfileManager::GetProfileBaseAndData(boost::optional index, ProfileBase& profile, std::array& data) const { if (GetProfileBase(index, profile)) { @@ -176,17 +203,20 @@ bool ProfileManager::GetProfileBaseAndData(boost::optional index, Profil return false; } +/// Return the users profile base and the unknown arbitary data. bool ProfileManager::GetProfileBaseAndData(UUID uuid, ProfileBase& profile, std::array& data) const { auto idx = GetUserIndex(uuid); return GetProfileBaseAndData(idx, profile, data); } +/// Return the users profile base and the unknown arbitary data. bool ProfileManager::GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, std::array& data) const { return GetProfileBaseAndData(user.user_uuid, profile, data); } +/// Returns if the system is allowing user registrations or not bool ProfileManager::CanSystemRegisterUser() const { return false; // TODO(ogniK): Games shouldn't have // access to user registration, when we diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index d86a7a226..908519095 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -42,6 +42,8 @@ struct UUID { uuid[1] = (static_cast(std::rand()) << 32) | std::rand(); return *this; } + + // Set the UUID to {0,0} to be considered an invalid user void Invalidate() { uuid = INVALID_UUID; } @@ -66,6 +68,7 @@ struct ProfileBase { u64_le timestamp; std::array username; + // Zero out all the fields to make the profile slot considered "Empty" void Invalidate() { user_uuid.Invalidate(); timestamp = 0; From 448290bee43b49d7502269b185938d6e8c1aca03 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sun, 12 Aug 2018 02:11:04 +1000 Subject: [PATCH 20/21] Removed un-needed count from ListOpenUsers and ListAllUsers --- src/core/hle/service/acc/acc.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index b94dda9ea..979f2f892 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -153,17 +153,15 @@ void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) { void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { LOG_INFO(Service_ACC, "called"); ctx.WriteBuffer(profile_manager->GetAllUsers()); - IPC::ResponseBuilder rb{ctx, 3}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - rb.Push(static_cast(profile_manager->GetUserCount())); } void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { LOG_INFO(Service_ACC, "called"); ctx.WriteBuffer(profile_manager->GetOpenUsers()); - IPC::ResponseBuilder rb{ctx, 3}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - rb.Push(static_cast(profile_manager->GetOpenUserCount())); } void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) { From 10f494eefead7b2da17d8095abdfaad9ff9290fb Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sun, 12 Aug 2018 02:31:43 +1000 Subject: [PATCH 21/21] Better UUID randomness --- src/core/hle/service/acc/profile_manager.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 908519095..314bccbf9 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "boost/optional.hpp" #include "common/common_types.h" #include "common/swap.h" @@ -38,8 +39,12 @@ struct UUID { // TODO(ogniK): Properly generate uuids based on RFC-4122 const UUID& Generate() { - uuid[0] = (static_cast(std::rand()) << 32) | std::rand(); - uuid[1] = (static_cast(std::rand()) << 32) | std::rand(); + std::random_device device; + std::mt19937 gen(device()); + std::uniform_int_distribution distribution(1, + std::numeric_limits::max()); + uuid[0] = distribution(gen); + uuid[1] = distribution(gen); return *this; }