mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	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");
 | 
			
		||||
 | 
			
		||||
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)) {}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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>;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user