GetProfileBase and GetProfileBaseAndData added
This commit is contained in:
		| @@ -27,19 +27,13 @@ struct UserData { | |||||||
| }; | }; | ||||||
| static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); | static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); | ||||||
|  |  | ||||||
| struct ProfileBase { |  | ||||||
|     UUID user_id; |  | ||||||
|     u64 timestamp; |  | ||||||
|     std::array<u8, 0x20> username; |  | ||||||
| }; |  | ||||||
| static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); |  | ||||||
|  |  | ||||||
| // TODO(ogniK): Generate a real user id based on username, md5(username) maybe? | // TODO(ogniK): Generate a real user id based on username, md5(username) maybe? | ||||||
| static UUID DEFAULT_USER_ID{1ull, 0ull}; | static UUID DEFAULT_USER_ID{1ull, 0ull}; | ||||||
|  |  | ||||||
| class IProfile final : public ServiceFramework<IProfile> { | class IProfile final : public ServiceFramework<IProfile> { | ||||||
| public: | 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[] = { |         static const FunctionInfo functions[] = { | ||||||
|             {0, &IProfile::Get, "Get"}, |             {0, &IProfile::Get, "Get"}, | ||||||
|             {1, &IProfile::GetBase, "GetBase"}, |             {1, &IProfile::GetBase, "GetBase"}, | ||||||
| @@ -51,40 +45,41 @@ public: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     void Get(Kernel::HLERequestContext& ctx) { |     void Get(Kernel::HLERequestContext& ctx) { | ||||||
|         LOG_WARNING(Service_ACC, "(STUBBED) called"); |         LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); | ||||||
|         ProfileBase profile_base{}; |         ProfileBase profile_base{}; | ||||||
|         profile_base.user_id = user_id; |         std::array<u8, MAX_DATA> data{}; | ||||||
|         if (Settings::values.username.size() > profile_base.username.size()) { |         /*if (Settings::values.username.size() > profile_base.username.size()) { | ||||||
|             std::copy_n(Settings::values.username.begin(), profile_base.username.size(), |             std::copy_n(Settings::values.username.begin(), profile_base.username.size(), | ||||||
|                         profile_base.username.begin()); |                         profile_base.username.begin()); | ||||||
|         } else { |         } else { | ||||||
|             std::copy(Settings::values.username.begin(), Settings::values.username.end(), |             std::copy(Settings::values.username.begin(), Settings::values.username.end(), | ||||||
|                       profile_base.username.begin()); |                       profile_base.username.begin()); | ||||||
|         } |         }*/ | ||||||
|  |         if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) { | ||||||
|  |             ctx.WriteBuffer(data); | ||||||
|             IPC::ResponseBuilder rb{ctx, 16}; |             IPC::ResponseBuilder rb{ctx, 16}; | ||||||
|             rb.Push(RESULT_SUCCESS); |             rb.Push(RESULT_SUCCESS); | ||||||
|             rb.PushRaw(profile_base); |             rb.PushRaw(profile_base); | ||||||
|  |         } else { | ||||||
|  |             IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |             rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void GetBase(Kernel::HLERequestContext& ctx) { |     void GetBase(Kernel::HLERequestContext& ctx) { | ||||||
|         LOG_WARNING(Service_ACC, "(STUBBED) called"); |         LOG_INFO(Service_ACC, "called user_id={}", user_id.Format()); | ||||||
|  |  | ||||||
|         // TODO(Subv): Retrieve this information from somewhere. |  | ||||||
|         ProfileBase profile_base{}; |         ProfileBase profile_base{}; | ||||||
|         profile_base.user_id = user_id; |         if (profile_manager.GetProfileBase(user_id, profile_base)) { | ||||||
|         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()); |  | ||||||
|         } |  | ||||||
|             IPC::ResponseBuilder rb{ctx, 16}; |             IPC::ResponseBuilder rb{ctx, 16}; | ||||||
|             rb.Push(RESULT_SUCCESS); |             rb.Push(RESULT_SUCCESS); | ||||||
|             rb.PushRaw(profile_base); |             rb.PushRaw(profile_base); | ||||||
|  |         } else { | ||||||
|  |             IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|  |             rb.Push(ResultCode(-1)); // TODO(ogniK): Get actual error code | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     ProfileManager& profile_manager; | ||||||
|     UUID user_id; ///< The user id this profile refers to. |     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) { | void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { | ||||||
|     LOG_WARNING(Service_ACC, "(STUBBED) called"); |     LOG_INFO(Service_ACC, "called"); | ||||||
|     // TODO(Subv): There is only one user for now. |     ctx.WriteBuffer(profile_manager->GetAllUsers()); | ||||||
|     const std::vector<UUID> user_ids = {DEFAULT_USER_ID}; |  | ||||||
|     ctx.WriteBuffer(user_ids); |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { | void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { | ||||||
|     LOG_WARNING(Service_ACC, "(STUBBED) called"); |     LOG_INFO(Service_ACC, "called"); | ||||||
|     // TODO(Subv): There is only one user for now. |     ctx.WriteBuffer(profile_manager->GetOpenUsers()); | ||||||
|     const std::vector<UUID> user_ids = {DEFAULT_USER_ID}; |  | ||||||
|     ctx.WriteBuffer(user_ids); |  | ||||||
|     IPC::ResponseBuilder rb{ctx, 2}; |     IPC::ResponseBuilder rb{ctx, 2}; | ||||||
|     rb.Push(RESULT_SUCCESS); |     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<UUID>(profile_manager->GetLastOpennedUser()); | ||||||
|  | } | ||||||
|  |  | ||||||
| void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { | void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) { | ||||||
|     IPC::RequestParser rp{ctx}; |     IPC::RequestParser rp{ctx}; | ||||||
|     UUID user_id = rp.PopRaw<UUID>(); |     UUID user_id = rp.PopRaw<UUID>(); | ||||||
|     IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |     IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||||||
|     rb.Push(RESULT_SUCCESS); |     rb.Push(RESULT_SUCCESS); | ||||||
|     rb.PushIpcInterface<IProfile>(user_id); |     rb.PushIpcInterface<IProfile>(user_id, *profile_manager); | ||||||
|     LOG_DEBUG(Service_ACC, "called user_id={}", user_id.Format()); |     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"); |     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> module, const char* name) | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | ||||||
|     : ServiceFramework(name), module(std::move(module)) {} |     : ServiceFramework(name), module(std::move(module)) {} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,10 +43,13 @@ ResultCode ProfileManager::CreateNewUser(UUID uuid, std::array<u8, 0x20> usernam | |||||||
|     prof_inf.username = username; |     prof_inf.username = username; | ||||||
|     prof_inf.data = std::array<u8, MAX_DATA>(); |     prof_inf.data = std::array<u8, MAX_DATA>(); | ||||||
|     prof_inf.creation_time = 0x0; |     prof_inf.creation_time = 0x0; | ||||||
|  |     prof_inf.is_open = false; | ||||||
|     return AddUser(prof_inf); |     return AddUser(prof_inf); | ||||||
| } | } | ||||||
|  |  | ||||||
| size_t ProfileManager::GetUserIndex(UUID uuid) { | size_t ProfileManager::GetUserIndex(UUID uuid) { | ||||||
|  |     if (!uuid) | ||||||
|  |         return -1; | ||||||
|     for (unsigned i = 0; i < user_count; i++) |     for (unsigned i = 0; i < user_count; i++) | ||||||
|         if (profiles[i].user_uuid == uuid) |         if (profiles[i].user_uuid == uuid) | ||||||
|             return i; |             return i; | ||||||
| @@ -86,4 +89,61 @@ bool ProfileManager::UserExists(UUID uuid) { | |||||||
|     return (GetUserIndex(uuid) != -1); |     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<UUID, MAX_USERS> ProfileManager::GetAllUsers() { | ||||||
|  |     std::array<UUID, MAX_USERS> output; | ||||||
|  |     for (unsigned i = 0; i < user_count; i++) { | ||||||
|  |         output[i] = profiles[i].user_uuid; | ||||||
|  |     } | ||||||
|  |     return output; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::array<UUID, MAX_USERS> ProfileManager::GetOpenUsers() { | ||||||
|  |     std::array<UUID, MAX_USERS> 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<u8, MAX_DATA>& 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<u8, MAX_DATA>& data) { | ||||||
|  |     auto idx = GetUserIndex(uuid); | ||||||
|  |     return GetProfileBaseAndData(idx, profile, data); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ProfileManager::GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, | ||||||
|  |                                            std::array<u8, MAX_DATA>& data) { | ||||||
|  |     return GetProfileBaseAndData(user.user_uuid, profile, data); | ||||||
|  | } | ||||||
|  |  | ||||||
| }; // namespace Service::Account | }; // namespace Service::Account | ||||||
|   | |||||||
| @@ -54,7 +54,8 @@ struct ProfileInfo { | |||||||
|     UUID user_uuid; |     UUID user_uuid; | ||||||
|     std::array<u8, 0x20> username; |     std::array<u8, 0x20> username; | ||||||
|     u64 creation_time; |     u64 creation_time; | ||||||
|     std::array<u8, MAX_DATA> data; |     std::array<u8, MAX_DATA> data; // TODO(ognik): Work out what this is | ||||||
|  |     bool is_open; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct ProfileBase { | struct ProfileBase { | ||||||
| @@ -83,14 +84,24 @@ public: | |||||||
|     bool GetProfileBase(size_t index, ProfileBase& profile); |     bool GetProfileBase(size_t index, ProfileBase& profile); | ||||||
|     bool GetProfileBase(UUID uuid, ProfileBase& profile); |     bool GetProfileBase(UUID uuid, ProfileBase& profile); | ||||||
|     bool GetProfileBase(ProfileInfo user, ProfileBase& profile); |     bool GetProfileBase(ProfileInfo user, ProfileBase& profile); | ||||||
|  |     bool GetProfileBaseAndData(size_t index, ProfileBase& profile, std::array<u8, MAX_DATA>& data); | ||||||
|  |     bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, std::array<u8, MAX_DATA>& data); | ||||||
|  |     bool GetProfileBaseAndData(ProfileInfo user, ProfileBase& profile, | ||||||
|  |                                std::array<u8, MAX_DATA>& data); | ||||||
|     size_t GetUserCount(); |     size_t GetUserCount(); | ||||||
|     bool UserExists(UUID uuid); |     bool UserExists(UUID uuid); | ||||||
|  |     void OpenUser(UUID uuid); | ||||||
|  |     void CloseUser(UUID uuid); | ||||||
|  |     std::array<UUID, MAX_USERS> GetOpenUsers(); | ||||||
|  |     std::array<UUID, MAX_USERS> GetAllUsers(); | ||||||
|  |     const UUID& GetLastOpennedUser(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     std::array<ProfileInfo, MAX_USERS> profiles{}; |     std::array<ProfileInfo, MAX_USERS> profiles{}; | ||||||
|     size_t user_count = 0; |     size_t user_count = 0; | ||||||
|     size_t AddToProfiles(const ProfileInfo& profile); |     size_t AddToProfiles(const ProfileInfo& profile); | ||||||
|     bool RemoveProfileAtIdx(size_t index); |     bool RemoveProfileAtIdx(size_t index); | ||||||
|  |     UUID last_openned_user{0, 0}; | ||||||
| }; | }; | ||||||
| using ProfileManagerPtr = std::unique_ptr<ProfileManager>; | using ProfileManagerPtr = std::unique_ptr<ProfileManager>; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user