* Add security notice

* Updating libHttpClient

* Update to 2011 GDK QFE1 (#550)

Co-authored-by: jplafonta <jlafonta0550@gmail.com>
Co-authored-by: Nathan Iskandar <54045034+natiskan@users.noreply.github.com>
This commit is contained in:
Ramsey 2021-01-25 13:17:54 -08:00 коммит произвёл GitHub
Родитель a674430474
Коммит 02e1e048fb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
95 изменённых файлов: 1096 добавлений и 432 удалений

Просмотреть файл

@ -20,6 +20,6 @@ extern "C"
/// YYYYMMDD Date string describing the date the build was created
/// rrr QFE number (000 indicates base release)
/// </summary>
#define XAL_VERSION "2020.11.20201102.000"
#define XAL_VERSION "2020.11.20201204.001"
}

Просмотреть файл

@ -165,6 +165,11 @@ typedef struct XblLeaderboardRow
/// </summary>
uint32_t rank;
/// <summary>
/// The global rank of the player.
/// </summary>
uint32_t globalRank;
/// <summary>
/// UTF-8 encoded values for each column in the leaderboard row for the player.
/// </summary>

Просмотреть файл

@ -542,7 +542,7 @@ STDAPI XblMultiplayerEventArgsMembers(
/// </summary>
/// <param name="argsHandle">The event args handle from the XblMultiplayerEvent.</param>
/// <param name="member">Passes back a given member for the following event results:
/// XblMultiplayerEventType::HostChanged - The new host member. If an existing host leaves, argsHandle will be nullptr.
/// XblMultiplayerEventType::HostChanged - The new host member. If an existing host leaves, there won't be a member to pass back so this function will return HRESULT_FROM_WIN32(ERROR_RESOURCE_DATA_NOT_FOUND).
/// XblMultiplayerEventType::MemberPropertyChanged - The member whose property changed.</param>
/// <returns>HRESULT return code for this API operation.</returns>
STDAPI XblMultiplayerEventArgsMember(

Просмотреть файл

@ -20,6 +20,12 @@ xbox_live_context::xbox_live_context(_In_ XblUserHandle user)
HRESULT hr = XblContextCreateHandle(user, &m_handle);
if (FAILED(hr)) throw std::runtime_error("XblContextCreateHandle failed");
XblSetApiType(XblApiType::XblCPPApi);
// Unlike the rest of the services, notification_service needs to maintain state
// That is because of the differences between C-APIs for subscribing for RTA events
// and the C++ subscribe_to_notifications call
m_notificationService = std::make_shared<notification::notification_service>(m_handle);
}
xbox_live_context::xbox_live_context(_In_ XblContextHandle xboxLiveContextHandle)

Просмотреть файл

@ -85,7 +85,10 @@ try
return ApiImpl([&](AchievementsManager& achievementsManager)
{
RETURN_HR_INVALIDARGUMENT_IF(user == nullptr);
return achievementsManager.AddLocalUser(user, TaskQueue::DeriveWorkerQueue(queue));
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
return achievementsManager.AddLocalUser(wrapUserResult.ExtractPayload(), TaskQueue::DeriveWorkerQueue(queue));
});
}
CATCH_RETURN()
@ -98,7 +101,10 @@ try
return ApiImpl([&](AchievementsManager& achievementsManager)
{
RETURN_HR_INVALIDARGUMENT_IF_NULL(user);
return achievementsManager.RemoveLocalUser(user);
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
return achievementsManager.RemoveLocalUser(wrapUserResult.Payload());
});
}
CATCH_RETURN()

Просмотреть файл

