profile_manager.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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 <optional>
  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 u128 INVALID_UUID{{0, 0}};
  13. struct UUID {
  14. // UUIDs which are 0 are considered invalid!
  15. u128 uuid = INVALID_UUID;
  16. UUID() = default;
  17. explicit UUID(const u128& id) : uuid{id} {}
  18. explicit UUID(const u64 lo, const u64 hi) : uuid{{lo, hi}} {}
  19. explicit operator bool() const {
  20. return uuid != INVALID_UUID;
  21. }
  22. bool operator==(const UUID& rhs) const {
  23. return uuid == rhs.uuid;
  24. }
  25. bool operator!=(const UUID& rhs) const {
  26. return !operator==(rhs);
  27. }
  28. // TODO(ogniK): Properly generate uuids based on RFC-4122
  29. static UUID Generate();
  30. // Set the UUID to {0,0} to be considered an invalid user
  31. void Invalidate() {
  32. uuid = INVALID_UUID;
  33. }
  34. std::string Format() const;
  35. std::string FormatSwitch() const;
  36. };
  37. static_assert(sizeof(UUID) == 16, "UUID is an invalid size!");
  38. constexpr std::size_t profile_username_size = 32;
  39. using ProfileUsername = std::array<u8, profile_username_size>;
  40. using UserIDArray = std::array<UUID, MAX_USERS>;
  41. /// Contains extra data related to a user.
  42. /// TODO: RE this structure
  43. struct ProfileData {
  44. INSERT_PADDING_WORDS(1);
  45. u32 icon_id;
  46. u8 bg_color_id;
  47. INSERT_PADDING_BYTES(0x7);
  48. INSERT_PADDING_BYTES(0x10);
  49. INSERT_PADDING_BYTES(0x60);
  50. };
  51. static_assert(sizeof(ProfileData) == 0x80, "ProfileData structure has incorrect size");
  52. /// This holds general information about a users profile. This is where we store all the information
  53. /// based on a specific user
  54. struct ProfileInfo {
  55. UUID user_uuid;
  56. ProfileUsername username;
  57. u64 creation_time;
  58. ProfileData data; // TODO(ognik): Work out what this is
  59. bool is_open;
  60. };
  61. struct ProfileBase {
  62. UUID user_uuid;
  63. u64_le timestamp;
  64. ProfileUsername username;
  65. // Zero out all the fields to make the profile slot considered "Empty"
  66. void Invalidate() {
  67. user_uuid.Invalidate();
  68. timestamp = 0;
  69. username.fill(0);
  70. }
  71. };
  72. static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase is an invalid size");
  73. /// The profile manager is used for handling multiple user profiles at once. It keeps track of open
  74. /// users, all the accounts registered on the "system" as well as fetching individual "ProfileInfo"
  75. /// objects
  76. class ProfileManager {
  77. public:
  78. ProfileManager();
  79. ~ProfileManager();
  80. ResultCode AddUser(const ProfileInfo& user);
  81. ResultCode CreateNewUser(UUID uuid, const ProfileUsername& username);
  82. ResultCode CreateNewUser(UUID uuid, const std::string& username);
  83. std::optional<UUID> GetUser(std::size_t index) const;
  84. std::optional<std::size_t> GetUserIndex(const UUID& uuid) const;
  85. std::optional<std::size_t> GetUserIndex(const ProfileInfo& user) const;
  86. bool GetProfileBase(std::optional<std::size_t> index, ProfileBase& profile) const;
  87. bool GetProfileBase(UUID uuid, ProfileBase& profile) const;
  88. bool GetProfileBase(const ProfileInfo& user, ProfileBase& profile) const;
  89. bool GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile,
  90. ProfileData& data) const;
  91. bool GetProfileBaseAndData(UUID uuid, ProfileBase& profile, ProfileData& data) const;
  92. bool GetProfileBaseAndData(const ProfileInfo& user, ProfileBase& profile,
  93. ProfileData& data) const;
  94. std::size_t GetUserCount() const;
  95. std::size_t GetOpenUserCount() const;
  96. bool UserExists(UUID uuid) const;
  97. bool UserExistsIndex(std::size_t index) const;
  98. void OpenUser(UUID uuid);
  99. void CloseUser(UUID uuid);
  100. UserIDArray GetOpenUsers() const;
  101. UserIDArray GetAllUsers() const;
  102. UUID GetLastOpenedUser() const;
  103. bool CanSystemRegisterUser() const;
  104. bool RemoveUser(UUID uuid);
  105. bool SetProfileBase(UUID uuid, const ProfileBase& profile_new);
  106. private:
  107. void ParseUserSaveFile();
  108. void WriteUserSaveFile();
  109. std::optional<std::size_t> AddToProfiles(const ProfileInfo& profile);
  110. bool RemoveProfileAtIndex(std::size_t index);
  111. std::array<ProfileInfo, MAX_USERS> profiles{};
  112. std::size_t user_count = 0;
  113. UUID last_opened_user{INVALID_UUID};
  114. };
  115. }; // namespace Service::Account