diff options
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/acc/acc.cpp | 77 | ||||
| -rw-r--r-- | src/core/hle/service/acc/profile_manager.cpp | 60 | ||||
| -rw-r--r-- | 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<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?  static UUID DEFAULT_USER_ID{1ull, 0ull};  class IProfile final : public ServiceFramework<IProfile> {  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<u8, MAX_DATA> 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<UUID> 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<UUID> 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<UUID>(profile_manager->GetLastOpennedUser()); +} +  void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      UUID user_id = rp.PopRaw<UUID>();      IPC::ResponseBuilder rb{ctx, 2, 0, 1};      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());  } @@ -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> 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<u8, 0x20> usernam      prof_inf.username = username;      prof_inf.data = std::array<u8, MAX_DATA>();      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<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 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<u8, 0x20> username;      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 { @@ -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<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();      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:      std::array<ProfileInfo, MAX_USERS> 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<ProfileManager>; | 
