[XAM/USER] - Implement Multiple Functions

- Implement XamUserGetCachedUserFlags, XamIsChildAccountSignedIn, XamUserGetOnlineLanguageFromXUID and XamUserGetOnlineCountryFromXUID
- add IsParentalControlled()
This commit is contained in:
The-Little-Wolf 2025-06-15 12:10:45 -07:00 committed by Radosław Gliński
parent fd1abfe6aa
commit 20d3ac4ca9
4 changed files with 60 additions and 9 deletions

View file

@ -95,10 +95,23 @@ class UserProfile {
uint32_t signin_state() const { return 1; }
uint32_t type() const { return 1 | 2; /* local | online profile? */ }
uint32_t GetReservedFlags() const {
return account_info_.GetReservedFlags();
};
uint32_t GetCachedFlags() const { return account_info_.GetCachedFlags(); };
uint32_t GetCountry() const {
return static_cast<uint32_t>(account_info_.GetCountry());
};
uint32_t GetSubscriptionTier() const {
return account_info_.GetSubscriptionTier();
}
uint32_t GetLanguage() const {
return static_cast<uint32_t>(account_info_.GetLanguage());
};
bool IsParentalControlled() const {
return account_info_.IsParentalControlled();
};
bool IsLiveEnabled() const { return account_info_.IsLiveEnabled(); }
std::span<const uint8_t> GetProfileIcon(XTileType icon_type) {

View file

@ -733,6 +733,18 @@ dword_result_t XamIsXbox1TitleId_entry(dword_t title_id) {
}
DECLARE_XAM_EXPORT1(XamIsXbox1TitleId, kNone, kImplemented);
dword_result_t XamIsChildAccountSignedIn_entry() {
for (uint32_t i = 0; i < XUserMaxUserCount; i++) {
const auto& profile = kernel_state()->xam_state()->GetUserProfile(i);
if (profile && profile->IsParentalControlled()) {
return true;
}
}
return false;
}
DECLARE_XAM_EXPORT1(XamIsChildAccountSignedIn, kNone, kImplemented);
void XamSetActiveDashAppInfo_entry(pointer_t<X_DASH_APP_INFO> dash_app) {
if (!dash_app) {
kernel_state()->dash_app_info_ = {};

View file

@ -19,6 +19,7 @@
#include "third_party/stb/stb_image.h"
DECLARE_int32(user_language);
DECLARE_int32(user_country);
namespace xe {
namespace kernel {
@ -913,6 +914,18 @@ dword_result_t XamUserGetSubscriptionType_entry(dword_t user_index,
}
DECLARE_XAM_EXPORT1(XamUserGetSubscriptionType, kUserProfiles, kStub);
dword_result_t XamUserGetCachedUserFlags_entry(dword_t user_index) {
if (!kernel_state()->xam_state()->IsUserSignedIn(user_index)) {
return 0;
}
const auto& user_profile =
kernel_state()->xam_state()->GetUserProfile(user_index);
return user_profile->GetCachedFlags();
}
DECLARE_XAM_EXPORT1(XamUserGetCachedUserFlags, kUserProfiles, kImplemented);
dword_result_t XamUserGetUserFlags_entry(dword_t user_index) {
if (!kernel_state()->xam_state()->IsUserSignedIn(user_index)) {
return 0;
@ -936,16 +949,24 @@ dword_result_t XamUserGetUserFlagsFromXUID_entry(qword_t xuid) {
DECLARE_XAM_EXPORT1(XamUserGetUserFlagsFromXUID, kUserProfiles, kImplemented);
dword_result_t XamUserGetOnlineLanguageFromXUID_entry(qword_t xuid) {
/* Notes:
- Calls XamUserGetUserFlagsFromXUID and returns (ulonglong)(cached_flag <<
0x20) >> 0x39 & 0x1f;
- XamUserGetMembershipTierFromXUID and XamUserGetOnlineCountryFromXUID also
call it
- Removed in metro
*/
return cvars::user_language;
const auto& user = kernel_state()->xam_state()->GetUserProfile(xuid);
if (!user) {
return cvars::user_language;
}
return user->GetLanguage();
}
DECLARE_XAM_EXPORT1(XamUserGetOnlineLanguageFromXUID, kUserProfiles, kStub);
DECLARE_XAM_EXPORT1(XamUserGetOnlineLanguageFromXUID, kUserProfiles,
kImplemented);
dword_result_t XamUserGetOnlineCountryFromXUID_entry(qword_t xuid) {
const auto& user = kernel_state()->xam_state()->GetUserProfile(xuid);
if (!user) {
return cvars::user_country;
}
return user->GetCountry();
}
DECLARE_XAM_EXPORT1(XamUserGetOnlineCountryFromXUID, kUserProfiles,
kImplemented);
constexpr uint8_t kStatsMaxAmount = 64;

View file

@ -812,6 +812,7 @@ struct X_XAMACCOUNTINFO {
return std::string_view(online_domain);
}
uint32_t GetReservedFlags() const { return reserved_flags; };
uint32_t GetCachedFlags() const { return cached_user_flags; };
XOnlineCountry GetCountry() const {
@ -823,6 +824,10 @@ struct X_XAMACCOUNTINFO {
(cached_user_flags & kSubscriptionTierMask) >> 20);
}
bool IsParentalControlled() const {
return static_cast<bool>((cached_user_flags & kLanguageMask) >> 24);
}
XLanguage GetLanguage() const {
return static_cast<XLanguage>((cached_user_flags & kLanguageMask) >> 25);
}