@ -60,18 +60,17 @@ std::shared_ptr<xbox::services::RefCounter> XblAchievementsManagerResult::GetSha
NAMESPACE_MICROSOFT_XBOX_SERVICES_ACHIEVEMENTS_MANAGER_CPP_BEGIN
AchievementsManagerUser::AchievementsManagerUser(
_In_ const User& localUser,
_In_ User&& localUser,
_In_ const TaskQueue& queue
) noexcept :
m_queue{ queue.DeriveWorkerQueue() },
m_xuid{ localUser.Xuid() },
m_rtaManager{ GlobalState::Get()->RTAManager() }
{
m_xblContext = MakeShared<XblContext>(localUser);
m_xblContext->Initialize(m_rtaManager);
// Maintain legacy RTA activation count.
m_rtaManager->Activate(localUser);
m_xblContext = XblContext::Make(std::move(localUser));
}
AchievementsManagerUser::~AchievementsManagerUser()
@ -107,8 +106,9 @@ Result<void> AchievementsManagerUser::Initialize(
)
{
assert(!m_isInitialized);
std::weak_ptr<AchievementsManagerUser> weakThis{ shared_from_this() };
RETURN_HR_IF_FAILED(m_xblContext->Initialize(m_rtaManager));
std::weak_ptr<AchievementsManagerUser> weakThis{ shared_from_this() };
m_achievementProgressToken = m_xblContext->AchievementsService()->AddAchievementProgressChangeHandler(
[weakThis](const XblAchievementProgressChangeEventArgs& args)
{
@ -1212,19 +1212,20 @@ HRESULT AchievementsManager::CleanUpDeepCopyAchievement(XblAchievement& achievem
}
HRESULT AchievementsManager::AddLocalUser(
const User & user,
User&& user,
TaskQueue && queue
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
if (m_localUsers.find(user.Xuid()) != m_localUsers.end())
auto xuid{ user.Xuid() };
if (m_localUsers.find(xuid) != m_localUsers.end())
{
LOGS_ERROR << "User " << user.Xuid() << " already added to AchievementsManager";
LOGS_ERROR << "User " << xuid << " already added to AchievementsManager";
return E_UNEXPECTED;
}
auto localUser = MakeShared<AchievementsManagerUser>(user, queue);
auto localUser = MakeShared<AchievementsManagerUser>(std::move(user), queue);
Result<void> result = localUser->Initialize(AsyncContext<HRESULT>{
[
@ -1250,14 +1251,14 @@ HRESULT AchievementsManager::AddLocalUser(
if (Succeeded(result))
{
m_localUsers[user.Xuid()] = localUser;
m_localUsers[xuid] = localUser;
}
return result.Hresult();
}
HRESULT AchievementsManager::RemoveLocalUser(
const User & user
const User& user
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };

Просмотреть файл

@ -100,7 +100,7 @@ class AchievementsManagerUser : public std::enable_shared_from_this<Achievements
{
public:
AchievementsManagerUser(
_In_ const User& localUser,
_In_ User&& localUser,
_In_ const TaskQueue& queue
) noexcept;
virtual ~AchievementsManagerUser();
@ -192,7 +192,7 @@ public:
static HRESULT CleanUpDeepCopyAchievement(_In_ XblAchievement& achievement);
HRESULT AddLocalUser(
_In_ const User& user,
_In_ User&& user,
_In_ TaskQueue&& queue
) noexcept;

Просмотреть файл

@ -67,13 +67,13 @@ EXTERN_C __declspec(selectany) ETX_PROVIDER_DESCRIPTOR XSAPI_Update_Achievement_
#endif
AchievementsService::AchievementsService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<AppConfig> appConfig,
_In_ std::weak_ptr<XblContext> xboxLiveContextImpl,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) :
m_user(std::move(user)),
) :
m_user{ std::move(user) },
m_xboxLiveContextSettings(std::move(xboxLiveContextSettings)),
m_appConfig(std::move(appConfig)),
m_xboxLiveContextImpl(std::move(xboxLiveContextImpl)),
@ -101,7 +101,7 @@ HRESULT AchievementsService::UpdateAchievement(
HRESULT AchievementsService::UpdateAchievement(
_In_ uint64_t xboxUserId,
_In_ uint32_t titleId,
_In_ String scid,
_In_ const String& scid,
_In_ const String& achievementId,
_In_ uint32_t percentComplete,
_In_ AsyncContext<Result<void>> async
@ -112,6 +112,9 @@ HRESULT AchievementsService::UpdateAchievement(
RETURN_HR_INVALIDARGUMENT_IF(achievementId.empty());
RETURN_HR_INVALIDARGUMENT_IF(percentComplete > 100);
// Achievements service is doing case sensitive comparison on scid and always expects it to be lower case
String lowercaseScid = utils::ToLower(scid);
#if HC_PLATFORM == HC_PLATFORM_XDK
{
auto xsapiSingleton = get_xsapi_singleton();
@ -128,13 +131,12 @@ HRESULT AchievementsService::UpdateAchievement(
return hr;
}
string_t wScid = utils::string_t_from_internal_string(scid);
string_t wScid = utils::string_t_from_internal_string(lowercaseScid);
std::error_code errC = utils::guid_from_string(wScid, const_cast<GUID*>(&XSAPI_Update_Achievement_Provider.Guid), false);
if (errC)
{
return utils::convert_xbox_live_error_code_to_hresult(errC);
}
scid = utils::internal_string_from_string_t(wScid);
CHAR strTitleId[16] = "";
sprintf_s(strTitleId, "%0.8X", titleId);
@ -158,9 +160,12 @@ HRESULT AchievementsService::UpdateAchievement(
#endif
Stringstream subPath;
subPath << ("/users/xuid(") << xboxUserId << (")/achievements/") << scid << ("/update");
subPath << ("/users/xuid(") << xboxUserId << (")/achievements/") << lowercaseScid << ("/update");
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -182,7 +187,7 @@ HRESULT AchievementsService::UpdateAchievement(
achievementsJson.PushBack(achievementJson, allocator);
request.AddMember("action", "progressUpdate", allocator);
request.AddMember("serviceConfigId", JsonValue(scid.c_str(), allocator).Move(), allocator);
request.AddMember("serviceConfigId", JsonValue(lowercaseScid.c_str(), allocator).Move(), allocator);
request.AddMember("titleId", titleId, allocator);
request.AddMember("userId", JsonValue(utils::uint64_to_internal_string(xboxUserId).c_str(), allocator).Move(), allocator);
request.AddMember("achievements", achievementsJson, allocator);
@ -358,9 +363,12 @@ HRESULT AchievementsService::GetAchievement(
RETURN_HR_INVALIDARGUMENT_IF(achievementId.empty());
Stringstream subPath;
subPath << ("/users/xuid(") << xboxUserId << (")/achievements/") << serviceConfigurationId << ("/") << achievementId;
subPath << ("/users/xuid(") << xboxUserId << (")/achievements/") << utils::ToLower(serviceConfigurationId) << ("/") << achievementId;
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"GET",
@ -444,7 +452,10 @@ HRESULT AchievementsService::GetAchievements(
continuationToken
);
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"GET",

Просмотреть файл

@ -41,7 +41,7 @@ class AchievementsService : public std::enable_shared_from_this<AchievementsServ
{
public:
AchievementsService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<AppConfig> appConfig,
_In_ std::weak_ptr<::XblContext> xboxLiveContextImpl,
@ -58,7 +58,7 @@ public:
HRESULT UpdateAchievement(
_In_ uint64_t xboxUserId,
_In_ uint32_t titleId,
_In_ String serviceConfigurationId,
_In_ const String& serviceConfigurationId,
_In_ const String& achievementId,
_In_ uint32_t percentComplete,
_In_ AsyncContext<Result<void>> async

Просмотреть файл

@ -16,7 +16,7 @@ AchievementProgressChangeSubscription::AchievementProgressChangeSubscription(
: m_userId(xuid)
{
Stringstream uri;
uri << "https://achievements.xboxlive.com/users/xuid(" << m_userId << ")/achievements/" << scid;
uri << "https://achievements.xboxlive.com/users/xuid(" << m_userId << ")/achievements/" << utils::ToLower(scid);
m_resourceUri = uri.str();
}

Просмотреть файл

@ -20,9 +20,17 @@
using namespace xbox::services;
using namespace xbox::services::system;
XblContext::XblContext(_In_ xbox::services::User user) noexcept
: m_user{ std::move(user) }
/*static*/ std::shared_ptr<XblContext> XblContext::Make(
_In_ xbox::services::User&& user
) noexcept
{
auto xblContext = std::shared_ptr<XblContext>(
new (Alloc(sizeof(XblContext))) XblContext
{
std::move(user)
}
);
return xblContext;
}
const xbox::services::User& XblContext::User() const noexcept
@ -51,43 +59,119 @@ HRESULT XblContext::Initialize(
std::weak_ptr<XblContext> thisWeakPtr = shared_from_this();
m_achievementService = MakeShared<xbox::services::achievements::AchievementsService>(m_user, m_xboxLiveContextSettings, AppConfig::Instance(), thisWeakPtr, rtaManager);
m_profileService = MakeShared<xbox::services::social::ProfileService>(m_user, m_xboxLiveContextSettings, AppConfig::Instance());
m_reputationServiceImpl = MakeShared<xbox::services::social::ReputationService>(m_user, m_xboxLiveContextSettings);
m_presenceService = MakeShared<xbox::services::presence::PresenceService>(m_user, m_xboxLiveContextSettings, rtaManager);
m_socialService = MakeShared<xbox::services::social::SocialService>(m_user, m_xboxLiveContextSettings, rtaManager);
m_stringService = MakeShared<xbox::services::system::StringService>(m_user, m_xboxLiveContextSettings);
m_multiplayerService = MakeShared<xbox::services::multiplayer::MultiplayerService>(m_user, m_xboxLiveContextSettings, AppConfig::Instance(), rtaManager);
m_privacyService = MakeShared<privacy::PrivacyService>(m_user, m_xboxLiveContextSettings);
m_titleManagedStatisticsService = MakeShared<xbox::services::user_statistics::TitleManagedStatisticsService>(m_user, m_xboxLiveContextSettings);
m_userStatisticsService = MakeShared<xbox::services::user_statistics::UserStatisticsService>(m_user, m_xboxLiveContextSettings, rtaManager);
m_leaderboardService = MakeShared<xbox::services::leaderboard::LeaderboardService>(m_user, m_xboxLiveContextSettings, AppConfig::Instance());
m_matchmakingService = MakeShared<xbox::services::matchmaking::MatchmakingService>(m_user, m_xboxLiveContextSettings);
m_titleStorageService = MakeShared<xbox::services::title_storage::TitleStorageService>(m_user, m_xboxLiveContextSettings);
m_multiplayerActivityService = MakeShared<multiplayer_activity::MultiplayerActivityService>(m_user, get_xsapi_singleton_async_queue(), m_xboxLiveContextSettings);
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_achievementService = MakeShared<xbox::services::achievements::AchievementsService>(userResult.ExtractPayload(), m_xboxLiveContextSettings, AppConfig::Instance(), thisWeakPtr, rtaManager);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_profileService = MakeShared<xbox::services::social::ProfileService>(userResult.ExtractPayload(), m_xboxLiveContextSettings, AppConfig::Instance());
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_reputationServiceImpl = MakeShared<xbox::services::social::ReputationService>(userResult.ExtractPayload(), m_xboxLiveContextSettings);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_presenceService = MakeShared<xbox::services::presence::PresenceService>(userResult.ExtractPayload(), m_xboxLiveContextSettings, rtaManager);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_socialService = MakeShared<xbox::services::social::SocialService>(userResult.ExtractPayload(), m_xboxLiveContextSettings, rtaManager);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_stringService = MakeShared<xbox::services::system::StringService>(userResult.ExtractPayload(), m_xboxLiveContextSettings);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_multiplayerService = MakeShared<xbox::services::multiplayer::MultiplayerService>(userResult.ExtractPayload(), m_xboxLiveContextSettings, AppConfig::Instance(), rtaManager);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_privacyService = MakeShared<privacy::PrivacyService>(userResult.ExtractPayload(), m_xboxLiveContextSettings);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_titleManagedStatisticsService = MakeShared<xbox::services::user_statistics::TitleManagedStatisticsService>(userResult.ExtractPayload(), m_xboxLiveContextSettings);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_userStatisticsService = MakeShared<xbox::services::user_statistics::UserStatisticsService>(userResult.ExtractPayload(), m_xboxLiveContextSettings, rtaManager);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_leaderboardService = MakeShared<xbox::services::leaderboard::LeaderboardService>(userResult.ExtractPayload(), m_xboxLiveContextSettings, AppConfig::Instance());
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_matchmakingService = MakeShared<xbox::services::matchmaking::MatchmakingService>(userResult.ExtractPayload(), m_xboxLiveContextSettings);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_titleStorageService = MakeShared<xbox::services::title_storage::TitleStorageService>(userResult.ExtractPayload(), m_xboxLiveContextSettings);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
m_multiplayerActivityService = MakeShared<multiplayer_activity::MultiplayerActivityService>(userResult.ExtractPayload(), get_xsapi_singleton_async_queue(), m_xboxLiveContextSettings);
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
#if XSAPI_EVENTS_SERVICE
m_eventsService = MakeShared<events::EventsService>(
m_user
m_eventsService = MakeShared<events::EventsService>(
userResult.ExtractPayload()
#if XSAPI_INTERNAL_EVENTS_SERVICE
, get_xsapi_singleton_async_queue()
, get_xsapi_singleton_async_queue()
#endif
);
HRESULT hr = m_eventsService->Initialize();
RETURN_HR_IF_FAILED(hr);
);
RETURN_HR_IF_FAILED(m_eventsService->Initialize());
#endif
}
{
Result<xbox::services::User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
#if XSAPI_NOTIFICATION_SERVICE
#if !XSAPI_UNIT_TESTS && (HC_PLATFORM == HC_PLATFORM_WIN32 || HC_PLATFORM_IS_EXTERNAL)
m_notificationService = MakeShared<xbox::services::notification::RTANotificationService>(m_user, m_xboxLiveContextSettings, rtaManager);
m_notificationService->RegisterForSpopNotificationEvents();
m_notificationService = MakeShared<xbox::services::notification::RTANotificationService>(userResult.ExtractPayload(), m_xboxLiveContextSettings, rtaManager);
m_notificationService->RegisterForSpopNotificationEvents();
#elif HC_PLATFORM == HC_PLATFORM_ANDROID || HC_PLATFORM == HC_PLATFORM_IOS
m_notificationService = MakeShared<xbox::services::notification::MobileNotificationService>(m_user, m_xboxLiveContextSettings);
m_notificationService = MakeShared<xbox::services::notification::MobileNotificationService>(userResult.ExtractPayload(), m_xboxLiveContextSettings);
#elif HC_PLATFORM == HC_PLATFORM_UWP
m_notificationService = MakeShared<xbox::services::notification::UWPNotificationService>(m_user, m_xboxLiveContextSettings);
m_notificationService->RegisterWithNotificationService(AsyncContext<HRESULT>{TaskQueue{ get_xsapi_singleton_async_queue() }});
m_notificationService = MakeShared<xbox::services::notification::UWPNotificationService>(userResult.ExtractPayload(), m_xboxLiveContextSettings);
m_notificationService->RegisterWithNotificationService(AsyncContext<HRESULT>{TaskQueue{ get_xsapi_singleton_async_queue() }});
#endif
#endif
}
auto userChangedRegistrationResult = User::RegisterChangeEventHandler(
[

Просмотреть файл

@ -20,7 +20,10 @@ try
return E_XBL_NOT_INITIALIZED;
}
auto xboxLiveContext = MakeShared<XblContext>(user);
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
auto xboxLiveContext = XblContext::Make(wrapUserResult.ExtractPayload());
HRESULT hr = xboxLiveContext->Initialize(globalState->RTAManager());
if (SUCCEEDED(hr))

Просмотреть файл

@ -30,7 +30,10 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_MATCHMAKING_CPP_END
struct XblContext : public std::enable_shared_from_this<XblContext>, public xbox::services::RefCounter
{
public:
XblContext(_In_ xbox::services::User user) noexcept;
static std::shared_ptr<XblContext> Make(
_In_ xbox::services::User&& user
) noexcept;
~XblContext();
const xbox::services::User& User() const noexcept;
@ -137,6 +140,9 @@ public:
protected:
std::shared_ptr<xbox::services::RefCounter> GetSharedThis() override;
XblContext(_In_ xbox::services::User&& user) noexcept
: m_user{ std::move(user) }
{}
private:
std::shared_ptr<xbox::services::XboxLiveContextSettings> m_xboxLiveContextSettings;

Просмотреть файл

@ -8,7 +8,7 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_EVENTS_CPP_BEGIN
EventQueue::EventQueue(
User user,
User&& user,
std::shared_ptr<cll::CllTenantSettings> tenantSettings
) :
m_user{ std::move(user) },
@ -82,7 +82,9 @@ HRESULT EventQueue::AddEvents(xsapi_internal_vector<Event>&& events)
std::shared_ptr<EventUploadPayload> payload;
if (m_queue.empty())
{
payload = MakeShared<EventUploadPayload>(m_user, m_tenantSettings);
auto copyUserResult = m_user.Copy();
RETURN_HR_IF_FAILED(copyUserResult.Hresult());
payload = MakeShared<EventUploadPayload>(copyUserResult.ExtractPayload(), m_tenantSettings);
m_queue.push_back(payload);
}
else
@ -95,7 +97,9 @@ HRESULT EventQueue::AddEvents(xsapi_internal_vector<Event>&& events)
auto hr = payload->AddEvent(event);
if (FAILED(hr))
{
payload = MakeShared<EventUploadPayload>(m_user, m_tenantSettings);
auto copyUserResult = m_user.Copy();
RETURN_HR_IF_FAILED(copyUserResult.Hresult());
payload = MakeShared<EventUploadPayload>(copyUserResult.ExtractPayload(), m_tenantSettings);
m_queue.push_back(payload);
hr = payload->AddEvent(event);
RETURN_HR_IF_FAILED(hr);
@ -198,7 +202,12 @@ HRESULT EventQueue::Populate()
sharedThis->WriteDirectoryFile();
}
sharedThis->m_localStorage->ClearAsync(sharedThis->m_user.Handle(), metadata.first, nullptr);
auto clearAsyncHR = sharedThis->m_localStorage->ClearAsync(sharedThis->m_user, metadata.first, nullptr);
if (FAILED(clearAsyncHR))
{
// Log failure but don't let when failure prevent populating the rest of the files.
LOGS_WARN << "Failed to read events file due to user being available. HR = " << clearAsyncHR;
}
}
});
@ -208,6 +217,7 @@ HRESULT EventQueue::Populate()
LOGS_WARN << "Failed to read events file " << metadata.first << " that appeared in " << m_directoryFilename;
}
}
return S_OK;
}
@ -297,8 +307,17 @@ HRESULT EventQueue::Flush()
auto metadataToDelete{ sharedThis->m_fileMetadata.begin() };
sharedThis->m_totalFilesSize -= metadataToDelete->second;
sharedThis->m_localStorage->ClearAsync(sharedThis->m_user.Handle(), metadataToDelete->first, nullptr);
sharedThis->m_fileMetadata.erase(metadataToDelete);
auto clearAsyncHR = sharedThis->m_localStorage->ClearAsync(sharedThis->m_user, metadataToDelete->first, nullptr);
if (SUCCEEDED(clearAsyncHR))
{
sharedThis->m_fileMetadata.erase(metadataToDelete);
}
else
{
LOGS_INFO << "The user is currently unavailable. Failed to clear oldest event.";
return; //todo: What's the proper handling here?
}
}
sharedThis->WriteDirectoryFile();

Просмотреть файл

@ -13,7 +13,7 @@ using namespace xbox::services::legacy;
NAMESPACE_MICROSOFT_XBOX_SERVICES_EVENTS_CPP_BEGIN
EventUploadPayload::EventUploadPayload(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<cll::CllTenantSettings> tenantSettings
) :
m_user{ std::move(user) },

Просмотреть файл

@ -31,10 +31,8 @@ DEFINE_GUID(GUID_LOGGING_CHANNEL,
NAMESPACE_MICROSOFT_XBOX_SERVICES_EVENTS_CPP_BEGIN
EventsService::EventsService(
_In_ User user
) :
m_user{ std::move(user) }
EventsService::EventsService(_In_ User&& user)
: m_user{ std::move(user) }
{
m_playSession = utils::create_guid(true);
}
@ -49,8 +47,10 @@ EventsService::~EventsService()
#endif
}
HRESULT EventsService::Initialize()
HRESULT EventsService::Initialize(
)
{
#if HC_PLATFORM != HC_PLATFORM_UWP
m_hrCoIncrementMTAUsage = CoIncrementMTAUsage(&m_mtaUsageCookie);
if (FAILED(m_hrCoIncrementMTAUsage))

Просмотреть файл

@ -14,7 +14,7 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_EVENTS_CPP_BEGIN
class EventsService : public IEventsService, public std::enable_shared_from_this<EventsService>
{
public:
EventsService(_In_ User user);
EventsService(_In_ User&& user);
~EventsService();
HRESULT Initialize();

Просмотреть файл

@ -12,7 +12,7 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_EVENTS_CPP_BEGIN
EventsService::EventsService(
_In_ User user
User&& user
) :
m_user{ std::move(user) },
m_playSession{ utils::create_guid(true) }

Просмотреть файл

@ -12,12 +12,12 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_EVENTS_CPP_BEGIN
class EventsService : public IEventsService, public std::enable_shared_from_this<EventsService>
{
public:
EventsService(_In_ User user);
EventsService(_In_ User&& user);
~EventsService();
HRESULT Initialize();
HRESULT WriteInGameEvent(
HRESULT WriteInGameEvent(
_In_z_ const char* eventName,
_In_opt_z_ const char* dimensions,
_In_opt_z_ const char* measurements

Просмотреть файл

@ -20,9 +20,6 @@ EventsService::EventsService(
m_queue{ queue.DeriveWorkerQueue() }
{
InitializeTenantSettings();
m_eventQueue = MakeShared<EventQueue>(m_user, m_tenantSettings);
m_eventQueue->Initialize();
}
EventsService::~EventsService()
@ -33,6 +30,10 @@ EventsService::~EventsService()
HRESULT EventsService::Initialize()
{
auto copyUserResult = m_user.Copy();
RETURN_HR_IF_FAILED(copyUserResult.Hresult());
m_eventQueue = MakeShared<EventQueue>(copyUserResult.ExtractPayload(), m_tenantSettings);
m_eventQueue->Initialize();
return ScheduleUpload();
}
@ -197,7 +198,14 @@ HRESULT EventsService::UploadEventPayload(
auto sharedThis{ weakThis.lock() };
if (sharedThis && Succeeded(result))
{
auto httpCall = MakeShared<XblHttpCall>(sharedThis->m_user);
Result<User> userResult = sharedThis->m_user.Copy();
if (FAILED(userResult.Hresult()))
{
return async.Complete(userResult.Hresult());
}
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
auto hr = httpCall->Init(MakeShared<XboxLiveContextSettings>(), "POST", sharedThis->m_eventUploadUrl, xbox_live_api::events_upload);
if (FAILED(hr))
{

Просмотреть файл

@ -52,7 +52,7 @@ class EventUploadPayload : public std::enable_shared_from_this<EventUploadPayloa
{
public:
EventUploadPayload(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<cll::CllTenantSettings> tenantSettings
);
@ -96,7 +96,7 @@ class EventQueue : public std::enable_shared_from_this<EventQueue>
{
public:
EventQueue(
User user,
User&& user,
std::shared_ptr<cll::CllTenantSettings> tenantSettings
);

Просмотреть файл

@ -86,6 +86,7 @@ public:
_In_ uint64_t xboxUserId,
_In_ double percentile,
_In_ uint32_t rank,
_In_ uint32_t globalRank,
_In_ xsapi_internal_vector<xsapi_internal_string> columnValues,
_In_ xsapi_internal_string metadata
);
@ -107,6 +108,7 @@ public:
uint64_t XboxUserId() const;
double Percentile() const;
uint32_t Rank() const;
uint32_t GlobalRank() const;
const xsapi_internal_vector<xsapi_internal_string>& ColumnValues() const;
private:
@ -114,9 +116,10 @@ private:
xsapi_internal_string m_modernGamertag;
xsapi_internal_string m_modernGamertagSuffix;
xsapi_internal_string m_uniqueModernGamertag;
uint64_t m_xuid;
double m_percentile;
uint32_t m_rank;
uint64_t m_xuid{ 0 };
double m_percentile{ 0 };
uint32_t m_rank{ 0 };
uint32_t m_globalRank{ 0 };
xsapi_internal_vector<xsapi_internal_string> m_columnValues;
xsapi_internal_vector<const char*> m_columnValuesC;
JsonDocument m_metadata;
@ -167,7 +170,7 @@ class LeaderboardService : public std::enable_shared_from_this<LeaderboardServic
{
public:
LeaderboardService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::AppConfig> appConfig
);

Просмотреть файл

@ -20,6 +20,7 @@ LeaderboardRow::LeaderboardRow(
_In_ uint64_t xboxUserId,
_In_ double percentile,
_In_ uint32_t rank,
_In_ uint32_t globalRank,
_In_ xsapi_internal_vector<xsapi_internal_string> columnValues,
_In_ xsapi_internal_string metadata
) :
@ -30,6 +31,7 @@ LeaderboardRow::LeaderboardRow(
m_xuid{ xboxUserId },
m_percentile{ percentile },
m_rank{ rank },
m_globalRank{ globalRank },
m_columnValues(std::move(columnValues))
{
if(!metadata.empty())
@ -47,6 +49,7 @@ LeaderboardRow::LeaderboardRow(const LeaderboardRow& other)
m_xuid = other.m_xuid;
m_percentile = other.m_percentile;
m_rank = other.m_rank;
m_globalRank = other.m_globalRank;
m_columnValues = other.m_columnValues;
m_columnValuesC = other.m_columnValuesC;
JsonUtils::CopyFrom(m_metadata, other.m_metadata);
@ -61,6 +64,7 @@ LeaderboardRow& LeaderboardRow::operator =(const LeaderboardRow& other)
m_xuid = other.m_xuid;
m_percentile = other.m_percentile;
m_rank = other.m_rank;
m_globalRank = other.m_globalRank;
m_columnValues = other.m_columnValues;
m_columnValuesC = other.m_columnValuesC;
JsonUtils::CopyFrom(m_metadata, other.m_metadata);
@ -103,6 +107,11 @@ uint32_t LeaderboardRow::Rank() const
return m_rank;
}
uint32_t LeaderboardRow::GlobalRank() const
{
return m_globalRank;
}
const xsapi_internal_vector<xsapi_internal_string>& LeaderboardRow::ColumnValues() const
{
return m_columnValues;
@ -125,7 +134,9 @@ const xsapi_internal_vector<xsapi_internal_string>& LeaderboardRow::ColumnValues
double percentile = 0.0;
RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonDouble(json, "percentile", percentile, true));
int rank = 0;
int globalRank = 0;
RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonInt(json, "rank", rank, true));
RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonInt(json, "globalrank", globalRank, false));
xsapi_internal_vector<xsapi_internal_string> values;
if (json.IsObject() && json.HasMember("value") && !json["value"].IsNull())
{
@ -148,6 +159,7 @@ const xsapi_internal_vector<xsapi_internal_string>& LeaderboardRow::ColumnValues
xuid,
percentile,
rank,
globalRank,
values,
metadata
);
@ -175,6 +187,7 @@ char* LeaderboardRow::Serialize(XblLeaderboardRow* row, char* buffer)
row->percentile = m_percentile;
row->rank = m_rank;
row->globalRank = m_globalRank;
row->xboxUserId = m_xuid;
utils::strcpy(row->gamertag, sizeof(XblLeaderboardRow::gamertag), m_gamertag.c_str());

Просмотреть файл

@ -26,14 +26,15 @@ constexpr const char* g_eventBasedStatsGlobalLeaderboardVersion{ "3.1" };
constexpr const char* g_eventBasedStatsSocialLeaderboardVersion{ "1.1" };
LeaderboardService::LeaderboardService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::AppConfig> appConfig
) :
m_user(std::move(user)),
) :
m_user{ std::move(user) },
m_xboxLiveContextSettings(std::move(xboxLiveContextSettings)),
m_appConfig(std::move(appConfig))
{ }
{
}
xbl_result<xsapi_internal_string>
CreateLeaderboardUrl(
@ -171,7 +172,10 @@ LeaderboardService::GetLeaderboard(
if (op == XAsyncOp::DoWork)
{
auto httpCall = MakeShared<XblHttpCall>(sharedThis->m_user);
Result<User> userResult = sharedThis->m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
sharedThis->m_xboxLiveContextSettings,
"GET",
@ -360,7 +364,10 @@ LeaderboardService::GetLeaderboardForSocialGroup(
{
if (op == XAsyncOp::DoWork)
{
auto httpCall = MakeShared<XblHttpCall>(sharedThis->m_user);
Result<User> userResult = sharedThis->m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
sharedThis->m_xboxLiveContextSettings,
"GET",

Просмотреть файл

@ -10,7 +10,7 @@ class MatchmakingService : public std::enable_shared_from_this<MatchmakingServic
public:
MatchmakingService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
);

Просмотреть файл

@ -13,8 +13,8 @@ using namespace xbox::services::legacy;
NAMESPACE_MICROSOFT_XBOX_SERVICES_MATCHMAKING_CPP_BEGIN
MatchmakingService::MatchmakingService (
_In_ User user,
MatchmakingService::MatchmakingService(
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
) :
m_user{ std::move(user) },
@ -291,7 +291,10 @@ HRESULT MatchmakingService::CreateMatchTicket(
{
if (op == XAsyncOp::DoWork)
{
auto httpCall = MakeShared<XblHttpCall>(sharedThis->m_user);
Result<User> userResult = sharedThis->m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
sharedThis->m_contextSettings,
"POST",
@ -355,7 +358,10 @@ HRESULT MatchmakingService::DeleteMatchTicketAsync(
{
if (op == XAsyncOp::DoWork)
{
auto httpCall = MakeShared<XblHttpCall>(sharedThis->m_user);
Result<User> userResult = sharedThis->m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
sharedThis->m_contextSettings,
"DELETE",
@ -407,7 +413,10 @@ HRESULT MatchmakingService::GetMatchTicketDetailsAsync(
{
if (op == XAsyncOp::DoWork)
{
auto httpCall = MakeShared<XblHttpCall>(sharedThis->m_user);
Result<User> userResult = sharedThis->m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
sharedThis->m_contextSettings,
"GET",
@ -495,7 +504,10 @@ HRESULT MatchmakingService::GetHopperStatistics(
{
if (op == XAsyncOp::DoWork)
{
auto httpCall = MakeShared<XblHttpCall>(sharedThis->m_user);
Result<User> userResult = sharedThis->m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
sharedThis->m_contextSettings,
"GET",

Просмотреть файл

@ -273,7 +273,9 @@ MultiplayerClientManager::JoinLobby(
int invitedUserIndex = 0;
for (auto& user: users)
{
if (invitedXuid == User{ user }.Xuid())
auto userResult = User::WrapHandle(user);
RETURN_HR_IF_FAILED(userResult.Hresult());
if (invitedXuid == userResult.ExtractPayload().Xuid())
{
invitedUserFound = true;
break;
@ -458,10 +460,15 @@ MultiplayerClientManager::GetActivitiesForSocialGroup(
)
{
RETURN_HR_INVALIDARGUMENT_IF(user == nullptr);
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
return GetMultiplayerService(user)->GetActivitiesForSocialGroup(
auto serviceResult = GetMultiplayerService(user);
RETURN_HR_IF_FAILED(serviceResult.Hresult());
return serviceResult.ExtractPayload()->GetActivitiesForSocialGroup(
AppConfig::Instance()->OverrideScid(),
User{ user }.Xuid(),
wrapUserResult.Payload().Xuid(),
socialGroup,
AsyncContext<Result<Vector<XblMultiplayerActivityDetails>>>{ queue, std::move(callback) }
);
@ -604,7 +611,10 @@ MultiplayerClientManager::InviteUsers(
std::weak_ptr<MultiplayerClientManager> weakSessionWriter = shared_from_this();
return GetMultiplayerService(user)->SendInvites(
auto serviceResult = GetMultiplayerService(user);
RETURN_HR_IF_FAILED(serviceResult.Hresult());
return serviceResult.ExtractPayload()->SendInvites(
latestPendingRead->LobbyClient()->Session()->SessionReference(),
xboxUserIds,
AppConfig::Instance()->OverrideTitleId(),
@ -628,7 +638,7 @@ MultiplayerClientManager::InviteUsers(
});
}
std::shared_ptr<MultiplayerService>
Result<std::shared_ptr<MultiplayerService>>
MultiplayerClientManager::GetMultiplayerService(
_In_ xbox_live_user_t user
)
@ -642,7 +652,11 @@ MultiplayerClientManager::GetMultiplayerService(
{
std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings = MakeShared<xbox::services::XboxLiveContextSettings>();
std::shared_ptr<AppConfig> appConfig = xbox::services::AppConfig::Instance();
return MakeShared<MultiplayerService>(user, xboxLiveContextSettings, appConfig, nullptr);
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
auto multiplayerService = MakeShared<MultiplayerService>(wrapUserResult.ExtractPayload(), xboxLiveContextSettings, appConfig, nullptr);
return multiplayerService;
}
}

Просмотреть файл

@ -109,11 +109,25 @@ STDAPI XblMultiplayerEventArgsMember(
if (hostChangedArgs != nullptr)
{
*member = hostChangedArgs->HostMember->GetReference();
if (hostChangedArgs->HostMember != nullptr)
{
*member = hostChangedArgs->HostMember->GetReference();
}
else
{
return __HRESULT_FROM_WIN32(ERROR_RESOURCE_DATA_NOT_FOUND);
}
}
else if (memberPropertyChangedArgs != nullptr)
{
*member = memberPropertyChangedArgs->Member->GetReference();
if (memberPropertyChangedArgs->Member != nullptr)
{
*member = memberPropertyChangedArgs->Member->GetReference();
}
else
{
return __HRESULT_FROM_WIN32(ERROR_RESOURCE_DATA_NOT_FOUND);
}
}
else
{

Просмотреть файл

@ -327,7 +327,10 @@ MultiplayerLobbyClient::AddLocalUser(
if (localUser == nullptr)
{
localUser = m_multiplayerLocalUserManager->AddUserToXboxLiveContextToMap(user);
auto localUserResult = m_multiplayerLocalUserManager->AddUserToXboxLiveContextToMap(user);
RETURN_HR_IF_FAILED(localUserResult.Hresult());
localUser = localUserResult.ExtractPayload();
}
auto pendingRequest = std::make_shared<MultiplayerClientPendingRequest>();

Просмотреть файл

@ -10,7 +10,7 @@ using namespace xbox::services::multiplayer;
NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_MANAGER_CPP_BEGIN
MultiplayerLocalUser::MultiplayerLocalUser(
_In_ xbox_live_user_t user,
_In_ User&& user,
_In_ uint64_t xuid,
_In_ bool isPrimary
) :
@ -21,10 +21,11 @@ MultiplayerLocalUser::MultiplayerLocalUser(
m_xuid(xuid),
m_lobbyState(MultiplayerLocalUserLobbyState::Unknown),
m_gameState(MultiplayerLocalUserGameState::Unknown),
m_isPrimaryXboxLiveContext(isPrimary),
m_xboxLiveContextImpl(MakeShared<XblContext>(user))
m_isPrimaryXboxLiveContext(isPrimary)
{
// TODO parameterize RTAManager
m_xboxLiveContextImpl = XblContext::Make(std::move(user));
m_xboxLiveContextImpl->Initialize(GlobalState::Get()->RTAManager());
}

Просмотреть файл

@ -78,12 +78,13 @@ MultiplayerLocalUserManager::GetLocalUserHelper(
_In_ xbox_live_user_t user
)
{
if (user == nullptr)
auto wrapUserResult{ User::WrapHandle(user) };
if (Failed(wrapUserResult))
{
return nullptr;
}
return GetLocalUserHelper(User{ user }.Xuid());
return GetLocalUserHelper(wrapUserResult.Payload().Xuid());
}
std::shared_ptr<MultiplayerLocalUser>
@ -159,22 +160,32 @@ MultiplayerLocalUserManager::IsLocalUserGameState(
return true;
}
const std::shared_ptr<MultiplayerLocalUser>&
Result<const std::shared_ptr<MultiplayerLocalUser>>
MultiplayerLocalUserManager::AddUserToXboxLiveContextToMap(
_In_ xbox_live_user_t user
)
{
XSAPI_ASSERT(user != nullptr);
auto wrapUserResult{ User::WrapHandle(user) };
if (Failed(wrapUserResult))
{
return wrapUserResult.Hresult();
}
uint64_t xboxUserId = User{ user }.Xuid();
uint64_t xboxUserId = wrapUserResult.Payload().Xuid();
bool isPrimary = m_localUserRequestMap.size() == 0 ? true : false;
auto iter = m_localUserRequestMap.find(xboxUserId);
if (iter == m_localUserRequestMap.end())
{
auto innerWrapUserResult{ User::WrapHandle(user) };
if (Failed(innerWrapUserResult))
{
return innerWrapUserResult.Hresult();
}
auto localUser = std::make_shared<MultiplayerLocalUser>(
user,
innerWrapUserResult.ExtractPayload(),
xboxUserId,
isPrimary
);

Просмотреть файл

@ -722,6 +722,8 @@ public:
_In_ std::shared_ptr<MultiplayerLocalUserManager> localUserManager
) noexcept;
uint64_t Id() const;
const std::shared_ptr<XblMultiplayerSession>& Session() const;
void UpdateSession(_In_ const std::shared_ptr<XblMultiplayerSession>& updatedSession);
@ -824,6 +826,7 @@ private:
XblFunctionContext m_sessionUpdateEventHandlerCounter{ 0 };
UnorderedMap<uint32_t, Callback<const std::shared_ptr<XblMultiplayerSession>>> m_sessionUpdateEventHandler;
uint64_t m_id{ 0 }; // used to ignore calls made before resetting the state via destory()
std::mutex m_synchronizeWriteWithTapLock;
uint64_t m_tapChangeNumber{ 0 };
bool m_isTapReceived{ false };
@ -1226,7 +1229,7 @@ class MultiplayerLocalUser
public:
MultiplayerLocalUser(
_In_ xbox_live_user_t user,
_In_ User&& user,
_In_ uint64_t xboxUserId,
_In_ bool isPrimary
);
@ -1298,7 +1301,7 @@ public:
_In_ xbox_live_user_t user
);
const std::shared_ptr<MultiplayerLocalUser>& AddUserToXboxLiveContextToMap(_In_ xbox_live_user_t user);
Result<const std::shared_ptr<MultiplayerLocalUser>> AddUserToXboxLiveContextToMap(_In_ xbox_live_user_t user);
void RemoveStaleLocalUsersFromMap();
void ActivateMultiplayerEvents(_In_ const std::shared_ptr<xbox::services::multiplayer::manager::MultiplayerLocalUser>& localuser);
@ -1474,7 +1477,7 @@ private:
void Destroy();
std::shared_ptr<xbox::services::multiplayer::MultiplayerService> GetMultiplayerService(
Result<std::shared_ptr<xbox::services::multiplayer::MultiplayerService>> GetMultiplayerService(
_In_ xbox_live_user_t user
);
@ -1650,7 +1653,7 @@ private:
mutable std::mutex m_multiplayerEventQueueLock;
MultiplayerEventQueue m_multiplayerEventQueue;
XblCreateMatchTicketResponse m_matchTicketResponse{};
XblMultiplayerSessionReference m_matchTicketSessionRef;
XblMultiplayerSessionReference m_matchTicketSessionRef{};
std::shared_ptr<XblMultiplayerSession> m_matchSession;
std::shared_ptr<MultiplayerLocalUserManager> m_multiplayerLocalUserManager;

Просмотреть файл

@ -511,6 +511,7 @@ MultiplayerMatchClient::UpdateSession(
if (m_matchSession == nullptr || session == nullptr)
{
m_matchSession = session;
m_matchTicketSessionRef = {};
}
else if(XblMultiplayerSession::DoSessionsMatch(m_matchSession, session) &&
session->SessionInfo().ChangeNumber > m_matchSession->SessionInfo().ChangeNumber)
@ -593,7 +594,7 @@ void MultiplayerMatchClient::HandleMatchFound(
{
// Perhaps its OK to call handle_session_joined() immediately here, but to maintain behavioral parody with
// pplx code, differ that until the next do_work call
pThis->m_joinTargetSessionResult = result;
pThis->m_joinTargetSessionResult = std::move(result);
pThis->m_joinTargetSessionComplete = true;
}
});

Просмотреть файл

@ -34,6 +34,7 @@ MultiplayerSessionWriter::MultiplayerSessionWriter(
void
MultiplayerSessionWriter::Destroy()
{
m_id++;
m_session = nullptr;
m_isTapReceived = false;
m_numOfWritesInProgress = 0;
@ -46,6 +47,12 @@ MultiplayerSessionWriter::GetPrimaryContext()
return m_multiplayerLocalUserManager->GetPrimaryContext();
}
uint64_t
MultiplayerSessionWriter::Id() const
{
return m_id;
}
const std::shared_ptr<XblMultiplayerSession>&
MultiplayerSessionWriter::Session() const
{
@ -280,6 +287,7 @@ HRESULT MultiplayerSessionWriter::WriteSession(
AsyncContext<Result<std::shared_ptr<XblMultiplayerSession>>>{ m_queue,
[
weakThis = std::weak_ptr<MultiplayerSessionWriter>{ shared_from_this() },
sessionWriterId = m_id,
updateLatest,
callback
]
@ -287,7 +295,14 @@ HRESULT MultiplayerSessionWriter::WriteSession(
{
if (auto sharedThis{ weakThis.lock() })
{
sharedThis->HandleWriteSessionResult(sessionResult, updateLatest, callback);
if (sharedThis->Id() != sessionWriterId)
{
callback({ E_FAIL, "Session writer has been reset" });
}
else
{
sharedThis->HandleWriteSessionResult(sessionResult, updateLatest, callback);
}
}
else
{
@ -321,6 +336,7 @@ HRESULT MultiplayerSessionWriter::WriteSessionByHandle(
AsyncContext<Result<std::shared_ptr<XblMultiplayerSession>>>{ m_queue,
[
weakThis = std::weak_ptr<MultiplayerSessionWriter>{ shared_from_this() },
sessionWriterId = m_id,
updateLatest,
callback
]
@ -328,7 +344,14 @@ HRESULT MultiplayerSessionWriter::WriteSessionByHandle(
{
if (auto sharedThis{ weakThis.lock() })
{
sharedThis->HandleWriteSessionResult(sessionResult, updateLatest, callback);
if (sharedThis->Id() != sessionWriterId)
{
callback({ E_FAIL, "Session writer has been reset" });
}
else
{
sharedThis->HandleWriteSessionResult(sessionResult, updateLatest, callback);
}
}
else
{
@ -484,10 +507,12 @@ HRESULT MultiplayerSessionWriter::LeaveRemoteSession(
LeaveSessionOperation(
std::shared_ptr<MultiplayerSessionWriter> sessionWriter,
const XblMultiplayerSessionReference& sessionRefToLeave,
TaskQueue& queue,
MultiplayerSessionCallback&& callback
) noexcept :
m_sessionWriter{ std::move(sessionWriter) },
m_sessionToLeaveRef{ sessionRefToLeave },
m_queue{ queue },
m_localUsers{ m_sessionWriter->m_multiplayerLocalUserManager->GetLocalUserMap() },
m_callback{ std::move(callback) }
{
@ -519,11 +544,11 @@ HRESULT MultiplayerSessionWriter::LeaveRemoteSession(
RETURN_HR_IF_FAILED(sessionToCommit->Leave());
// Never update latest copy upon leaving.
return m_sessionWriter->WriteSession(
userContext,
return userContext->MultiplayerService()->WriteSession(
sessionToCommit,
XblMultiplayerSessionWriteMode::UpdateExisting,
false,
AsyncContext<Result<std::shared_ptr<XblMultiplayerSession>>>{ m_queue,
[
sharedThis{ shared_from_this() }, this
]
@ -538,11 +563,12 @@ HRESULT MultiplayerSessionWriter::LeaveRemoteSession(
m_latestSession = writeSessionResult.ExtractPayload();
sharedThis->Run();
}
});
}});
}
std::shared_ptr<MultiplayerSessionWriter> m_sessionWriter;
XblMultiplayerSessionReference m_sessionToLeaveRef;
TaskQueue m_queue;
Map<uint64_t, std::shared_ptr<MultiplayerLocalUser>> m_localUsers;
std::shared_ptr<XblMultiplayerSession> m_latestSession{ nullptr };
MultiplayerSessionCallback m_callback;
@ -551,6 +577,7 @@ HRESULT MultiplayerSessionWriter::LeaveRemoteSession(
auto operation = MakeShared<LeaveSessionOperation>(
shared_from_this(),
session->SessionReference(),
m_queue,
std::move(callback)
);

Просмотреть файл

@ -377,7 +377,7 @@ class MultiplayerService : public std::enable_shared_from_this<MultiplayerServic
{
public:
MultiplayerService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::AppConfig> appConfig,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaService

Просмотреть файл

@ -19,7 +19,7 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_MULTIPLAYER_CPP_BEGIN
#define MULTIPLAYER_SERVICE_CONTRACT_VERSION 107
MultiplayerService::MultiplayerService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::AppConfig> appConfig,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> realTimeActivity
@ -90,7 +90,10 @@ HRESULT MultiplayerService::GetCurrentSession(
sessionReference.SessionName
);
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"GET",
@ -149,7 +152,10 @@ HRESULT MultiplayerService::GetCurrentSessionByHandle(
RETURN_HR_INVALIDARGUMENT_IF(handleId.empty());
String pathAndQuery = MultiplayerSessionDirectoryCreateOrUpdateByHandleSubpath(handleId);
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"GET",
@ -334,7 +340,10 @@ HRESULT MultiplayerService::GetSessions(
RETURN_HR_INVALIDARGUMENT_IF(getSessionsRequest.IncludeReservations && (getSessionsRequest.XuidFilters == nullptr || getSessionsRequest.XuidFiltersCount == 0));
RETURN_HR_INVALIDARGUMENT_IF(getSessionsRequest.IncludeInactiveSessions && (getSessionsRequest.XuidFilters == nullptr || getSessionsRequest.XuidFiltersCount == 0));
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
getSessionsRequest.XuidFiltersCount > 1 ? "POST" : "GET",
@ -397,7 +406,10 @@ HRESULT MultiplayerService::SetActivity(
MultiplayerActivityHandlePostRequest request{ sessionReference };
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -439,7 +451,10 @@ HRESULT MultiplayerService::SetTransferHandle(
MultiplayerTransferHandlePostRequest request{ targetSessionReference, originSessionReference };
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -487,7 +502,10 @@ HRESULT MultiplayerService::CreateSearchHandle(
_In_ AsyncContext<Result<std::shared_ptr<XblMultiplayerSearchHandleDetails>>> async
) const noexcept
{
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -567,7 +585,13 @@ HRESULT MultiplayerService::ClearActivity(
subPath << "/handles/" << activityDetails.at(0).HandleId;
}
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
if (FAILED(userResult.Hresult()))
{
return async.Complete(userResult.Hresult());
}
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"DELETE",
@ -616,7 +640,10 @@ HRESULT MultiplayerService::DeleteSearchHandle(
String handleStr = "/handles/" + handleId;
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"DELETE",
@ -696,7 +723,10 @@ HRESULT MultiplayerService::SendInvites(
private:
HRESULT SendInvite(uint64_t xuid) noexcept
{
auto httpCall = MakeShared<XblHttpCall>(m_multiplayerService->m_user);
Result<User> userResult = m_multiplayerService->m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_multiplayerService->m_xboxLiveContextSettings,
"POST",
@ -774,7 +804,10 @@ HRESULT MultiplayerService::GetActivitiesForSocialGroup(
MultiplayerActivityQueryPostRequest request{ scid, socialGroup, socialGroupOwnerXuid };
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -833,7 +866,10 @@ HRESULT MultiplayerService::GetActivitiesForUsers(
MultiplayerActivityQueryPostRequest request{ scid, xuids };
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -888,7 +924,10 @@ HRESULT MultiplayerService::GetSearchHandles(
{
RETURN_HR_INVALIDARGUMENT_IF(searchHandleRequest.Scid().empty() || searchHandleRequest.SessionTemplateName().empty());
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -940,7 +979,10 @@ HRESULT MultiplayerService::WriteSessionUsingSubpath(
{
RETURN_HR_INVALIDARGUMENT_IF(subpathAndQuery.empty());
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"PUT",

Просмотреть файл

@ -31,7 +31,7 @@ class MultiplayerActivityService : public std::enable_shared_from_this<Multiplay
{
public:
MultiplayerActivityService(
_In_ User user,
_In_ User&& user,
_In_ const TaskQueue& queue,
_In_ std::shared_ptr<XboxLiveContextSettings> settings
) noexcept;
@ -44,7 +44,7 @@ public:
) noexcept;
HRESULT FlushRecentPlayers(
_In_ AsyncContext<HRESULT> async
_In_ AsyncContext<Result<void>>&& async
) noexcept;
HRESULT SetActivity(

Просмотреть файл

@ -18,7 +18,7 @@ namespace multiplayer_activity
constexpr auto PlatformName = EnumName<XblMultiplayerActivityPlatform, 0, static_cast<uint32_t>(XblMultiplayerActivityPlatform::All)>;
MultiplayerActivityService::MultiplayerActivityService(
_In_ User user,
_In_ User&& user,
_In_ const TaskQueue& queue,
_In_ std::shared_ptr<XboxLiveContextSettings> settings
) noexcept
@ -62,7 +62,7 @@ HRESULT MultiplayerActivityService::UpdateRecentPlayers(
}
HRESULT MultiplayerActivityService::FlushRecentPlayers(
_In_ AsyncContext<HRESULT> async
_In_ AsyncContext<Result<void>>&& async
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
@ -77,7 +77,8 @@ HRESULT MultiplayerActivityService::FlushRecentPlayers(
class ServiceCall : public XblHttpCall
{
public:
ServiceCall(User user) noexcept : XblHttpCall{ std::move(user) }
ServiceCall(User&& user) noexcept
: XblHttpCall{ std::move(user) }
{
}
@ -104,23 +105,29 @@ HRESULT MultiplayerActivityService::FlushRecentPlayers(
);
}
HRESULT Perform(
AsyncContext<HttpResult> async,
bool forceRefresh = false
) override
HRESULT PerformWithRetry(
AsyncContext<xbox::services::Result<void>>&& async
)
{
m_async = std::move(async);
return XblHttpCall::Perform({ async.Queue().DeriveWorkerQueue(), IntermediateCallback }, forceRefresh);
return XblHttpCall::Perform(AsyncContext<HttpResult>{ async.Queue().DeriveWorkerQueue(),
[async](HttpResult httpResult) mutable
{
HandleHttpResult(std::move(httpResult), std::move(async));
}
});
}
private:
static void IntermediateCallback(HttpResult result) noexcept
static void HandleHttpResult(
HttpResult result,
AsyncContext<xbox::services::Result<void>>&& async
) noexcept
{
auto sharedThis{ std::dynamic_pointer_cast<ServiceCall>(result.Payload()) };
if (Failed(result))
{
return sharedThis->m_async.Complete(result);
return async.Complete(result);
}
auto httpResult{ result.Payload()->Result() };
@ -133,29 +140,46 @@ HRESULT MultiplayerActivityService::FlushRecentPlayers(
// XblHttpCall already retries 401 so don't do it again here.
case S_OK:
{
return sharedThis->m_async.Complete(result);
return async.Complete(S_OK);
}
default:
{
// For other failures, backoff and retry
auto backoff{ __min(std::pow(2, ++sharedThis->m_iteration), 60) * 1000 };
sharedThis->m_async.Queue().RunWork([ sharedThis ]
async.Queue().RunWork([ sharedThis, async ]
{
sharedThis->ResetAndCopyForRetry();
sharedThis->XblHttpCall::Perform({ sharedThis->m_async.Queue().DeriveWorkerQueue(), IntermediateCallback });
HRESULT hr = sharedThis->ResetAndCopyForRetry();
if (FAILED(hr))
{
return async.Complete(hr);
}
hr = sharedThis->XblHttpCall::Perform(AsyncContext<HttpResult>{ async.Queue().DeriveWorkerQueue(),
[async](HttpResult httpResult) mutable
{
HandleHttpResult(std::move(httpResult), std::move(async));
}
});
if (FAILED(hr))
{
return async.Complete(hr);
}
},
backoff);
}
}
}
AsyncContext<HttpResult> m_async;
uint32_t m_iteration{ 0 };
std::shared_ptr<GlobalState> m_globalState{ nullptr };
};
auto serviceCall = MakeShared<ServiceCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto serviceCall = MakeShared<ServiceCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(serviceCall->Init(m_xboxLiveContextSettings, m_titleId));
JsonDocument requestBody{ rapidjson::kObjectType };
@ -174,18 +198,7 @@ HRESULT MultiplayerActivityService::FlushRecentPlayers(
requestBody.AddMember("recentPlayers", recentPlayers.Move(), a);
RETURN_HR_IF_FAILED(serviceCall->SetRequestBody(requestBody));
RETURN_HR_IF_FAILED(serviceCall->Perform({
async.Queue().DeriveWorkerQueue(),
[
async
]
(HttpResult httpResult)
{
HRESULT hr{ Failed(httpResult) ? httpResult.Hresult() : httpResult.Payload()->Result() };
async.Complete(hr);
}
}));
RETURN_HR_IF_FAILED(serviceCall->PerformWithRetry(std::move(async)));
m_pendingRecentPlayerUpdates.clear();
return S_OK;
@ -223,7 +236,10 @@ HRESULT MultiplayerActivityService::SetActivity(
requestBody.AddMember("platform", JsonValue{ PlatformName(GetLocalPlatform()).data(), a }, a);
}
auto httpCall{ MakeShared<XblHttpCall>(m_user) };
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"PUT",
@ -261,7 +277,10 @@ HRESULT MultiplayerActivityService::GetActivity(
JsonUtils::SerializeVector(JsonUtils::JsonXuidSerializer, xuids, userList, a);
requestBody.AddMember("users", userList.Move(), a);
auto httpCall{ MakeShared<XblHttpCall>(m_user) };
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -301,7 +320,10 @@ HRESULT MultiplayerActivityService::DeleteActivity(
requestBody.AddMember("sequenceNumber", static_cast<int64_t>(time(nullptr)), a);
auto httpCall{ MakeShared<XblHttpCall>(m_user) };
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"DELETE",
@ -353,7 +375,10 @@ HRESULT MultiplayerActivityService::SendInvites(
}
requestBody.AddMember("invitedUsers", invitedUsersArray.Move(), a);
auto httpCall{ MakeShared<XblHttpCall>(m_user) };
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -383,13 +408,13 @@ void MultiplayerActivityService::ScheduleRecentPlayersUpdate() noexcept
auto pThis{ weakThis.lock() };
if (pThis)
{
pThis->FlushRecentPlayers({ pThis->m_queue, [ pThis ] (HRESULT hr)
pThis->FlushRecentPlayers({ pThis->m_queue, [ pThis ] (Result<void> result)
{
// FlushRecentPlayers already has retry logic. If we get to this point, just log the error
// and schedule the next upload.
if (FAILED(hr))
if (Failed(result))
{
LOGS_ERROR << "MultiplayerActivity::FlushRecentPlayers failed with HRESULT " << hr;
LOGS_ERROR << "MultiplayerActivity::FlushRecentPlayers failed with HRESULT " << result.Hresult();
}
pThis->ScheduleRecentPlayersUpdate();
} });

Просмотреть файл

@ -4,9 +4,9 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_NOTIFICATION_CPP_BEGIN
#if HC_PLATFORM == HC_PLATFORM_IOS || HC_PLATFORM == HC_PLATFORM_ANDROID
MobileNotificationService::MobileNotificationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
) : NotificationService(user, contextSettings)
) : NotificationService(std::move(user), contextSettings)
{}
HRESULT MobileNotificationService::RegisterWithNotificationService(

Просмотреть файл

@ -55,11 +55,11 @@ HRESULT RTANotificationService::RTANotificationService::UnregisterForEvents(std:
}
RTANotificationService::RTANotificationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) noexcept :
NotificationService(user, contextSettings),
NotificationService(std::move(user), contextSettings),
m_rtaManager{ std::move(rtaManager) }
{
}
@ -68,9 +68,21 @@ HRESULT RTANotificationService::RegisterForSpopNotificationEvents() noexcept
{
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
m_rtaManager->Activate(m_user);
m_spopNotificationSubscription = MakeShared<SpopKickSubscription>(m_user, AppConfig::Instance()->TitleId());
RETURN_HR_IF_FAILED(m_rtaManager->AddSubscription(m_user, m_spopNotificationSubscription));
auto copiedUserResult = m_user.Copy();
RETURN_HR_IF_FAILED(copiedUserResult.Hresult());
m_rtaManager->Activate(copiedUserResult.ExtractPayload());
{
auto subscriptionUserCopyResult = m_user.Copy();
RETURN_HR_IF_FAILED(subscriptionUserCopyResult.Hresult());
m_spopNotificationSubscription = MakeShared<SpopKickSubscription>(subscriptionUserCopyResult.ExtractPayload(), AppConfig::Instance()->TitleId());
}
{
auto subscriptionUserCopyResult = m_user.Copy();
RETURN_HR_IF_FAILED(subscriptionUserCopyResult.Hresult());
RETURN_HR_IF_FAILED(m_rtaManager->AddSubscription(subscriptionUserCopyResult.ExtractPayload(), m_spopNotificationSubscription));
}
return RegisterWithNotificationService(
m_spopNotificationSubscription->ResourceUri(),
@ -153,14 +165,12 @@ HRESULT RTANotificationService::RegisterWithNotificationService(
derivedPtr->UnregisterForAchievementUnlockEvents();
}
async.Complete(hr);
return derivedPtr->m_registrationAsync.Complete(hr);
return async.Complete(hr);
}
else
{
async.Complete(E_XBL_AUTH_RUNTIME_ERROR);
return derivedPtr->m_registrationAsync.Complete(E_XBL_RUNTIME_ERROR);
return async.Complete(E_XBL_AUTH_RUNTIME_ERROR);
}
}
}

Просмотреть файл

@ -8,10 +8,10 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_NOTIFICATION_CPP_BEGIN
SpopKickSubscription::SpopKickSubscription(
_In_ User user,
_In_ User&& user,
_In_ uint32_t titleId
) noexcept :
m_user(user)
m_user(std::move(user))
{
Stringstream ss;
ss << "https://notify.xboxlive.com/users/xuid(" << m_user.Xuid() << ")/deviceId/current/titleId/" << titleId;

Просмотреть файл

@ -13,7 +13,7 @@ class SpopKickSubscription : public real_time_activity::Subscription
{
public:
SpopKickSubscription(
User user,
User&& user,
uint32_t titleId
) noexcept;
@ -24,7 +24,7 @@ protected:
void OnResync() noexcept override;
private:
User m_user{ nullptr };
User m_user;
};
NAMESPACE_MICROSOFT_XBOX_SERVICES_NOTIFICATION_CPP_END
#endif

Просмотреть файл

@ -9,10 +9,10 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_NOTIFICATION_CPP_BEGIN
UWPNotificationService::UWPNotificationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
) noexcept :
NotificationService(user, contextSettings)
NotificationService(std::move(user), contextSettings)
{
}
@ -37,7 +37,7 @@ HRESULT UWPNotificationService::RegisterWithNotificationService(
{
auto channel = asyncOp->GetResults();
channel->PushNotificationReceived += ref new Windows::Foundation::TypedEventHandler<Windows::Networking::PushNotifications::PushNotificationChannel ^, Windows::Networking::PushNotifications::PushNotificationReceivedEventArgs ^>(
[thisWeak](Windows::Networking::PushNotifications::PushNotificationChannel ^ channel, Windows::Networking::PushNotifications::PushNotificationReceivedEventArgs^ args)
[thisWeak, async](Windows::Networking::PushNotifications::PushNotificationChannel ^ channel, Windows::Networking::PushNotifications::PushNotificationReceivedEventArgs^ args)
{
try
{
@ -91,19 +91,18 @@ HRESULT UWPNotificationService::RegisterWithNotificationService(
notificationFilterList,
{
async.Queue(),
[thisWeak](HRESULT hr)
[thisWeak, async](HRESULT hr)
{
if (auto pThis{ thisWeak.lock() })
{
auto derivedPtr = dynamic_cast<UWPNotificationService*>(pThis.get());
if (SUCCEEDED(hr))
{
derivedPtr->m_registrationAsync.Complete(hr);
async.Complete(hr);
}
else
{
derivedPtr->m_registrationAsync.Complete(E_XBL_RUNTIME_ERROR);
LOG_ERROR("Failed to successfully register with notification service");
async.Complete(E_XBL_RUNTIME_ERROR);
}
}
}

Просмотреть файл

@ -43,7 +43,7 @@ public:
} m_registrationStatus;
NotificationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings);
virtual ~NotificationService() = default;
@ -57,7 +57,6 @@ public:
_In_ AsyncContext<HRESULT> async);
protected:
AsyncContext<HRESULT> m_registrationAsync;
AsyncContext<HRESULT> m_unregistrationAsync;
@ -89,7 +88,7 @@ class MobileNotificationService : public NotificationService
{
public:
MobileNotificationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings);
HRESULT RegisterWithNotificationService(
@ -169,7 +168,7 @@ class RTANotificationService : public NotificationService
{
public:
RTANotificationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) noexcept;
@ -238,7 +237,7 @@ class UWPNotificationService : public NotificationService
{
public:
UWPNotificationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
) noexcept;

Просмотреть файл

@ -17,10 +17,10 @@ static const int32_t NUM_RETRY_TIMES = 10;
NAMESPACE_MICROSOFT_XBOX_SERVICES_NOTIFICATION_CPP_BEGIN
NotificationService::NotificationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
) :
m_user(user),
m_user(std::move(user)),
m_contextSettings(contextSettings)
{}
@ -69,7 +69,10 @@ HRESULT NotificationService::UnregisterFromNotificationHelper(
{
auto subpath = "/system/notifications/endpoints/" + endpointId;
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_contextSettings,
"DELETE",
@ -156,6 +159,7 @@ HRESULT NotificationService::RegisterForNotificationsHelper(
}
default:
{
m_registrationAsync = AsyncContext<HRESULT>::Collapse({ std::move(m_registrationAsync), std::move(async) });
m_registrationStatus = RegistrationStatus::Registering;
xsapi_internal_stringstream str;
@ -198,7 +202,10 @@ HRESULT NotificationService::RegisterForNotificationsHelper(
}
payload.AddMember("filters", filterJson, allocator);
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_contextSettings,
"POST",
@ -236,7 +243,7 @@ HRESULT NotificationService::RegisterForNotificationsHelper(
case RegistrationStatus::Registering:
{
pThis->m_registrationStatus = RegistrationStatus::Registered;
async.Complete(hr);
pThis->m_registrationAsync.Complete(hr);
break;
}
default:
@ -250,7 +257,7 @@ HRESULT NotificationService::RegisterForNotificationsHelper(
{
// Registration failed for some reason
pThis->m_registrationStatus = RegistrationStatus::Unregistered;
async.Complete(E_XBL_RUNTIME_ERROR);
pThis->m_registrationAsync.Complete(E_XBL_RUNTIME_ERROR);
}
}
}

Просмотреть файл

@ -138,7 +138,7 @@ class PresenceService : public std::enable_shared_from_this<PresenceService>
{
public:
PresenceService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) noexcept;

Просмотреть файл

@ -12,7 +12,7 @@ using namespace xbox::services::real_time_activity;
NAMESPACE_MICROSOFT_XBOX_SERVICES_PRESENCE_CPP_BEGIN
PresenceService::PresenceService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) noexcept
@ -268,10 +268,14 @@ HRESULT PresenceService::SetPresence(
_In_ AsyncContext<HRESULT> async
) const noexcept
{
Stringstream subpath;
subpath << "/users/xuid(" << m_user.Xuid() << ")/devices/current/titles/current";
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -324,7 +328,10 @@ HRESULT PresenceService::GetPresence(
Stringstream subpath;
subpath << "/users/xuid(" << xuid << ")?level=all";
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"GET",
@ -355,7 +362,10 @@ HRESULT PresenceService::GetBatchPresence(
_In_ AsyncContext<Result<xsapi_internal_vector<std::shared_ptr<XblPresenceRecord>>>> async
) const noexcept
{
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",

Просмотреть файл

@ -14,7 +14,7 @@ constexpr auto XblPermissionName = EnumName<XblPermission, 1000, 1025>;
NAMESPACE_MICROSOFT_XBOX_SERVICES_PRIVACY_CPP_BEGIN
PrivacyService::PrivacyService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
) noexcept :
m_user{ std::move(user) },
@ -44,7 +44,10 @@ HRESULT PrivacyService::GetUserList(
xsapi_internal_stringstream path;
path << "/users/xuid(" << m_user.Xuid() << ")/people/" << (listType == PrivacyListType::Mute ? "mute" : "avoid");
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_contextSettings,
"GET",
@ -126,7 +129,10 @@ HRESULT PrivacyService::CheckPermission(
subPathBuilder.append_query(_T("setting"), StringTFromUtf8(XblPermissionName(permission).data()));
subPathBuilder.append_query(_T("target"), StringTFromUtf8(targetQuery.data()));
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_contextSettings,
"GET",
@ -208,7 +214,10 @@ HRESULT PrivacyService::BatchCheckPermission(
requestBody.AddMember("permissions", permissionsJson, allocator);
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_contextSettings,
"POST",

Просмотреть файл

@ -36,7 +36,7 @@ class PrivacyService : public std::enable_shared_from_this<PrivacyService>
{
public:
PrivacyService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
) noexcept;

Просмотреть файл

@ -74,7 +74,7 @@ HRESULT ConvertRTAErrorCode(ErrorCode rtaErrorCode) noexcept
}
Connection::Connection(
User user,
User&& user,
const TaskQueue& queue,
ConnectionStateChangedHandler stateChangedHandler,
real_time_activity::ResyncHandler resyncHandler
@ -101,8 +101,8 @@ Connection::~Connection() noexcept
#endif
}
std::shared_ptr<Connection> Connection::Make(
User user,
Result<std::shared_ptr<Connection>> Connection::Make(
User&& user,
const TaskQueue& queue,
ConnectionStateChangedHandler stateChangedHandler,
real_time_activity::ResyncHandler resyncHandler
@ -119,7 +119,12 @@ std::shared_ptr<Connection> Connection::Make(
Deleter<Connection>()
);
rtaConnection->InitializeWebsocket();
auto hr = rtaConnection->InitializeWebsocket();
if (FAILED(hr))
{
return hr;
}
rtaConnection->m_stateChangedHandler(rtaConnection->m_state);
rtaConnection->m_websocket->Connect(s_rtaUri, s_rtaSubprotocol);
@ -625,7 +630,11 @@ void Connection::ConnectCompleteHandler(WebsocketResult result) noexcept
//libHttpClient websocket does not support connecting
// the same websocket handle multiple times, so create a new one.
InitializeWebsocket();
auto hr = InitializeWebsocket();
if (FAILED(hr))
{
return;
}
// Backoff and attempt to connect again.
m_connectAttempt++;
@ -658,7 +667,11 @@ void Connection::Reconnect() noexcept
// Immediately attempt to reconnect. libHttpClient websocket does not support connecting
// the same websocket handle multiple times, so create a new one.
InitializeWebsocket();
auto hr = InitializeWebsocket();
if (FAILED(hr))
{
return;
}
m_connectAttempt = 0;
m_state = XblRealTimeActivityConnectionState::Connecting;
@ -805,7 +818,7 @@ void Connection::WebsocketMessageReceived(const String& message) noexcept
}
}
void Connection::InitializeWebsocket() noexcept
HRESULT Connection::InitializeWebsocket() noexcept
{
if (m_websocket)
{
@ -814,7 +827,10 @@ void Connection::InitializeWebsocket() noexcept
m_websocket->SetReceiveHandler([](String) {});
}
m_websocket = IWebsocket::Make(m_user, m_queue);
auto copyUserResult = m_user.Copy();
RETURN_HR_IF_FAILED(copyUserResult.Hresult());
m_websocket = IWebsocket::Make(copyUserResult.ExtractPayload(), m_queue);
std::weak_ptr<Connection> thisWeakPtr{ shared_from_this() };
@ -844,6 +860,8 @@ void Connection::InitializeWebsocket() noexcept
sharedThis->WebsocketMessageReceived(message);
}
});
return S_OK;
}
NAMESPACE_MICROSOFT_XBOX_SERVICES_RTA_CPP_END

Просмотреть файл

@ -11,8 +11,8 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_RTA_CPP_BEGIN
class Connection : public std::enable_shared_from_this<Connection>
{
public:
static std::shared_ptr<Connection> Make(
User user,
static Result<std::shared_ptr<Connection>> Make(
User&& user,
const TaskQueue& queue,
ConnectionStateChangedHandler stateChangedHandler,
ResyncHandler resyncHandler
@ -43,7 +43,7 @@ public:
private:
Connection(
User user,
User&& user,
const TaskQueue& queue,
ConnectionStateChangedHandler stateChangedHandler,
ResyncHandler resyncHandler
@ -67,7 +67,7 @@ private:
void ConnectCompleteHandler(WebsocketResult result) noexcept;
void DisconnectHandler(WebSocketCloseStatus result) noexcept;
void WebsocketMessageReceived(const String& message) noexcept;
void InitializeWebsocket() noexcept;
HRESULT InitializeWebsocket() noexcept;
void Reconnect() noexcept;
User m_user;

Просмотреть файл

@ -45,8 +45,9 @@ HRESULT RealTimeActivityManager::AddSubscription(
RETURN_HR_INVALIDARGUMENT_IF_NULL(subscription);
std::lock_guard<std::recursive_mutex> lock{ m_lock };
auto connection{ GetConnection(user) };
return connection->AddSubscription(subscription, AsyncContext<Result<void>>{ m_queue });
auto connectionResult{ GetConnection(user) };
RETURN_HR_IF_FAILED(connectionResult.Hresult());
return connectionResult.ExtractPayload()->AddSubscription(subscription, AsyncContext<Result<void>>{ m_queue });
}
HRESULT RealTimeActivityManager::RemoveSubscription(
@ -186,7 +187,7 @@ void RealTimeActivityManager::Deactivate(
}
}
std::shared_ptr<Connection> RealTimeActivityManager::GetConnection(
Result<std::shared_ptr<Connection>> RealTimeActivityManager::GetConnection(
const User& user
) noexcept
{
@ -239,7 +240,19 @@ std::shared_ptr<Connection> RealTimeActivityManager::GetConnection(
}
};
connection = Connection::Make(user, m_queue, std::move(stateChangedHandler), std::move(resyncHandler));
auto copyUserResult{ user.Copy() };
if (Failed(copyUserResult))
{
return copyUserResult.Hresult();
}
auto connectionResult = Connection::Make(copyUserResult.ExtractPayload(), m_queue, std::move(stateChangedHandler), std::move(resyncHandler));
if (Failed(connectionResult))
{
return connectionResult.Hresult();
}
connection = connectionResult.ExtractPayload();
m_rtaConnections[user.Xuid()] = connection;
}

Просмотреть файл

@ -62,7 +62,7 @@ public:
) noexcept;
private:
std::shared_ptr<class Connection> GetConnection(
Result<std::shared_ptr<class Connection>> GetConnection(
const User& user
) noexcept;

Просмотреть файл

@ -8,7 +8,7 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_SOCIAL_MANAGER_CPP_BEGIN
PeoplehubService::PeoplehubService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> httpCallSettings,
_In_ uint32_t titleId
) noexcept :
@ -88,7 +88,10 @@ HRESULT PeoplehubService::MakeServiceCall(
}
}
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_httpSettings,
relationshipType == RelationshipType::Batch ? "POST" : "GET",

Просмотреть файл

@ -11,7 +11,7 @@ class PeoplehubService
{
public:
PeoplehubService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> httpCallSettings,
_In_ uint32_t titleId
) noexcept;

Просмотреть файл

@ -82,21 +82,29 @@ private:
/// -----------------------------------------------------------------------------------------------
SocialGraph::SocialGraph(
_In_ const User& localUser,
_In_ User&& localUser,
_In_ const TaskQueue& queue,
_In_ std::shared_ptr<real_time_activity::RealTimeActivityManager> rtaManager
) noexcept :
m_user{ MakeShared<User>(localUser) },
) noexcept :
m_user{ std::make_shared<User>(std::move(localUser))},
m_queue{ queue.DeriveWorkerQueue() },
m_rtaManager{ std::move(rtaManager) }
{
assert(m_user);
}
m_xblContext = MakeShared<XblContext>(localUser);
m_xblContext->Initialize(m_rtaManager);
HRESULT SocialGraph::Initialize() noexcept
{
// Maintain legacy RTA activation count.
m_rtaManager->Activate(*m_user);
auto copiedUser = m_user->Copy();
RETURN_HR_IF_FAILED(copiedUser.Hresult());
m_xblContext = XblContext::Make(copiedUser.ExtractPayload());
RETURN_HR_IF_FAILED(m_xblContext->Initialize(m_rtaManager));
return S_OK;
}
SocialGraph::~SocialGraph()
@ -124,17 +132,30 @@ SocialGraph::~SocialGraph()
m_rtaManager->Deactivate(*m_user);
}
std::shared_ptr<SocialGraph> SocialGraph::Make(
_In_ const User& user,
Result<std::shared_ptr<SocialGraph>> SocialGraph::Make(
_In_ User&& user,
_In_ const XblSocialManagerExtraDetailLevel detailLevel,
_In_ const TaskQueue& queue,
_In_ std::shared_ptr<real_time_activity::RealTimeActivityManager> rtaManager
) noexcept
{
auto graph = std::shared_ptr<SocialGraph>(new (Alloc(sizeof(SocialGraph))) SocialGraph{ user, queue, rtaManager });
Result<xbox::services::User> userResult = user.Copy();
if (userResult.Hresult())
{
return userResult.Hresult();
}
auto graph = std::shared_ptr<SocialGraph>(new (Alloc(sizeof(SocialGraph))) SocialGraph{ userResult.ExtractPayload(), queue, rtaManager });
auto hr = graph->Initialize();
if (FAILED(hr))
{
return hr;
}
std::weak_ptr<SocialGraph> weakGraph{ graph };
auto peoplehubService = MakeShared<PeoplehubService>(user, graph->m_xblContext->Settings(), AppConfig::Instance()->TitleId());
auto peoplehubService = MakeShared<PeoplehubService>(std::move(user), graph->m_xblContext->Settings(), AppConfig::Instance()->TitleId());
auto presenceService = graph->m_xblContext->PresenceService();
auto peoplehubResultHandler = [weakGraph](Vector<XblSocialManagerUser>&& profiles)

Просмотреть файл

@ -49,8 +49,8 @@ struct TrackedUser
class SocialGraph : public std::enable_shared_from_this<SocialGraph>
{
public:
static std::shared_ptr<SocialGraph> Make(
_In_ const User& localUser,
static Result<std::shared_ptr<SocialGraph>> Make(
_In_ User&& localUser,
_In_ const XblSocialManagerExtraDetailLevel detailLevel,
_In_ const TaskQueue& queue,
_In_ std::shared_ptr<real_time_activity::RealTimeActivityManager> rtaManager
@ -88,9 +88,10 @@ public:
// runs it immediately.
void SetRichPresencePolling(bool enabled) noexcept;
HRESULT Initialize() noexcept;
private:
SocialGraph(
_In_ const User& localUser,
_In_ User&& localUser,
_In_ const TaskQueue& queue,
_In_ std::shared_ptr<real_time_activity::RealTimeActivityManager> rtaManager
) noexcept;
@ -138,7 +139,7 @@ private:
std::shared_ptr<XblPresenceRecord> presenceRecord
) noexcept;
std::shared_ptr<User> const m_user;
std::shared_ptr<User> m_user;
TaskQueue const m_queue;
// Graph state

Просмотреть файл

@ -18,27 +18,24 @@ SocialManager::SocialManager() noexcept
}
HRESULT SocialManager::AddLocalUser(
const User& user,
User&& user,
XblSocialManagerExtraDetailLevel detailLevel,
TaskQueue&& queue
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
auto xuid = user.Xuid();
if (xuid == 0)
{
LOGS_ERROR << "User being added is currently unavailable. Probably due to the title still being in suspended state. Try again later";
return user.GetConstructorHR();
}
auto xuid{ user.Xuid() };
if (m_graphs.find(xuid) != m_graphs.end())
{
LOGS_ERROR << "User " << xuid << " already added to SocialManager";
return E_UNEXPECTED;
}
m_graphs[xuid] = SocialGraph::Make(user, detailLevel, queue, GlobalState::Get()->RTAManager());
auto socialGraph = SocialGraph::Make(std::move(user), detailLevel, queue, GlobalState::Get()->RTAManager());
RETURN_HR_IF_FAILED(socialGraph.Hresult());
m_graphs[xuid] = socialGraph.ExtractPayload();
return S_OK;
}
@ -51,12 +48,6 @@ HRESULT SocialManager::RemoveLocalUser(
std::lock_guard<std::mutex> lock{ m_mutex };
auto xuid = user.Xuid();
if (xuid == 0)
{
LOGS_ERROR << "User being removed is currently unavailable. Probably due to the title still being in suspended state. Try again later";
return user.GetConstructorHR();
}
auto graphIter{ m_graphs.find(xuid) };
if (graphIter == m_graphs.end())
{
@ -110,12 +101,6 @@ Result<std::shared_ptr<XblSocialManagerUserGroup>> SocialManager::CreateUserGrou
Vector<uint64_t>&& trackedUsers
) noexcept
{
if (user.Handle() == nullptr)
{
LOGS_ERROR << "User being added is currently unavailable. Probably because the title is still in suspended mode. Try again later";
return user.GetConstructorHR();
}
std::lock_guard<std::mutex> lock{ m_mutex };
auto graphIter = m_graphs.find(user.Xuid());

Просмотреть файл

@ -191,7 +191,10 @@ try
return ApiImpl([&](SocialManager& socialManager)
{
RETURN_HR_INVALIDARGUMENT_IF(user == nullptr);
return socialManager.AddLocalUser(user, extraLevelDetail, TaskQueue::DeriveWorkerQueue(queue));
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
return socialManager.AddLocalUser(wrapUserResult.ExtractPayload(), extraLevelDetail, TaskQueue::DeriveWorkerQueue(queue));
});
}
CATCH_RETURN()
@ -204,7 +207,10 @@ try
return ApiImpl([&](SocialManager& socialManager)
{
RETURN_HR_INVALIDARGUMENT_IF_NULL(user);
return socialManager.RemoveLocalUser(user);
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
return socialManager.RemoveLocalUser(wrapUserResult.Payload());
});
}
CATCH_RETURN()
@ -243,8 +249,10 @@ try
return ApiImpl([&](SocialManager& socialManager)
{
RETURN_HR_INVALIDARGUMENT_IF(user == nullptr || group == nullptr);
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
auto result = socialManager.CreateUserGroup(user, presenceFilter, relationshipFilter);
auto result = socialManager.CreateUserGroup(wrapUserResult.Payload(), presenceFilter, relationshipFilter);
if (Succeeded(result))
{
*group = result.ExtractPayload().get();
@ -267,8 +275,10 @@ try
return ApiImpl([&](SocialManager& socialManager)
{
RETURN_HR_INVALIDARGUMENT_IF(user == nullptr || xuids == nullptr || xuidsCount <= 0 || xuidsCount > XBL_SOCIAL_MANAGER_MAX_USERS_FROM_LIST || group == nullptr);
auto result = socialManager.CreateUserGroup(user, xsapi_internal_vector<uint64_t>(xuids, xuids + xuidsCount));
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
auto result = socialManager.CreateUserGroup(wrapUserResult.Payload(), Vector<uint64_t>(xuids, xuids + xuidsCount));
if (Succeeded(result))
{
*group = result.ExtractPayload().get();
@ -334,8 +344,9 @@ try
{
return ApiImpl([&](SocialManager& socialManager)
{
RETURN_HR_INVALIDARGUMENT_IF_NULL(user);
return socialManager.SetRichPresencePolling(user, shouldEnablePolling);
auto wrapUserResult{ User::WrapHandle(user) };
RETURN_HR_IF_FAILED(wrapUserResult.Hresult());
return socialManager.SetRichPresencePolling(wrapUserResult.Payload(), shouldEnablePolling);
});
}
CATCH_RETURN()

Просмотреть файл

@ -13,7 +13,7 @@ public:
SocialManager() noexcept;
HRESULT AddLocalUser(
const User& user,
User&& user,
XblSocialManagerExtraDetailLevel detailLevel,
TaskQueue&& queue
) noexcept;

Просмотреть файл

@ -11,7 +11,7 @@ class ProfileService : public std::enable_shared_from_this<ProfileService>
{
public:
ProfileService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<AppConfig> appConfig
) noexcept;

Просмотреть файл

@ -21,7 +21,7 @@ static const char* s_settings[] = {
};
ProfileService::ProfileService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<AppConfig> appConfig
) noexcept :
@ -36,7 +36,10 @@ HRESULT ProfileService::GetUserProfiles(
_In_ AsyncContext<Result<xsapi_internal_vector<XblUserProfile>>> async
) const noexcept
{
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -95,7 +98,10 @@ HRESULT ProfileService::GetUserProfilesForSocialGroup(
pathAndQuery << s_settings[i];
}
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"GET",

Просмотреть файл

@ -7,7 +7,7 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_SOCIAL_CPP_BEGIN
ReputationService::ReputationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings
) noexcept :
m_user{ std::move(user) },
@ -20,7 +20,10 @@ HRESULT ReputationService::SubmitFeedback(
AsyncContext<HRESULT> async
) const noexcept
{
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",

Просмотреть файл

@ -76,7 +76,7 @@ class SocialService : public std::enable_shared_from_this<SocialService>
{
public:
SocialService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) noexcept;
@ -147,7 +147,7 @@ class ReputationService : public std::enable_shared_from_this<ReputationService>
{
public:
ReputationService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings
) noexcept;

Просмотреть файл

@ -8,7 +8,7 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_SOCIAL_CPP_BEGIN
SocialService::SocialService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) noexcept :
@ -97,7 +97,10 @@ HRESULT SocialService::GetSocialRelationships(
nextDelimiter = "&";
}
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"GET",

Просмотреть файл

@ -41,7 +41,7 @@ class TitleManagedStatisticsService: public std::enable_shared_from_this<TitleMa
{
public:
TitleManagedStatisticsService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings
) noexcept;

Просмотреть файл

@ -7,7 +7,7 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_USERSTATISTICS_CPP_BEGIN
TitleManagedStatisticsService::TitleManagedStatisticsService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings
) noexcept :
m_user{ std::move(user) },
@ -30,7 +30,10 @@ HRESULT TitleManagedStatisticsService::WriteTitleManagedStatisticsAsync(
request.AddMember("revision", GetRevisionFromClock(), allocator);
request.AddMember("timestamp", JsonValue(utils::internal_string_from_string_t(xbox::services::datetime::utc_now().to_string(xbox::services::datetime::date_format::ISO_8601)).c_str(), allocator).Move(), allocator);
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",
@ -58,7 +61,10 @@ HRESULT TitleManagedStatisticsService::UpdateTitleManagedStatistics(
_In_ AsyncContext<HRESULT> async
) const noexcept
{
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"PATCH",

Просмотреть файл

@ -163,7 +163,7 @@ class UserStatisticsService : public std::enable_shared_from_this<UserStatistics
{
public:
UserStatisticsService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) noexcept;

Просмотреть файл

@ -11,7 +11,7 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_USERSTATISTICS_CPP_BEGIN
UserStatisticsService::UserStatisticsService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings,
_In_ std::shared_ptr<xbox::services::real_time_activity::RealTimeActivityManager> rtaManager
) noexcept :
@ -54,7 +54,10 @@ HRESULT UserStatisticsService::GetSingleUserStatistics(
{
RETURN_HR_INVALIDARGUMENT_IF(scid.empty());
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"GET",
@ -165,7 +168,10 @@ HRESULT UserStatisticsService::GetMultipleUserStatisticsForMultipleServiceConfig
rootJson.AddMember("requestedscids", requestedscidsJson, allocator);
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
RETURN_HR_IF_FAILED(httpCall->Init(
m_xboxLiveContextSettings,
"POST",

Просмотреть файл

@ -14,7 +14,7 @@ using namespace xbox::services::system;
NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_BEGIN
StringService::StringService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
) :
m_user{ std::move(user) },
@ -40,7 +40,10 @@ HRESULT StringService::VerifyStrings(
request.AddMember("stringsToVerify", stringsJson, request.GetAllocator());
xsapi_internal_vector<VerifyStringResult> result;
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_contextSettings,
"POST",

Просмотреть файл

@ -38,7 +38,7 @@ class StringService : public std::enable_shared_from_this<StringService>
public:
StringService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> contextSettings
);

Просмотреть файл

@ -56,7 +56,7 @@ class TitleStorageService : public std::enable_shared_from_this<TitleStorageServ
{
public:
TitleStorageService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings
);

Просмотреть файл

@ -16,7 +16,7 @@ const char E_TAG_INVALID_VALUE[] = "InvalidETagValue";
const char RANGE_HEADER_NAME[] = "Range";
TitleStorageService::TitleStorageService(
_In_ User user,
_In_ User&& user,
_In_ std::shared_ptr<xbox::services::XboxLiveContextSettings> xboxLiveContextSettings
) :
m_user{ std::move(user) },
@ -36,7 +36,10 @@ TitleStorageService::GetQuota(
auto subpath = TitleStorageQuotaSubpath(storageType, scid, m_user.Xuid());
RETURN_HR_INVALIDARGUMENT_IF(!Succeeded(subpath));
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"GET",
@ -138,7 +141,10 @@ TitleStorageService::GetBlobMetadata(
RETURN_HR_INVALIDARGUMENT_IF(!Succeeded(subpath));
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"GET",
@ -200,7 +206,10 @@ TitleStorageService::DeleteBlob(
XblTitleStorageETagMatchCondition::IfMatch :
XblTitleStorageETagMatchCondition::NotUsed;
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"DELETE",
@ -287,7 +296,10 @@ HRESULT TitleStorageService::DownloadBlobHelper(
RETURN_HR_INVALIDARGUMENT_IF(!Succeeded(subpath));
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"GET",
@ -438,7 +450,10 @@ TitleStorageService::UploadBlobHelper(
Result<xsapi_internal_string> subpath = TitleStorageUploadBlobSubpath(args->blobMetadata, continuationToken, finalBlock);
RETURN_HR_INVALIDARGUMENT_IF(!Succeeded(subpath));
auto httpCall = MakeShared<XblHttpCall>(m_user);
Result<User> userResult = m_user.Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(
m_xboxLiveContextSettings,
"PUT",

Просмотреть файл

@ -9,4 +9,4 @@
//*********************************************************
#pragma once
#define XBOX_SERVICES_API_VERSION_STRING "2020.11.20201117.0"
#define XBOX_SERVICES_API_VERSION_STRING "2020.11.20210116.1"

Просмотреть файл

@ -19,7 +19,10 @@ STDAPI XblHttpCallCreate(
{
VERIFY_XBL_INITIALIZED();
auto httpCall = MakeShared<XblHttpCall>(xblContext->User());
auto userResult = xblContext->User().Copy();
RETURN_HR_IF_FAILED(userResult.Hresult());
auto httpCall = MakeShared<XblHttpCall>(userResult.ExtractPayload());
HRESULT hr = httpCall->Init(xblContext->Settings(), method, url, xbox_live_api::unspecified);
if (SUCCEEDED(hr))
{

Просмотреть файл

@ -521,7 +521,7 @@ void XblHttpCall::SetLongHttpCall(_In_ bool longHttpCall)
m_longHttpCall = longHttpCall;
}
XblHttpCall::XblHttpCall(User user)
XblHttpCall::XblHttpCall(_In_ User&& user)
: m_user{ std::move(user) }
{
}

Просмотреть файл

@ -209,7 +209,7 @@ using namespace xbox::services;
struct XblHttpCall : public HttpCall
{
public:
XblHttpCall(User user);
XblHttpCall(User&& user);
virtual HRESULT Init(
_In_ std::shared_ptr<XboxLiveContextSettings> contextSettings,

Просмотреть файл

@ -15,7 +15,11 @@ class Result
{
public:
Result() = default;
Result(const Result<T>&) = default;
Result(const Result&) = default;
Result(Result&& other) = default;
~Result() = default;
Result& operator=(const Result& rhs) = default;
Result(HRESULT hr, String errorMessage = {}) : m_result{ hr }, m_errorMessage{ std::move(errorMessage) } {}

Просмотреть файл

@ -7,38 +7,40 @@
NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN
User::User(XblUserHandle userHandle) noexcept
{
auto hr = XalUserDuplicateHandle(userHandle, &m_handle);
if (FAILED(hr))
{
m_handle = nullptr;
m_constructorHR = hr;
LOGS_ERROR << "User being used is currently unavailable. Probably because the title is still in suspended mode. Try again later";
}
}
User::User(const User& other) noexcept
{
auto hr = XalUserDuplicateHandle(other.m_handle, &m_handle);
if (FAILED(hr))
{
m_handle = nullptr;
m_constructorHR = hr;
LOGS_ERROR << "User being used is currently unavailable. Probably because the title is still in suspended mode. Try again later";
}
}
: m_handle(userHandle)
{}
User::User(User&& other) noexcept
: m_handle{ other.m_handle }
: m_handle{ other.m_handle }, m_localId { std::move(other.m_localId) }, m_xuid {other.m_xuid }
{
Map<XalGamertagComponent, String>::iterator it = other.m_gamertags.begin();
while(it != other.m_gamertags.end())
{
m_gamertags[it->first] = std::move(it->second);
it++;
}
other.m_gamertags.clear();
other.m_handle = nullptr;
m_constructorHR = other.m_constructorHR;
}
User& User::operator=(User other) noexcept
User& User::operator=(User&& other) noexcept
{
std::swap(other.m_handle, m_handle);
m_constructorHR = other.m_constructorHR;
m_localId = std::move(other.m_localId);
m_xuid = other.m_xuid;
Map<XalGamertagComponent, String>::iterator it = other.m_gamertags.begin();
while (it != other.m_gamertags.end())
{
m_gamertags[it->first] = std::move(it->second);
it++;
}
other.m_gamertags.clear();
return *this;
}
@ -50,17 +52,111 @@ User::~User() noexcept
}
}
uint64_t User::Xuid() const noexcept
/*static*/ Result<User> User::WrapHandle(XblUserHandle userHandle) noexcept
{
uint64_t xuid{ 0 };
if (m_handle != nullptr)
if (userHandle == nullptr)
{
auto hr = XalUserGetId(m_handle, &xuid);
UNREFERENCED_PARAMETER(hr);
return Result<User>{ User(nullptr), E_INVALIDARG };
}
return xuid;
XalUserHandle copiedHandle;
auto hr = XalUserDuplicateHandle(userHandle, &copiedHandle);
if (FAILED(hr))
{
LOGS_ERROR << "Copying user failed: User failed to duplicate.";
return Result<User>{ User(nullptr), hr };
}
else
{
User user{ copiedHandle };
hr = user.InitializeUser();
if (FAILED(hr))
{
LOGS_ERROR << "Copying user failed: User failed to duplicate.";
return Result<User>{ User(nullptr), hr };
}
return Result<User>{ std::move(user) , S_OK };
}
}
HRESULT User::InitializeUser() noexcept
{
auto hr = XalUserGetId(m_handle, &m_xuid);
if (FAILED(hr))
{
LOGS_ERROR << "Failed to get User ID with HRESULT: " << hr;
return hr;
}
hr = XalUserGetLocalId(m_handle, &m_localId);
if (FAILED(hr))
{
LOGS_ERROR << "Failed to get User LocalID with HRESULT: " << hr;
return hr;
}
auto gamertagComponentResult = GetGamertagComponent(XalGamertagComponent_Classic);
if (FAILED(gamertagComponentResult.Hresult()))
{
LOGS_ERROR << "Failed to get Gamertag Component" << XalGamertagComponent_Classic << " with HRESULT: " << hr;
return hr;
}
m_gamertags[XalGamertagComponent_Classic] = gamertagComponentResult.ExtractPayload();
gamertagComponentResult = GetGamertagComponent(XalGamertagComponent_Modern);
if (FAILED(gamertagComponentResult.Hresult()))
{
LOGS_ERROR << "Failed to get Gamertag Component" << XalGamertagComponent_Modern << " with HRESULT: " << hr;
return hr;
}
m_gamertags[XalGamertagComponent_Modern] = gamertagComponentResult.ExtractPayload();
gamertagComponentResult = GetGamertagComponent(XalGamertagComponent_ModernSuffix);
if (FAILED(gamertagComponentResult.Hresult()))
{
LOGS_ERROR << "Failed to get Gamertag Component" << XalGamertagComponent_ModernSuffix << " with HRESULT: " << hr;
return hr;
}
m_gamertags[XalGamertagComponent_ModernSuffix] = gamertagComponentResult.ExtractPayload();
gamertagComponentResult = GetGamertagComponent(XalGamertagComponent_UniqueModern);
if (FAILED(gamertagComponentResult.Hresult()))
{
LOGS_ERROR << "Failed to get Gamertag Component" << XalGamertagComponent_UniqueModern << " with HRESULT: " << hr;
return hr;
}
m_gamertags[XalGamertagComponent_UniqueModern] = gamertagComponentResult.ExtractPayload();
return S_OK;
}
Result<User> User::Copy() const noexcept
{
XalUserHandle copiedHandle;
auto hr = XalUserDuplicateHandle(this->m_handle, &copiedHandle);
if (FAILED(hr))
{
LOGS_ERROR << "Copying user failed: User failed to duplicate.";
return Result<User>{ User(nullptr), hr};
}
else
{
User copiedUser{ copiedHandle };
hr = copiedUser.InitializeUser();
return Result<User>{std::move(copiedUser), hr};
}
}
uint64_t User::Xuid() const noexcept
{
return m_xuid;
}
uint64_t User::LocalId() const noexcept
@ -69,46 +165,77 @@ uint64_t User::LocalId() const noexcept
if (m_handle != nullptr)
{
auto hr = XalUserGetLocalId(m_handle, &localId);
UNREFERENCED_PARAMETER(hr);
if (SUCCEEDED(hr))
{
m_localId = localId;
}
}
return localId.value;
return m_localId.value;
}
xsapi_internal_string User::Gamertag() const noexcept
{
return GetGamertagComponent(XalGamertagComponent_Classic);
auto result = GetGamertagComponent(XalGamertagComponent_Classic);
if (Failed(result))
{
return m_gamertags[XalGamertagComponent_Classic];
}
else
{
return result.ExtractPayload();
}
}
xsapi_internal_string User::ModernGamertag() const noexcept
{
return GetGamertagComponent(XalGamertagComponent_Modern);
auto result = GetGamertagComponent(XalGamertagComponent_Modern);
if (Failed(result))
{
return m_gamertags[XalGamertagComponent_Modern];
}
else
{
return result.ExtractPayload();
}
}
xsapi_internal_string User::ModernGamertagSuffix() const noexcept
{
return GetGamertagComponent(XalGamertagComponent_ModernSuffix);
auto result = GetGamertagComponent(XalGamertagComponent_ModernSuffix);
if (Failed(result))
{
return m_gamertags[XalGamertagComponent_ModernSuffix];
}
else
{
return result.ExtractPayload();
}
}
xsapi_internal_string User::UniqueModernGamertag() const noexcept
{
return GetGamertagComponent(XalGamertagComponent_UniqueModern);
auto result = GetGamertagComponent(XalGamertagComponent_UniqueModern);
if (Failed(result))
{
return m_gamertags[XalGamertagComponent_UniqueModern];
}
else
{
return result.ExtractPayload();
}
}
HRESULT User::GetTokenAndSignature(
const xsapi_internal_string& httpMethod,
const xsapi_internal_string& url,
const String& httpMethod,
const String& url,
const HttpHeaders& headers,
const uint8_t* requestBody,
size_t requestBodySize,
bool allUsers,
AsyncContext<Result<TokenAndSignature>> async
AsyncContext<Result<TokenAndSignature>>&& async
) noexcept
{
if (!m_handle)
{
return m_constructorHR;
}
bool forceRefresh{ false };
auto state{ GlobalState::Get() };
@ -131,7 +258,7 @@ HRESULT User::GetTokenAndSignature(
allUsers
};
xsapi_internal_vector<XalHttpHeader> xalHttpHeaders{};
Vector<XalHttpHeader> xalHttpHeaders{};
if (headers.size() > 0)
{
xalHttpHeaders.reserve(tokenAndSigArgs.headerCount);
@ -161,10 +288,11 @@ HRESULT User::GetTokenAndSignature(
XalUserGetTokenAndSignatureData* xalTokenSignatureData{ nullptr };
hr = XalUserGetTokenAndSignatureSilentlyResult(asyncBlock, bufferSize, buffer, &xalTokenSignatureData, nullptr);
assert(SUCCEEDED(hr));
payload.token = xsapi_internal_string{ xalTokenSignatureData->token, xalTokenSignatureData->tokenSize };
payload.signature = xsapi_internal_string{ xalTokenSignatureData->signature, xalTokenSignatureData->signatureSize };
if (SUCCEEDED(hr))
{
payload.token = String{ xalTokenSignatureData->token, xalTokenSignatureData->tokenSize };
payload.signature = String{ xalTokenSignatureData->signature, xalTokenSignatureData->signatureSize };
}
DeleteArray(buffer, bufferSize);
}
@ -187,11 +315,6 @@ HRESULT User::GetTokenAndSignature(
);
}
HRESULT User::GetConstructorHR() const noexcept
{
return m_constructorHR;
}
XalUserHandle User::Handle() const noexcept
{
return m_handle;
@ -204,7 +327,7 @@ void User::SetTokenExpired(uint64_t xuid) noexcept
{
state->InsertUserExpiredToken(xuid);
}
}
Result<XblFunctionContext> User::RegisterChangeEventHandler(
@ -220,7 +343,7 @@ Result<XblFunctionContext> User::RegisterChangeEventHandler(
[](void* context, UserLocalId userId, UserChangeType change)
{
auto handler{ static_cast<UserChangeEventHandler*>(context) };
(*handler)(userId, static_cast<UserChangeType>(change));
(*handler)(std::move(userId), std::move(static_cast<UserChangeType>(change)));
},
&token
);
@ -248,7 +371,7 @@ void User::UnregisterChangeEventHandle(
}
}
xsapi_internal_string User::GetGamertagComponent(
Result<String> User::GetGamertagComponent(
XalGamertagComponent component
) const noexcept
{
@ -258,19 +381,19 @@ xsapi_internal_string User::GetGamertagComponent(
std::vector<char> gamertagComponent(size, char{});
auto hr = XalUserGetGamertag(m_handle, component, size, &gamertagComponent[0], nullptr);
if (FAILED(hr))
if (SUCCEEDED(hr))
{
return "";
m_gamertags[component] = gamertagComponent.data();
}
else
else
{
return gamertagComponent.data();
LOGS_ERROR << "Getting Gamertag failed with HR: "<< hr ;
}
return Result<String>{m_gamertags[component], hr };
}
else
{
return "";
}
return E_UNEXPECTED;
}
NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END

Просмотреть файл

@ -3,6 +3,8 @@
#pragma once
struct XblHttpCall;
NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN
using HttpHeaders = Map<String, String>;
@ -23,16 +25,23 @@ typedef XalUserChangeType UserChangeType;
using UserChangeEventHandler = Function<void(UserLocalId /*localId*/, UserChangeType /*changeType*/)>;
class User;
template<>
class Result<User>;
// RAII wrapper around XalUser
class User
{
public:
User(XblUserHandle userHandle) noexcept;
User(const User& other) noexcept;
User(const User& other) = delete;
User(User&& other) noexcept;
User& operator=(User other) noexcept;
User& operator=(User&& other) noexcept;
~User() noexcept;
static Result<User> WrapHandle(XblUserHandle userHandle) noexcept;
Result<User> Copy() const noexcept;
uint64_t Xuid() const noexcept;
uint64_t LocalId() const noexcept;
String Gamertag() const noexcept;
@ -47,11 +56,9 @@ public:
const uint8_t* requestBody,
size_t requestBodySize,
bool allUsers,
AsyncContext<Result<TokenAndSignature>> async
AsyncContext<Result<TokenAndSignature>>&& async
) noexcept;
HRESULT GetConstructorHR() const noexcept;
XalUserHandle Handle() const noexcept;
static void SetTokenExpired(uint64_t xuid) noexcept;
@ -65,9 +72,46 @@ public:
) noexcept;
private:
String GetGamertagComponent(XalGamertagComponent component) const noexcept;
HRESULT m_constructorHR = S_OK;
User() noexcept = default;
User(XblUserHandle userHandle) noexcept;
HRESULT InitializeUser() noexcept;
Result<String> GetGamertagComponent(XalGamertagComponent component) const noexcept;
XblUserHandle m_handle{ nullptr };
mutable uint64_t m_xuid;
mutable XalUserLocalId m_localId;
mutable Map<XalGamertagComponent, String> m_gamertags;
friend class Result<User>;
};
template<>
class Result<User>
{
public:
Result(User&& user) : m_payload{ std::move(user) } {}
Result(User&& user, HRESULT error) : m_payload{ std::move(user) }, m_result{ error } {}
Result(Result&& other) = default;
Result(const Result& other) = delete;
HRESULT Hresult() const noexcept
{
return m_result;
}
const User& Payload() const noexcept
{
return m_payload;
}
User&& ExtractPayload() noexcept
{
return std::move(m_payload);
}
private:
HRESULT m_result;
User m_payload;
};
NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END

Просмотреть файл

@ -13,7 +13,7 @@ NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN
using namespace xbox::services::system;
Websocket::Websocket(
_In_ User user,
_In_ User&& user,
_In_ TaskQueue queue
) noexcept :
m_user{ std::move(user) },
@ -180,15 +180,18 @@ void Websocket::CloseHandler(
}
std::shared_ptr<IWebsocket> IWebsocket::Make(
User user,
User&& user,
TaskQueue queue
) noexcept
{
#if XSAPI_UNIT_TESTS
return MakeShared<MockWebsocket>(std::move(user), std::move(queue));
auto webSocket = MakeShared<MockWebsocket>(std::move(user), std::move(queue));
#else
return MakeShared<Websocket>(std::move(user), std::move(queue));
auto webSocket = MakeShared<Websocket>(std::move(user), std::move(queue));
#endif
return webSocket;
}
void IWebsocket::SetConnectCompleteHandler(_In_ Callback<WebsocketResult> connectCompleteHandler) noexcept

Просмотреть файл

@ -18,7 +18,7 @@ class IWebsocket
{
public:
static std::shared_ptr<IWebsocket> Make(
User user,
User&& user,
TaskQueue queue
) noexcept;
@ -53,7 +53,7 @@ class Websocket : public IWebsocket, public RefCounter, public std::enable_share
{
public:
Websocket(
_In_ User user,
_In_ User&& user,
_In_ TaskQueue queue
) noexcept;
@ -69,6 +69,7 @@ public:
HRESULT Disconnect() noexcept override;
private:
// RefCounter
std::shared_ptr<RefCounter> GetSharedThis() override;

Просмотреть файл

@ -1295,6 +1295,16 @@ xsapi_internal_vector<uint32_t> utils::uint32_array_to_internal_vector(
return vector;
}
String utils::ToLower(String str) noexcept
{
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c)
{
return static_cast<char>(tolower(c));
});
return str;
}
XAsyncBlock* utils::MakeAsyncBlock(XTaskQueueHandle queue, void* context, XAsyncCompletionRoutine* callback)
{
auto async = Make<XAsyncBlock>();

Просмотреть файл

@ -560,7 +560,9 @@ public:
static constexpr uint64_t TICKS_PER_MS = 10000;
static constexpr uint64_t TICKS_PER_SEC = (1000 * TICKS_PER_MS);
static constexpr uint64_t EPOCH_OFFSET = 11644473600LL;
static String ToLower(String str) noexcept;
private:
template<typename T>
struct SmartPointerContainer

Просмотреть файл

@ -45,17 +45,20 @@ LocalStorage::LocalStorage(
}
HRESULT LocalStorage::WriteAsync(
User user,
const User& user,
XblLocalStorageWriteMode mode,
String key,
Vector<uint8_t> data,
Callback<Result<size_t>> callback
) noexcept
{
WriteOperation::OperationLauncher launcher {
auto copyUserResult{ user.Copy() };
RETURN_HR_IF_FAILED(copyUserResult.Hresult());
WriteOperation::OperationLauncher launcher{
[
sharedThis{ shared_from_this() },
user{ std::move(user) },
user = MakeShared<User>(copyUserResult.ExtractPayload()),
mode,
key{ std::move(key) },
data{ std::move(data) }
@ -65,7 +68,7 @@ HRESULT LocalStorage::WriteAsync(
sharedThis->m_writeHandler(
sharedThis->m_context,
op,
user.Handle(),
user->Handle(),
mode,
key.data(),
data.size(),
@ -93,20 +96,23 @@ HRESULT LocalStorage::WriteAsync(
}
HRESULT LocalStorage::ReadAsync(
User user,
const User& user,
String key,
Callback<Result<Vector<uint8_t>>> callback
) noexcept
{
auto copyUserResult{ user.Copy() };
RETURN_HR_IF_FAILED(copyUserResult.Hresult());
ReadOperation::OperationLauncher launcher{
[
sharedThis{ shared_from_this() },
user{ std::move(user) },
user = MakeShared<User>(copyUserResult.ExtractPayload()),
key{ std::move(key) }
]
(XblClientOperationHandle op)
{
sharedThis->m_readHandler(sharedThis->m_context, op, user.Handle(), key.data());
sharedThis->m_readHandler(sharedThis->m_context, op, user->Handle(), key.data());
}};
auto op = MakeShared<ReadOperation>(
@ -129,20 +135,23 @@ HRESULT LocalStorage::ReadAsync(
}
HRESULT LocalStorage::ClearAsync(
User user,
const User& user,
String key,
Callback<HRESULT> callback
) noexcept
{
auto copyUserResult{ user.Copy() };
RETURN_HR_IF_FAILED(copyUserResult.Hresult());
ClearOperation::OperationLauncher launcher {
[
sharedThis{ shared_from_this() },
user{ std::move(user) },
user = MakeShared<User>(copyUserResult.ExtractPayload()),
key{ std::move(key) }
]
(XblClientOperationHandle op)
{
sharedThis->m_clearHandler(sharedThis->m_context, op, user.Handle(), key.data());
sharedThis->m_clearHandler(sharedThis->m_context, op, user->Handle(), key.data());
}};
auto op = MakeShared<ClearOperation>(

Просмотреть файл

@ -27,7 +27,7 @@ public:
using ClearOperation = ClientOperation<HRESULT>;
HRESULT WriteAsync(
User user,
const User& user,
XblLocalStorageWriteMode mode,
String key,
Vector<uint8_t> data,
@ -35,13 +35,13 @@ public:
) noexcept;
HRESULT ReadAsync(
User user,
const User& user,
String key,
Callback<Result<Vector<uint8_t>>> callback
) noexcept;
HRESULT ClearAsync(
User user,
const User& user,
String key,
Callback<HRESULT> callback
) noexcept;

Просмотреть файл

@ -56,7 +56,7 @@ end
function OnXblAchievementsManagerDoWork_LocalUserAddedEvent()
print("OnXblAchievementsManagerDoWork_LocalUserAddedEvent")
handle, hr = XblAchievementsManagerGetSortedAchievements()
handle, hr = XblAchievementsManagerGetAchievementsByState()
VerifySuccess(hr)
count, hr = XblAchievementsManagerResultGetAchievements()
VerifySuccess(hr)
@ -89,7 +89,7 @@ end
function OnXblAchievementsManagerDoWork_AchievementUnlockedEvent()
print("OnXblAchievementsManagerDoWork_AchievementUnlockedEvent")
handle, hr = XblAchievementsManagerGetSortedAchievements()
handle, hr = XblAchievementsManagerGetAchievementsByState()
VerifySuccess(hr)
count, hr = XblAchievementsManagerResultGetAchievements()
VerifySuccess(hr)

Просмотреть файл

@ -28,7 +28,8 @@ User CreateMockUser(
{
auto xalUserImpl = std::shared_ptr<XalUserImpl>{ new XalUserImpl{ xuid, gamertag, "", "", "", localId } };
auto xalUser = std::unique_ptr<XalUser>{ new XalUser{ xalUserImpl } };
return User{ xalUser.get() };
auto userResult = User::WrapHandle(xalUser.get());
return userResult.ExtractPayload();
}
NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END

Просмотреть файл

@ -132,7 +132,7 @@ std::shared_ptr<XblContext> TestEnvironment::CreateMockXboxLiveContext(
const std::string& gamertag
) const noexcept
{
auto context = std::make_shared<XblContext>(CreateMockUser(xuid, gamertag));
auto context = XblContext::Make(std::move(CreateMockUser(xuid, gamertag)));
VERIFY_SUCCEEDED(context->Initialize(GlobalState::Get()->RTAManager()));
return context;
}
@ -142,7 +142,7 @@ std::shared_ptr<xbox_live_context> TestEnvironment::CreateLegacyMockXboxLiveCont
const std::string& gamertag
) const noexcept
{
auto context = std::make_shared<XblContext>(CreateMockUser(xuid, gamertag));
auto context = XblContext::Make(std::move(CreateMockUser(xuid, gamertag)));
VERIFY_SUCCEEDED(context->Initialize(GlobalState::Get()->RTAManager()));
return std::make_shared<xbox_live_context>(context.get());
}

Просмотреть файл

@ -1863,7 +1863,7 @@ private:
));
VERIFY_SUCCEEDED(hr = XblAchievementsManagerResultGetAchievements(resultHandle, &achievement, &size));
VERIFY_IS_TRUE(achievement->progressState == XblAchievementProgressState::Achieved);
VERIFY_ARE_EQUAL(
VERIFY_ARE_EQUAL_STR(
achievement->progression.requirements[0].currentProgressValue,
achievement->progression.requirements[0].targetProgressValue
);
@ -2832,7 +2832,7 @@ public:
&size
));
VERIFY_IS_TRUE(achievement->progressState == XblAchievementProgressState::Achieved);
VERIFY_ARE_EQUAL(
VERIFY_ARE_EQUAL_STR(
achievement->progression.requirements[0].currentProgressValue,
achievement->progression.requirements[0].targetProgressValue
);
@ -3007,7 +3007,7 @@ public:
VERIFY_IS_TRUE(achievement->progressState == XblAchievementProgressState::Achieved);
for (uint8_t i = 0; i < achievement->progression.requirementsCount; ++i)
{
VERIFY_ARE_EQUAL(
VERIFY_ARE_EQUAL_STR(
achievement->progression.requirements[i].currentProgressValue,
achievement->progression.requirements[i].targetProgressValue
);

Просмотреть файл

@ -173,6 +173,7 @@ public:
VERIFY_ARE_EQUAL_INT(row->xboxUserId, strtoull(rowToVerify["xuid"].GetString(), nullptr, 0));
VERIFY_ARE_EQUAL_DOUBLE(row->percentile, rowToVerify["percentile"].GetDouble());
VERIFY_ARE_EQUAL_INT(row->rank, rowToVerify["rank"].GetUint());
VERIFY_ARE_EQUAL_INT(row->globalRank, rowToVerify["globalrank"].GetUint());
if (!rowToVerify.HasMember("values"))
{

Просмотреть файл

@ -226,8 +226,9 @@ public:
PeoplehubTestEnvironment() noexcept
: XboxLiveContext{ CreateMockXboxLiveContext() }
{
auto userResult = XboxLiveContext->User().Copy();
PeoplehubService = std::make_shared<xbox::services::social::manager::PeoplehubService>(
XboxLiveContext->User(),
userResult.ExtractPayload(),
std::make_shared<XboxLiveContextSettings>(),
AppConfig::Instance()->TitleId()
);

Просмотреть файл

@ -1663,7 +1663,9 @@ public:
env.SetPeoplehubMock(false, true);
uint64_t changedXuid{ 1 };
env.FireSocialGraphChangedRtaEvent(user, XblSocialNotificationType::Changed, changedXuid);
auto userResult = User::WrapHandle(user);
env.FireSocialGraphChangedRtaEvent(userResult.ExtractPayload(), XblSocialNotificationType::Changed, changedXuid);
bool profileChanged{ false };
bool presenceChanged{ false };
@ -1862,8 +1864,8 @@ public:
VERIFY_SUCCEEDED(XblSocialManagerDestroySocialUserGroup(groupHandle));
{
// Ensure the user in the event is valid even after destroying the group
User userFromEvent{ events[0]->user };
VERIFY_ARE_EQUAL_UINT(MOCK_XUID, userFromEvent.Xuid());
auto userFromEventResult = User::WrapHandle(events[0]->user);
VERIFY_ARE_EQUAL_UINT(MOCK_XUID, userFromEventResult.ExtractPayload().Xuid());
}
// Make a user go offline to trigger event
@ -1899,8 +1901,8 @@ public:
{
// Ensure the user handle from the event is still valid after removing the user
User userFromEvent{ events[0]->user };
VERIFY_ARE_EQUAL_UINT(MOCK_XUID, userFromEvent.Xuid());
auto userFromEventResult = User::WrapHandle(events[0]->user);
VERIFY_ARE_EQUAL_UINT(MOCK_XUID, userFromEventResult.ExtractPayload().Xuid());
}
}
@ -1909,7 +1911,6 @@ public:
SMTestEnvironment env{};
auto xboxLiveContext = env.CreateLegacyMockXboxLiveContext();
xbox_live_user_t userHandle = xboxLiveContext->user();
User localUser{ userHandle };
auto socialManager{ social_manager::get_singleton_instance() };

Просмотреть файл

@ -72,7 +72,6 @@ del "%githubPath%Microsoft.Xbox.Services.Android.*"
del "%githubPath%Microsoft.Xbox.Services.Win32.*"
del "%githubPath%Microsoft.Xbox.Services.XDK.*"
del "%githubPath%Microsoft.Xbox.Services.GDK.Bin.*"
del "%githubPath%LINKTOSOURCE.md"
del "%githubPath%tcui.*.props"
:: Copy build directory and selectively delete non-GDK and UnitTests projects

Просмотреть файл

@ -241,6 +241,15 @@ set BUILD_INFO_BODY="%TFS_DROPLOCATION% https://microsoft.visualstudio.com/Xb
del %BUILD_INFO_PATH%
echo %BUILD_INFO_BODY% > %BUILD_INFO_PATH%
rem setup folders for GDK docs
set PATH_GDK_DOCS=%TFS_DropLocation%\gdk-docs
set PATH_GDK_DOCS_DROP=%PATH_GDK_DOCS%\docs
mkdir %PATH_GDK_DOCS%
mkdir %PATH_GDK_DOCS_DROP%
call %BUILD_TOOLS%\Noggin\GenerateReferenceDocs.cmd %TFS_DropLocation%\include %PATH_GDK_DOCS_DROP%
copy %BUILD_TOOLS%\Noggin\CopyReferenceDocsToDocsRepo.cmd %PATH_GDK_DOCS%
rem create unity package
REM set UNITY_ASSET_DEST=%TFS_DropLocation%\unity
REM set UNITY_ASSET_SRC=%TFS_SourcesDirectory%\Utilities\IDXboxUnityAssetLayout