mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
[XAM] Multiple Profile/Dashboard related changes.
- Replaced multiple unknown parameters with proper named ones - Added code to support creation of profile from dashboard initial run - Added flag to remove ODD from being enumerated in devices (probably valid but not sure)
This commit is contained in:
parent
d18f80457d
commit
dd112ed462
|
|
@ -489,6 +489,23 @@ bool ProfileManager::CreateProfile(const std::string gamertag, bool autologin,
|
||||||
return is_account_created;
|
return is_account_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProfileManager::CreateProfile(const X_XAMACCOUNTINFO* account_info,
|
||||||
|
uint64_t xuid) {
|
||||||
|
if (!xuid) {
|
||||||
|
xuid = GenerateXuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::filesystem::create_directories(GetProfilePath(xuid))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MountProfile(xuid)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateAccount(xuid, account_info);
|
||||||
|
}
|
||||||
|
|
||||||
const X_XAMACCOUNTINFO* ProfileManager::GetAccount(const uint64_t xuid) {
|
const X_XAMACCOUNTINFO* ProfileManager::GetAccount(const uint64_t xuid) {
|
||||||
if (!accounts_.count(xuid)) {
|
if (!accounts_.count(xuid)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -505,15 +522,26 @@ bool ProfileManager::CreateAccount(const uint64_t xuid,
|
||||||
string_util::copy_truncating(account.gamertag, gamertag_u16,
|
string_util::copy_truncating(account.gamertag, gamertag_u16,
|
||||||
sizeof(account.gamertag));
|
sizeof(account.gamertag));
|
||||||
|
|
||||||
UpdateAccount(xuid, &account);
|
const bool result = UpdateAccount(xuid, &account);
|
||||||
DismountProfile(xuid);
|
DismountProfile(xuid);
|
||||||
|
|
||||||
accounts_.insert({xuid, account});
|
if (result) {
|
||||||
return true;
|
accounts_.insert({xuid, account});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProfileManager::CreateAccount(const uint64_t xuid,
|
||||||
|
const X_XAMACCOUNTINFO* account) {
|
||||||
|
const bool result = UpdateAccount(xuid, account);
|
||||||
|
if (result) {
|
||||||
|
accounts_.insert({xuid, *account});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProfileManager::UpdateAccount(const uint64_t xuid,
|
bool ProfileManager::UpdateAccount(const uint64_t xuid,
|
||||||
X_XAMACCOUNTINFO* account) {
|
const X_XAMACCOUNTINFO* account) {
|
||||||
const std::string guest_path =
|
const std::string guest_path =
|
||||||
fmt::format(kDefaultMountFormat, xuid) + ":\\Account";
|
fmt::format(kDefaultMountFormat, xuid) + ":\\Account";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,8 @@ class ProfileManager {
|
||||||
|
|
||||||
bool CreateProfile(const std::string gamertag, bool autologin,
|
bool CreateProfile(const std::string gamertag, bool autologin,
|
||||||
bool default_xuid = false);
|
bool default_xuid = false);
|
||||||
// bool CreateProfile(const X_XAMACCOUNTINFO* account_info);
|
bool CreateProfile(const X_XAMACCOUNTINFO* account_info, uint64_t xuid);
|
||||||
|
|
||||||
bool DeleteProfile(const uint64_t xuid);
|
bool DeleteProfile(const uint64_t xuid);
|
||||||
|
|
||||||
void ModifyGamertag(const uint64_t xuid, std::string gamertag);
|
void ModifyGamertag(const uint64_t xuid, std::string gamertag);
|
||||||
|
|
@ -105,7 +106,8 @@ class ProfileManager {
|
||||||
private:
|
private:
|
||||||
void UpdateConfig(const uint64_t xuid, const uint8_t slot);
|
void UpdateConfig(const uint64_t xuid, const uint8_t slot);
|
||||||
bool CreateAccount(const uint64_t xuid, const std::string gamertag);
|
bool CreateAccount(const uint64_t xuid, const std::string gamertag);
|
||||||
bool UpdateAccount(const uint64_t xuid, X_XAMACCOUNTINFO* account);
|
bool CreateAccount(const uint64_t xuid, const X_XAMACCOUNTINFO* account);
|
||||||
|
bool UpdateAccount(const uint64_t xuid, const X_XAMACCOUNTINFO* account);
|
||||||
|
|
||||||
std::filesystem::path GetProfilePath(const uint64_t xuid) const;
|
std::filesystem::path GetProfilePath(const uint64_t xuid) const;
|
||||||
std::filesystem::path GetProfilePath(const std::string xuid) const;
|
std::filesystem::path GetProfilePath(const std::string xuid) const;
|
||||||
|
|
|
||||||
|
|
@ -91,11 +91,13 @@ class UserProfile {
|
||||||
|
|
||||||
std::span<const uint8_t> GetProfileIcon(XTileType icon_type) {
|
std::span<const uint8_t> GetProfileIcon(XTileType icon_type) {
|
||||||
// Overwrite same types?
|
// Overwrite same types?
|
||||||
if (icon_type == XTileType::kPersonalGamerTile) {
|
if (icon_type == XTileType::kPersonalGamerTile ||
|
||||||
|
icon_type == XTileType::kLocalGamerTile) {
|
||||||
icon_type = XTileType::kGamerTile;
|
icon_type = XTileType::kGamerTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icon_type == XTileType::kPersonalGamerTileSmall) {
|
if (icon_type == XTileType::kPersonalGamerTileSmall ||
|
||||||
|
icon_type == XTileType::kLocalGamerTileSmall) {
|
||||||
icon_type = XTileType::kGamerTileSmall;
|
icon_type = XTileType::kGamerTileSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -770,6 +770,8 @@ std::span<const uint8_t> UserTracker::GetIcon(uint64_t xuid, uint32_t title_id,
|
||||||
}
|
}
|
||||||
case XTileType::kGamerTile:
|
case XTileType::kGamerTile:
|
||||||
case XTileType::kGamerTileSmall:
|
case XTileType::kGamerTileSmall:
|
||||||
|
case XTileType::kLocalGamerTile:
|
||||||
|
case XTileType::kLocalGamerTileSmall:
|
||||||
case XTileType::kPersonalGamerTile:
|
case XTileType::kPersonalGamerTile:
|
||||||
case XTileType::kPersonalGamerTileSmall:
|
case XTileType::kPersonalGamerTileSmall:
|
||||||
return user->GetProfileIcon(tile_type);
|
return user->GetProfileIcon(tile_type);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
#include "xenia/kernel/xam/xam_private.h"
|
#include "xenia/kernel/xam/xam_private.h"
|
||||||
#include "xenia/kernel/xenumerator.h"
|
#include "xenia/kernel/xenumerator.h"
|
||||||
|
#include "xenia/vfs/devices/stfs_xbox.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
@ -171,6 +172,11 @@ dword_result_t XamContentCreateDeviceEnumerator_entry(dword_t content_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& device_info : dummy_device_infos_) {
|
for (const auto& device_info : dummy_device_infos_) {
|
||||||
|
if (device_info->device_type == DeviceType::ODD &&
|
||||||
|
(content_flags & vfs::XContentFlag::kExcludeReadOnlyDevices)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy our dummy device into the enumerator
|
// Copy our dummy device into the enumerator
|
||||||
auto device_data = e->AppendItem();
|
auto device_data = e->AppendItem();
|
||||||
assert_not_null(device_data);
|
assert_not_null(device_data);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ namespace xam {
|
||||||
enum class DeviceType : uint32_t {
|
enum class DeviceType : uint32_t {
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
HDD = 1,
|
HDD = 1,
|
||||||
|
MU = 2,
|
||||||
ODD = 4,
|
ODD = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,11 +62,40 @@ dword_result_t XamProfileCreate_entry(dword_t flags, lpdword_t device_id,
|
||||||
pointer_t<X_XAMACCOUNTINFO> account,
|
pointer_t<X_XAMACCOUNTINFO> account,
|
||||||
dword_t unk1, dword_t unk2, dword_t unk3,
|
dword_t unk1, dword_t unk2, dword_t unk3,
|
||||||
dword_t unk4) {
|
dword_t unk4) {
|
||||||
// **unk4
|
if (device_id) {
|
||||||
|
*device_id = 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xuid != 0) {
|
||||||
|
assert_always();
|
||||||
|
return X_E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
X_XAMACCOUNTINFO account_info_data;
|
||||||
|
memcpy(&account_info_data, account, sizeof(X_XAMACCOUNTINFO));
|
||||||
|
xe::copy_and_swap<char16_t>(account_info_data.gamertag,
|
||||||
|
account_info_data.gamertag, 16);
|
||||||
|
|
||||||
|
bool result = kernel_state()->xam_state()->profile_manager()->CreateProfile(
|
||||||
|
&account_info_data, xuid);
|
||||||
|
|
||||||
|
return result ? X_ERROR_SUCCESS : X_ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
DECLARE_XAM_EXPORT1(XamProfileCreate, kNone, kSketchy);
|
||||||
|
|
||||||
|
dword_result_t XamProfileClose_entry(lpstring_t mount_name) {
|
||||||
|
std::string guest_name = mount_name.value();
|
||||||
|
const bool result =
|
||||||
|
kernel_state()->file_system()->UnregisterDevice(guest_name + ':');
|
||||||
|
|
||||||
|
return result ? X_ERROR_SUCCESS : X_ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
DECLARE_XAM_EXPORT1(XamProfileClose, kNone, kStub);
|
||||||
|
|
||||||
|
dword_result_t XamProfileGetCreationStatus_entry(lpdword_t r3, lpdword_t r4) {
|
||||||
return X_ERROR_SUCCESS;
|
return X_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(XamProfileCreate, kNone, kStub);
|
DECLARE_XAM_EXPORT1(XamProfileGetCreationStatus, kNone, kStub);
|
||||||
|
|
||||||
} // namespace xam
|
} // namespace xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
||||||
|
|
@ -2086,15 +2086,19 @@ dword_result_t XamShowCreateProfileUI_entry(dword_t user_index, dword_t unkn) {
|
||||||
DECLARE_XAM_EXPORT1(XamShowCreateProfileUI, kUserProfiles, kImplemented);
|
DECLARE_XAM_EXPORT1(XamShowCreateProfileUI, kUserProfiles, kImplemented);
|
||||||
|
|
||||||
dword_result_t XamShowAchievementsUI_entry(dword_t user_index,
|
dword_result_t XamShowAchievementsUI_entry(dword_t user_index,
|
||||||
dword_t unk_mask) {
|
dword_t title_id) {
|
||||||
auto user = kernel_state()->xam_state()->GetUserProfile(user_index);
|
auto user = kernel_state()->xam_state()->GetUserProfile(user_index);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return X_ERROR_NO_SUCH_USER;
|
return X_ERROR_NO_SUCH_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t proper_title_id =
|
||||||
|
title_id ? title_id.value()
|
||||||
|
: kernel_state()->xam_state()->spa_info()->title_id();
|
||||||
|
|
||||||
const auto info =
|
const auto info =
|
||||||
kernel_state()->xam_state()->user_tracker()->GetUserTitleInfo(
|
kernel_state()->xam_state()->user_tracker()->GetUserTitleInfo(
|
||||||
user->xuid(), kernel_state()->xam_state()->spa_info()->title_id());
|
user->xuid(), proper_title_id);
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return X_ERROR_NO_SUCH_USER;
|
return X_ERROR_NO_SUCH_USER;
|
||||||
|
|
|
||||||
|
|
@ -638,7 +638,10 @@ dword_result_t XamReadTile_entry(dword_t tile_type, dword_t title_id,
|
||||||
dword_t overlapped_ptr) {
|
dword_t overlapped_ptr) {
|
||||||
auto user = kernel_state()->xam_state()->GetUserProfile(user_index);
|
auto user = kernel_state()->xam_state()->GetUserProfile(user_index);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return X_ERROR_INVALID_PARAMETER;
|
user = kernel_state()->xam_state()->GetUserProfile(item_id);
|
||||||
|
if (!user) {
|
||||||
|
return X_ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buffer_size_ptr) {
|
if (!buffer_size_ptr) {
|
||||||
|
|
@ -802,7 +805,7 @@ dword_result_t XamReadTileToTexture_entry(dword_t tile_type, dword_t title_id,
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(XamReadTileToTexture, kUserProfiles, kStub);
|
DECLARE_XAM_EXPORT1(XamReadTileToTexture, kUserProfiles, kStub);
|
||||||
|
|
||||||
dword_result_t XamWriteGamerTile_entry(dword_t arg1, dword_t arg2,
|
dword_result_t XamWriteGamerTile_entry(dword_t user_index, dword_t title_id,
|
||||||
dword_t small_tile_id,
|
dword_t small_tile_id,
|
||||||
dword_t big_tile_id, dword_t arg5,
|
dword_t big_tile_id, dword_t arg5,
|
||||||
dword_t overlapped_ptr) {
|
dword_t overlapped_ptr) {
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,13 @@ enum XContentFlag : uint32_t {
|
||||||
kForceUI = 0x200,
|
kForceUI = 0x200,
|
||||||
|
|
||||||
// Enumeration
|
// Enumeration
|
||||||
kExcludeCommon = 0x1000
|
kExcludeCommon = 0x1000,
|
||||||
|
|
||||||
|
// Other
|
||||||
|
kEnumerateAllProfiles = 0x10000000,
|
||||||
|
|
||||||
|
// Device enumerator?
|
||||||
|
kExcludeReadOnlyDevices = 0x80000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* STFS structures */
|
/* STFS structures */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue