profile_manager.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include "boost/optional.hpp"
  7. #include "common/common_types.h"
  8. #include "common/swap.h"
  9. #include "core/hle/result.h"
  10. namespace Service::Account {
  11. constexpr std::size_t MAX_USERS = 8;
  12. constexpr std::size_t MAX_DATA = 128;
  13. constexpr u128 INVALID_UUID{{0, 0}};
  14. struct UUID {
  15. // UUIDs which are 0 are considered invalid!
  16. u128 uuid = INVALID_UUID;
  17. UUID() = default;
  18. explicit UUID(const u128& id) : uuid{id} {}
  19. explicit UUID(const u64 lo, const u64 hi) : uuid{{lo, hi}} {}
  20. explicit operator bool() const {
  21. return uuid != INVALID_UUID;
  22. }
  23. bool operator==(const UUID& rhs) const {
  24. return uuid == rhs.uuid;
  25. }
  26. bool operator!=(const UUID& rhs) const {
  27. return !operator==(rhs);
  28. }
  29. // TODO(ogniK): Properly generate uuids based on RFC-4122
  30. const UUID& Generate();
  31. // Set the UUID to {0,0} to be considered an invalid user
  32. void Invalidate() {
  33. uuid = INVALID_UUID;
  34. }
  35. std::string Format() const {
  36. return fmt::format("0x{:016X}{:016X}", uuid[1], uuid[0]);
  37. }
  38. };
  39. static_assert(sizeof(UUID) == 16, "UUID is an invalid size!");
  40. using ProfileUsername = std::array<u8, 0x20>;
  41. using ProfileData = std::array<u8, MAX_DATA>;
  42. using UserIDArray = std::array<UUID, MAX_USERS>;
  43. /// This holds general information about a users profile. This is where we store all the information
  44. /// based on a specific user
  45. struct ProfileInfo {
  46. UUID user_uuid;
  47. ProfileUsername username;
  48. u64 creation_time;
  49. ProfileData data; // TODO(ognik): Work out what this is
  50. bool is_open;
  51. };
  52. struct ProfileBase {
  53. UUID user_uuid;
  54. u64_le timestamp;
  55. ProfileUsername username;
  56. // Zero out all the fields to make the profile slot considered "Empty"
  57. void Invalidate() {
  58. user_uuid.Invalidate();
  59. timestamp = 0;
  60. username.fill(0);
  61. }
  62. };
  63. static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase is an invalid size");
  64. /// The profile manager is used for handling multiple user profiles at once. It keeps track of open
  65. /// users, all the accounts registered on the "system" as well as fetching individual "ProfileInfo"
  66. /// objects
  67. class ProfileManager {
  68. public:
  69. ProfileManager();
  70. ~ProfileManager();
  71. ResultCode AddUser(const ProfileInfo& user);
  72. ResultCode CreateNewUser(UUID uuid, const ProfileUsername& username);
  73. ResultCode CreateNewUser(UUID uuid, const std::string& username);
  74. boost::optional<std::size_t> GetUserIndex(const UUID& uuid) const;
  75. boost::optional<std::size_t> GetUserIndex(const ProfileInfo& user) const;
  76. bool GetProfileBase(boost::optional<std::size_t> index, ProfileBase& profile) const;
  77. bool GetProfileBase(UUID uuid, ProfileBase& profile) const;
  78. bool GetProfileBase(const ProfileInfo& user, ProfileBase& profile) const;
  79. bool GetProfileBaseAndData(boost::optional<std::size_t> index, ProfileBase& profile,
  80. ProfileData& data) const;
  81. bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, ProfileData& data) const;
  82. bool GetProfileBaseAndData(const ProfileInfo& user, ProfileBase& profile,
  83. ProfileData& data) const;
  84. std::size_t GetUserCount() const;
  85. std::size_t GetOpenUserCount() const;
  86. bool UserExists(UUID uuid) const;
  87. void OpenUser(UUID uuid);
  88. void CloseUser(UUID uuid);
  89. UserIDArray GetOpenUsers() const;
  90. UserIDArray GetAllUsers() const;
  91. UUID GetLastOpenedUser() const;
  92. bool CanSystemRegisterUser() const;
  93. private:
  94. std::array<ProfileInfo, MAX_USERS> profiles{};
  95. std::size_t user_count = 0;
  96. boost::optional<std::size_t> AddToProfiles(const ProfileInfo& profile);
  97. bool RemoveProfileAtIndex(std::size_t index);
  98. UUID last_opened_user{INVALID_UUID};
  99. };
  100. }; // namespace Service::Account