ReXGlue SDK
Loading...
Searching...
No Matches
user_profile.h
Go to the documentation of this file.
1
17
18#pragma once
19
20#include <cstddef>
21#include <memory>
22#include <unordered_map>
23#include <vector>
24#include <format>
25#include <string>
26#include <filesystem>
27#include <optional>
28#include <string_view>
29#include <functional>
30#include <span>
31
32#include <rex/platform.h>
33#include <rex/types.h>
34#include <rex/memory.h>
36#include <rex/memory/stream.h>
38#include <rex/result.h>
39#include <rex/filesystem/xdbf.h>
40#include <rex/utility.h>
41#include <rex/title.h>
42
43namespace rex::xam {
44
45class IContentManager;
46
53 u8 type;
54 u8 unk_1[3];
55 be_u32 unk_4;
57 union {
58 be_i32 s32;
59 be_i64 s64;
60 be_u32 u32;
61 be_f64 f64;
62 struct {
63 be_u32 size;
64 be_u32 ptr;
65 } unicode;
66 be_f32 f32;
67 struct {
68 be_u32 size;
69 be_u32 ptr;
70 } binary;
71 be_u64 filetime;
72 };
73};
74REX_STATIC_ASSERT_SIZE(X_USER_PROFILE_SETTING_DATA, 16);
75
78 be_u32 from;
79 be_u32 unk_04;
80 union {
81 be_u32 user_index;
82 be_u64 xuid;
83 };
84 be_u32 setting_id;
85 be_u32 unk_14;
86 union {
87 u8 data_bytes[sizeof(X_USER_PROFILE_SETTING_DATA)];
89 };
90};
91REX_STATIC_ASSERT_SIZE(X_USER_PROFILE_SETTING, 40);
92
93class UserProfile {
94 public:
96 class SettingByteStream : public memory::ByteStream {
97 public:
98 SettingByteStream(u32 ptr, u8* data, size_t data_length, size_t offset = 0)
99 : memory::ByteStream(data, data_length, offset), ptr_(ptr) {}
100
102 u32 GetPtr() const { return static_cast<u32>(ptr_ + GetOffset()); }
103
104 private:
105 u32 ptr_;
106 };
107
108 struct Setting {
110 enum class Type : u8 {
111 kContext = 0,
112 kInt32 = 1,
113 kInt64 = 2,
114 kDouble = 3,
115 kUnicode = 4,
116 kFloat = 5,
117 kBinary = 6,
118 kDateTime = 7,
119 kUnset = 0xFF,
120 };
121 union Key {
122 u32 value;
123 struct {
124 u32 id : 14;
125 u32 unk : 2;
126 u32 size : 12;
127 u32 type : 4;
128 };
129 };
130 u32 setting_id;
131 Type type;
132 size_t size;
133 bool is_set;
138 Setting(u32 setting_id, Type type, size_t size, bool is_set)
139 : setting_id(setting_id), type(type), size(size), is_set(is_set), loaded_title_id(0) {}
140 virtual ~Setting() = default;
148 (void)stream;
149 data->type = static_cast<u8>(type);
150 }
151
152 virtual std::vector<u8> Serialize() const { return std::vector<u8>(); }
154 virtual void Deserialize(const std::vector<u8>&) {}
160 bool IsTitleSpecific() const { return (setting_id & 0x3F00) == 0x3F00; }
161 };
162 struct Int32Setting : public Setting {
163 Int32Setting(u32 id, i32 value) : Setting(id, Type::kInt32, 4, true), value(value) {}
164 i32 value;
166 Setting::WriteTo(data, stream);
167 data->s32 = value;
168 }
169 };
170 struct Int64Setting : public Setting {
171 Int64Setting(u32 id, i64 value) : Setting(id, Type::kInt64, 8, true), value(value) {}
172 i64 value;
174 Setting::WriteTo(data, stream);
175 data->s64 = value;
176 }
177 };
178 struct DoubleSetting : public Setting {
179 DoubleSetting(u32 id, f64 value) : Setting(id, Type::kDouble, 8, true), value(value) {}
180 f64 value;
182 Setting::WriteTo(data, stream);
183 data->f64 = value;
184 }
185 };
186 struct UnicodeSetting : public Setting {
187 UnicodeSetting(u32 id, const std::u16string& value)
188 : Setting(id, Type::kUnicode, 8, true), value(value) {}
189 std::u16string value;
191 Setting::WriteTo(data, stream);
192 if (value.empty()) {
193 data->unicode.size = 0;
194 data->unicode.ptr = 0;
195 } else {
196 size_t count = value.size() + 1;
197 size_t size = 2 * count;
198 REX_ASSERT(size <= std::numeric_limits<u32>::max());
199 data->unicode.size = static_cast<u32>(size);
200 data->unicode.ptr = stream->GetPtr();
201 auto buffer = reinterpret_cast<u16*>(&stream->GetData()[stream->GetOffset()]);
202 stream->Advance(size);
203 memory::copy_and_swap(buffer, reinterpret_cast<const u16*>(value.data()), count);
204 }
205 }
206 };
207 struct FloatSetting : public Setting {
208 FloatSetting(u32 id, f32 value) : Setting(id, Type::kFloat, 4, true), value(value) {}
209 f32 value;
211 Setting::WriteTo(data, stream);
212 data->f32 = value;
213 }
214 };
215 struct BinarySetting : public Setting {
216 BinarySetting(u32 id) : Setting(id, Type::kBinary, 8, false) {}
217 BinarySetting(u32 id, const std::vector<u8>& value)
218 : Setting(id, Type::kBinary, 8, true), value(value) {}
219 std::vector<u8> value;
221 Setting::WriteTo(data, stream);
222 if (value.empty()) {
223 data->binary.size = 0;
224 data->binary.ptr = 0;
225 } else {
226 size_t size = value.size();
227 REX_ASSERT(size <= std::numeric_limits<u32>::max());
228 data->binary.size = static_cast<u32>(size);
229 data->binary.ptr = stream->GetPtr();
230 stream->Write(value.data(), size);
231 }
232 }
233 std::vector<u8> Serialize() const override {
234 return std::vector<u8>(value.data(), value.data() + value.size());
235 }
236 void Deserialize(const std::vector<u8>& data) override {
237 value = data;
238 is_set = true;
239 }
240 };
241 struct DateTimeSetting : public Setting {
242 DateTimeSetting(u32 id, i64 value) : Setting(id, Type::kDateTime, 8, true), value(value) {}
243 i64 value;
245 Setting::WriteTo(data, stream);
246 data->filetime = value;
247 }
248 };
249
251
259 content_ = &content;
260 title_id_ = std::move(title_id);
261 }
262
263 u64 GetXUID() const { return xuid_; }
264
265 std::string GetName() const { return name_; }
266
270 u32 GetSigninState() const { return 1; }
271
276 u32 GetType() const { return 1 | 2; }
277
284 REX_XAM_API void AddSetting(std::unique_ptr<Setting> setting);
290
291 private:
292 u64 xuid_;
293 std::string name_;
294 std::vector<std::unique_ptr<Setting>> setting_list_;
295 std::unordered_map<u32, Setting*> settings_;
296 IContentManager* content_ = nullptr;
297 rex::MoveOnlyFunction<u32()> title_id_;
298
299 REX_XAM_API void LoadSetting(UserProfile::Setting*);
300 REX_XAM_API void SaveSetting(UserProfile::Setting*);
301};
302
303} // namespace rex::xam
304
306template <>
307struct std::formatter<rex::xam::UserProfile::Setting::Type> : std::formatter<rex::i32> {
308 auto format(rex::xam::UserProfile::Setting::Type value, std::format_context& ctx) const {
309 return std::formatter<rex::i32>::format(static_cast<rex::i32>(value), ctx);
310 }
311};
#define REX_ASSERT(cond,...)
Definition assert.h:84
Definition stream.h:95
void Write(std::span< const u8 > buf)
Definition content_manager.h:73
Definition user_profile.h:96
u32 GetPtr() const
Definition user_profile.h:102
Definition user_profile.h:93
u32 GetType() const
Definition user_profile.h:276
REX_XAM_API void AddSetting(std::unique_ptr< Setting > setting)
REX_XAM_API Setting * GetSetting(u32 setting_id)
void SetContentManager(IContentManager &content, rex::MoveOnlyFunction< u32()> title_id)
Definition user_profile.h:258
u32 GetSigninState() const
Definition user_profile.h:270
Content package and language IDs.
void copy_and_swap(T *dest, const T *src, size_t count)
Definition endian.h:98
Definition app.h:36
typename detail::MoveOnlyFunctionFor< Signature >::type MoveOnlyFunction
Definition utility.h:254
Platform flags, packing macros and export markers.
#define REX_XAM_API
Definition platform.h:314
Bit, byte and ring buffer streams over memory.
void WriteTo(X_USER_PROFILE_SETTING_DATA *data, SettingByteStream *stream) override
Definition user_profile.h:220
std::vector< u8 > Serialize() const override
Definition user_profile.h:233
void Deserialize(const std::vector< u8 > &data) override
Definition user_profile.h:236
void WriteTo(X_USER_PROFILE_SETTING_DATA *data, SettingByteStream *stream) override
Definition user_profile.h:244
void WriteTo(X_USER_PROFILE_SETTING_DATA *data, SettingByteStream *stream) override
Definition user_profile.h:181
void WriteTo(X_USER_PROFILE_SETTING_DATA *data, SettingByteStream *stream) override
Definition user_profile.h:210
void WriteTo(X_USER_PROFILE_SETTING_DATA *data, SettingByteStream *stream) override
Definition user_profile.h:165
void WriteTo(X_USER_PROFILE_SETTING_DATA *data, SettingByteStream *stream) override
Definition user_profile.h:173
Definition user_profile.h:108
virtual void Deserialize(const std::vector< u8 > &)
Definition user_profile.h:154
virtual std::vector< u8 > Serialize() const
Definition user_profile.h:152
bool IsTitleSpecific() const
Definition user_profile.h:160
Type
Definition user_profile.h:110
virtual void WriteTo(X_USER_PROFILE_SETTING_DATA *data, SettingByteStream *stream)
Definition user_profile.h:147
u32 loaded_title_id
Definition user_profile.h:134
Setting(u32 setting_id, Type type, size_t size, bool is_set)
Definition user_profile.h:138
void WriteTo(X_USER_PROFILE_SETTING_DATA *data, SettingByteStream *stream) override
Definition user_profile.h:190
Definition user_profile.h:48
u8 unk_1[3]
Definition user_profile.h:54
u8 type
Definition user_profile.h:53
be_u32 unk_4
Definition user_profile.h:55
Definition user_profile.h:77
be_u32 from
Definition user_profile.h:78
be_u32 unk_14
Definition user_profile.h:85
be_u32 unk_04
Definition user_profile.h:79
Integer types, byte order wrappers and size literals.
Definition user_profile.h:121
struct rex::xam::X_USER_PROFILE_SETTING_DATA::@043023330207035126171061172277334130165007315100::@176300045133233070153170276052336107266103122233 binary
struct rex::xam::X_USER_PROFILE_SETTING_DATA::@043023330207035126171061172277334130165007315100::@151134163212016230170311217005205051130261302341 unicode
Move only function, const propagating pointer and scope guard.