* 2210 GDK QFE1
This commit is contained in:
Nathan Iskandar 2022-12-08 16:30:39 -08:00 коммит произвёл GitHub
Родитель 525786e8de
Коммит f1a347b91f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
23 изменённых файлов: 227 добавлений и 82 удалений

2
External/Xal/External/libHttpClient поставляемый

@ -1 +1 @@
Subproject commit b8e335836e0c6bc6b83f943b1c9ad3c815c1aab0
Subproject commit 41e4e73cc1dce236e0c9d674cd7096121493b48e

36
External/Xal/Source/Xal/Include/Xal/xal_internal_marketing.h поставляемый Normal file
Просмотреть файл

@ -0,0 +1,36 @@
#pragma once
#if !defined(__cplusplus)
#error C++11 required
#endif
// Attention: This file is intended for internal uses only.
// Its use is not recommended and not supported.
#include <Xal/xal_types.h>
extern "C"
{
//-----------------------------------------------------------------------------
// Marketing State
//-----------------------------------------------------------------------------
/// <summary>
/// Enum defining the various marketing states.
/// </summary>
typedef enum XalMarketingState
{
/// <summary>Existing user</summary>
XalMarketingState_ExistingUser = 0,
/// <summary>User went through account creation</summary>
XalMarketingState_NewUser = 1,
/// <summary>User went through account creation and saw the first party marketing notice</summary>
XalMarketingState_NewUserFirstPartyNotice = 2,
} XalMarketingState;
STDAPI XalUserGetMarketingState(
_In_ XalUserHandle user,
_Out_ XalMarketingState* marketingState
) noexcept;
}

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

@ -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 "2022.08.20220825.000"
#define XAL_VERSION "2022.10.20221205.000"
}

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

@ -463,7 +463,7 @@ STDAPI_(bool) XblSocialManagerPresenceRecordIsUserPlayingTitle(
/// <remarks>
/// Call this API after calling either <see cref="XblSocialManagerCreateSocialUserGroupFromFilters"/>
/// or <see cref="XblSocialManagerCreateSocialUserGroupFromList"/> to create an XblSocialManagerUserGroup.
/// Have the XblSocialManagerUserGroupHandle returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded
/// The XblSocialManagerUserGroupHandle is returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded
/// event in <see cref="XblSocialManagerDoWork"/>.
/// </remarks>
STDAPI XblSocialManagerUserGroupGetType(
@ -482,7 +482,7 @@ STDAPI XblSocialManagerUserGroupGetType(
/// <remarks>
/// Call this API after calling either <see cref="XblSocialManagerCreateSocialUserGroupFromFilters"/>
/// or <see cref="XblSocialManagerCreateSocialUserGroupFromList"/> to create an XblSocialManagerUserGroup.
/// Have the XblSocialManagerUserGroupHandle returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event
/// The XblSocialManagerUserGroupHandle is returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event
/// in <see cref="XblSocialManagerDoWork"/>.
/// </remarks>
STDAPI XblSocialManagerUserGroupGetLocalUser(
@ -501,7 +501,7 @@ STDAPI XblSocialManagerUserGroupGetLocalUser(
/// If the group is not a filter group, E_UNEXPECTED will be returned.
/// Call this API after either <see cref="XblSocialManagerCreateSocialUserGroupFromFilters"/>
/// or <see cref="XblSocialManagerCreateSocialUserGroupFromList"/> to create an XblSocialManagerUserGroup.
/// Have the XblSocialManagerUserGroupHandle returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded
/// The XblSocialManagerUserGroupHandle is returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded
/// event in <see cref="XblSocialManagerDoWork"/>.<br/>
/// </remarks>
STDAPI XblSocialManagerUserGroupGetFilters(
@ -533,8 +533,7 @@ typedef const XblSocialManagerUser* const* XblSocialManagerUserPtrArray;
/// they are statically sized and trivially copyable.
/// Call this API after calling either <see cref="XblSocialManagerCreateSocialUserGroupFromFilters"/>
/// or <see cref="XblSocialManagerCreateSocialUserGroupFromList"/> to create an XblSocialManagerUserGroup.
/// Have the XblSocialManagerUserGroupHandle returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded
/// event in <see cref="XblSocialManagerDoWork"/>.
/// Wait for <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event in <see cref="XblSocialManagerDoWork"/>. Prior to this the group will be empty.
/// </remarks>
STDAPI XblSocialManagerUserGroupGetUsers(
_In_ XblSocialManagerUserGroupHandle group,
@ -555,8 +554,7 @@ STDAPI XblSocialManagerUserGroupGetUsers(
/// but for filter-based groups, the set tracked users changes as the local user's relationships change.
/// Call this API after calling either <see cref="XblSocialManagerCreateSocialUserGroupFromFilters"/>
/// or <see cref="XblSocialManagerCreateSocialUserGroupFromList"/> to create an XblSocialManagerUserGroup.
/// Have the XblSocialManagerUserGroupHandle returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event
/// in <see cref="XblSocialManagerDoWork"/>.
/// Wait for <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event in <see cref="XblSocialManagerDoWork"/>. Prior to this the group will be empty.
/// </remarks>
STDAPI XblSocialManagerUserGroupGetUsersTrackedByGroup(
_In_ XblSocialManagerUserGroupHandle group,
@ -630,8 +628,7 @@ STDAPI XblSocialManagerDoWork(
/// (invalidating the returned handle) if the associated user is removed from Social Manager.</param>
/// <returns>HRESULT return code for this API operation.</returns>
/// <remarks>
/// The result of a user group being loaded will be triggered through
/// the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event in <see cref="XblSocialManagerDoWork"/>.
/// Wait for <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event in <see cref="XblSocialManagerDoWork"/>. Prior to this the group will be empty.
/// </remarks>
STDAPI XblSocialManagerCreateSocialUserGroupFromFilters(
_In_ XblUserHandle user,
@ -652,8 +649,7 @@ STDAPI XblSocialManagerCreateSocialUserGroupFromFilters(
/// (invalidating the returned handle) if the associated user is removed from Social Manager.</param>
/// <returns>HRESULT return code for this API operation.</returns>
/// <remarks>
/// The result of a user group being loaded will be triggered through
/// the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event in <see cref="XblSocialManagerDoWork"/>.
/// Wait for <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event in <see cref="XblSocialManagerDoWork"/>. Prior to this the group will be empty.
/// </remarks>
STDAPI XblSocialManagerCreateSocialUserGroupFromList(
_In_ XblUserHandle user,
@ -671,7 +667,7 @@ STDAPI XblSocialManagerCreateSocialUserGroupFromList(
/// This will stop updaing the Xbox Social User Group and remove tracking for any users the XblSocialManagerUserGroup holds.
/// Call this API after calling either <see cref="XblSocialManagerCreateSocialUserGroupFromFilters"/>
/// or <see cref="XblSocialManagerCreateSocialUserGroupFromList"/> to create an XblSocialManagerUserGroup.
/// Have the XblSocialManagerUserGroupHandle returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event
/// The XblSocialManagerUserGroupHandle is returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded event
/// in <see cref="XblSocialManagerDoWork"/>.
/// </remarks>
STDAPI XblSocialManagerDestroySocialUserGroup(
@ -722,7 +718,7 @@ STDAPI XblSocialManagerGetLocalUsers(
/// <see cref="XblSocialManagerEventType"/>::SocialUserGroupUpdated event in <see cref="XblSocialManagerDoWork"/>.
/// Call this API after calling either <see cref="XblSocialManagerCreateSocialUserGroupFromFilters"/>
/// or <see cref="XblSocialManagerCreateSocialUserGroupFromList"/> to create an XblSocialManagerUserGroup.
/// Have the XblSocialManagerUserGroupHandle returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded
/// The XblSocialManagerUserGroupHandle is returned by the <see cref="XblSocialManagerEventType"/>::SocialUserGroupLoaded
/// event in <see cref="XblSocialManagerDoWork"/>.
/// </remarks>
STDAPI XblSocialManagerUpdateSocialUserGroup(

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

@ -501,7 +501,7 @@ private:
_In_ AsyncContext<Result<void>> async
) noexcept;
HRESULT SubscribeToRta() noexcept;
HRESULT SubscribeToRta(std::unique_lock<std::mutex> lock) noexcept;
HRESULT UnsubscribeFromRta() noexcept;
HRESULT WriteSessionUsingSubpath(

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

@ -1157,7 +1157,7 @@ HRESULT MultiplayerService::SetRtaConnectionId(
return S_OK;
}
HRESULT MultiplayerService::SubscribeToRta() noexcept
HRESULT MultiplayerService::SubscribeToRta(std::unique_lock<std::mutex> lock) noexcept
{
if (m_subscription == nullptr)
{
@ -1223,6 +1223,8 @@ HRESULT MultiplayerService::SubscribeToRta() noexcept
}
});
// Unlock before adding subscription as it can synchronously call back into our ConnectionIdChanged handler
lock.unlock();
return m_rtaManager->AddSubscription(m_user, m_subscription);
}
return S_OK;
@ -1248,9 +1250,9 @@ HRESULT MultiplayerService::UnsubscribeFromRta() noexcept
HRESULT MultiplayerService::EnableMultiplayerSubscriptions() noexcept
{
std::lock_guard<std::mutex> lock{ m_mutexMultiplayerService };
std::unique_lock<std::mutex> lock{ m_mutexMultiplayerService };
m_forceEnableRtaSubscription = true;
return SubscribeToRta();
return SubscribeToRta(std::move(lock));
}
HRESULT MultiplayerService::DisableMultiplayerSubscriptions() noexcept
@ -1281,11 +1283,21 @@ XblFunctionContext MultiplayerService::AddMultiplayerSessionChangedHandler(
_In_ MultiplayerSubscription::SessionChangedHandler handler
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutexMultiplayerService };
{
std::unique_lock<std::mutex> lock{ m_mutexMultiplayerService };
SubscribeToRta(std::move(lock));
}
SubscribeToRta();
assert(m_subscription);
return m_subscription->AddSessionChangedHandler(std::move(handler));
XblFunctionContext token{};
{
std::unique_lock<std::mutex> lock{ m_mutexMultiplayerService };
if (m_subscription)
{
token = m_subscription->AddSessionChangedHandler(std::move(handler));
}
}
return token;
}
void MultiplayerService::RemoveMultiplayerSessionChangedHandler(

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

@ -235,7 +235,7 @@ private:
Map<uint32_t, size_t> m_trackedTitles;
uint32_t const m_titleId;
mutable std::mutex m_mutex;
mutable std::recursive_mutex m_mutex;
friend class DevicePresenceChangeSubscription;
friend class TitlePresenceChangeSubscription;

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

@ -54,7 +54,10 @@ XblFunctionContext PresenceService::AddTitlePresenceChangedHandler(
TitlePresenceChangedHandler handler
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::unique_lock<std::recursive_mutex> lock{ m_mutex };
m_titlePresenceChangedHandlers[m_nextHandlerToken] = std::move(handler);
auto token = m_nextHandlerToken++;
// Add subs to RTA manager if needed
if (m_titlePresenceChangedHandlers.empty())
@ -70,15 +73,14 @@ XblFunctionContext PresenceService::AddTitlePresenceChangedHandler(
}
}
m_titlePresenceChangedHandlers[m_nextHandlerToken] = std::move(handler);
return m_nextHandlerToken++;
return token;
}
void PresenceService::RemoveTitlePresenceChangedHandler(
_In_ XblFunctionContext context
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
auto removed{ m_titlePresenceChangedHandlers.erase(context) };
if (removed && m_titlePresenceChangedHandlers.empty())
@ -98,7 +100,7 @@ XblFunctionContext PresenceService::AddDevicePresenceChangedHandler(
DevicePresenceChangedHandler handler
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
// Add subs to RTA manager if needed
if (m_devicePresenceChangedHandlers.empty())
@ -118,7 +120,7 @@ void PresenceService::RemoveDevicePresenceChangedHandler(
_In_ XblFunctionContext context
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
auto removed{ m_devicePresenceChangedHandlers.erase(context) };
if (removed && m_devicePresenceChangedHandlers.empty())
@ -135,7 +137,7 @@ HRESULT PresenceService::TrackUsers(
const Vector<uint64_t>& xuids
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
if (!m_resyncHandlerToken)
{
@ -188,7 +190,7 @@ HRESULT PresenceService::StopTrackingUsers(
const Vector<uint64_t>& xuids
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
for (auto& xuid : xuids)
{
@ -217,7 +219,7 @@ HRESULT PresenceService::TrackAdditionalTitles(
const Vector<uint32_t>& titleIds
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
for (auto& titleId : titleIds)
{
@ -251,7 +253,7 @@ HRESULT PresenceService::StopTrackingAdditionalTitles(
const Vector<uint32_t>& titleIds
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
List<uint32_t> removedTitles{};
for (auto& titleId : titleIds)
@ -415,7 +417,7 @@ void PresenceService::HandleDevicePresenceChanged(
_In_ bool isUserLoggedOnDevice
) const noexcept
{
std::unique_lock<std::mutex> lock{ m_mutex };
std::unique_lock<std::recursive_mutex> lock{ m_mutex };
auto handlers{ m_devicePresenceChangedHandlers };
lock.unlock();
@ -431,7 +433,7 @@ void PresenceService::HandleTitlePresenceChanged(
_In_ XblPresenceTitleState state
) const noexcept
{
std::unique_lock<std::mutex> lock{ m_mutex };
std::unique_lock<std::recursive_mutex> lock{ m_mutex };
auto handlers{ m_titlePresenceChangedHandlers };
lock.unlock();
@ -443,7 +445,7 @@ void PresenceService::HandleTitlePresenceChanged(
void PresenceService::HandleRTAResync()
{
std::unique_lock<std::mutex> lock{ m_mutex };
std::unique_lock<std::recursive_mutex> lock{ m_mutex };
LOGS_DEBUG << "Resyncing " << m_trackedXuids.size() << " Presence Subscriptions";
@ -456,7 +458,7 @@ void PresenceService::HandleRTAResync()
return;
}
std::unique_lock<std::mutex> lock{ m_mutex };
std::unique_lock<std::recursive_mutex> lock{ m_mutex };
if(Succeeded(result))
{

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

@ -48,6 +48,9 @@ struct ServiceSubscription
Set<std::shared_ptr<Subscription>> clientSubscriptions;
List<AsyncContext<Result<void>>> subscribeAsyncContexts;
List<AsyncContext<Result<void>>> unsubscribeAsyncContexts;
// OnSubscribe data payload
JsonDocument onSubscribeData{ rapidjson::kNullType };
};
// RTA message types and error codes define by service here http://xboxwiki/wiki/Real_Time_Activity
@ -229,6 +232,8 @@ HRESULT Connection::AddSubscription(
{
// Subscription is already active, trivially complete
lock.unlock();
// Pass along original OnSubscribe payload for this subscription
sub->OnSubscribe(serviceSub->onSubscribeData);
async.Complete(S_OK);
return S_OK;
}
@ -431,7 +436,7 @@ void Connection::SubscribeResponseHandler(_In_ const JsonValue& message) noexcep
case ErrorCode::Success:
{
serviceSub->serviceId = message[3].GetInt();
const auto& data = message[4];
serviceSub->onSubscribeData.CopyFrom(message[4], serviceSub->onSubscribeData.GetAllocator());
m_subsByServiceId[serviceSub->serviceId] = serviceSub;
List<AsyncContext<Result<void>>> subscribeAsyncContexts{ std::move(serviceSub->subscribeAsyncContexts) };
@ -470,7 +475,7 @@ void Connection::SubscribeResponseHandler(_In_ const JsonValue& message) noexcep
}
for (auto& clientSub : clientSubs)
{
clientSub->OnSubscribe(data);
clientSub->OnSubscribe(serviceSub->onSubscribeData);
}
return;

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

@ -144,12 +144,15 @@ try
auto group{ socialManager.GetUserGroup(groupHandle) };
if (!group)
{
*users = nullptr;
*usersCount = 0;
return E_UNEXPECTED;
}
*users = group->Users().data();
*usersCount = group->Users().size();
auto& groupUsers = group->Users();
*users = groupUsers.data();
*usersCount = groupUsers.size();
return S_OK;
});
}
@ -170,12 +173,15 @@ try
auto group{ socialManager.GetUserGroup(groupHandle) };
if (!group)
{
*trackedUsers = nullptr;
*trackedUsersCount = 0;
return E_UNEXPECTED;
}
*trackedUsers = group->TrackedUsers().data();
*trackedUsersCount = group->TrackedUsers().size();
const auto& groupTrackedUsers = group->TrackedUsers();
*trackedUsers = groupTrackedUsers.data();
*trackedUsersCount = groupTrackedUsers.size();
return S_OK;
});
}

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

@ -203,10 +203,13 @@ const Vector<const XblSocialManagerUser*>& XblSocialManagerUserGroup::Users() no
PERF_START();
std::unique_lock<std::mutex> lock{ m_mutex };
m_usersView.clear();
std::transform(m_users.begin(), m_users.end(), std::back_inserter(m_usersView), [](const auto& pair)
if (m_loaded)
{
return pair.second;
});
std::transform(m_users.begin(), m_users.end(), std::back_inserter(m_usersView), [](const auto& pair)
{
return pair.second;
});
}
PERF_STOP();
return m_usersView;
}
@ -215,22 +218,29 @@ const Vector<uint64_t>& XblSocialManagerUserGroup::TrackedUsers() noexcept
{
PERF_START();
std::unique_lock<std::mutex> lock{ m_mutex };
switch (type)
if (m_loaded)
{
case XblSocialUserGroupType::FilterType:
switch (type)
{
case XblSocialUserGroupType::FilterType:
{
m_trackedUsersView.clear();
std::transform(m_users.begin(), m_users.end(), std::back_inserter(m_trackedUsersView), [](const auto& pair)
{
return pair.first;
});
break;
}
case XblSocialUserGroupType::UserListType:
{
// Tracked users view is static
break;
}
}
}
else
{
m_trackedUsersView.clear();
std::transform(m_users.begin(), m_users.end(), std::back_inserter(m_trackedUsersView), [](const auto& pair)
{
return pair.first;
});
break;
}
case XblSocialUserGroupType::UserListType:
{
// Tracked users view is static
break;
}
}
PERF_STOP();
return m_trackedUsersView;

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

@ -257,7 +257,7 @@ private:
// Tracked stats by scid. Needed to perform RTA resync
Map<String, Vector<String>> m_trackedStatsByScid;
mutable std::mutex m_mutex;
mutable std::recursive_mutex m_mutex;
friend class StatisticChangeSubscription;
};

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

@ -216,7 +216,7 @@ XblFunctionContext UserStatisticsService::AddStatisticChangedHandler(
StatisticChangeHandler handler
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
if (!m_resyncHandlerToken)
{
@ -251,7 +251,7 @@ void UserStatisticsService::RemoveStatisticChangedHandler(
XblFunctionContext token
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
auto removed{ m_statisticChangeHandlers.erase(token) };
@ -275,7 +275,7 @@ HRESULT UserStatisticsService::TrackStatistics(
_In_ const Vector<String>& statNames
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
for (auto& xuid : xuids)
{
@ -310,7 +310,7 @@ HRESULT UserStatisticsService::StopTrackingStatistics(
_In_ const Vector<String>& statNames
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
for (auto& xuid : xuids)
{
@ -336,7 +336,7 @@ HRESULT UserStatisticsService::StopTrackingUsers(
_In_ const Vector<uint64_t>& xuids
) noexcept
{
std::lock_guard<std::mutex> lock{ m_mutex };
std::lock_guard<std::recursive_mutex> lock{ m_mutex };
for (auto& xuid : xuids)
{
@ -361,7 +361,7 @@ void UserStatisticsService::HandleStatisticChanged(
const StatisticChangeEventArgs& args
) const noexcept
{
std::unique_lock<std::mutex> lock{ m_mutex };
std::unique_lock<std::recursive_mutex> lock{ m_mutex };
auto handlers{ m_statisticChangeHandlers };
lock.unlock();
@ -373,7 +373,7 @@ void UserStatisticsService::HandleStatisticChanged(
void UserStatisticsService::HandleRTAResync()
{
std::unique_lock<std::mutex> lock{ m_mutex };
std::unique_lock<std::recursive_mutex> lock{ m_mutex };
// Get all stats tracked stats for all tracked users so that we can resync in a single request.
// In the request callback, we will only invoke the stat changed handlers for the tracked users/stats
@ -398,7 +398,7 @@ void UserStatisticsService::HandleRTAResync()
return;
}
std::unique_lock<std::mutex> lock{ m_mutex };
std::unique_lock<std::recursive_mutex> lock{ m_mutex };
if (Succeeded(result))
{

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

@ -9,4 +9,4 @@
//*********************************************************
#pragma once
#define XBOX_SERVICES_API_VERSION_STRING "2022.10.20220915.0"
#define XBOX_SERVICES_API_VERSION_STRING "2022.10.20221025.1"

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

@ -353,6 +353,9 @@
<None Include="$(MSBuildThisFileDirectory)Tests\mp\MP_JoinLobbyViaActivity.lua">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(MSBuildThisFileDirectory)Tests\mp\mp_multiple_contexts.lua">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="$(MSBuildThisFileDirectory)Tests\mp\mp_partial_invite_flow.lua">
<DeploymentContent>true</DeploymentContent>
</None>

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

@ -822,5 +822,8 @@
<None Include="$(MSBuildThisFileDirectory)Tests\notification\multiple_notification_subscriptions.lua">
<Filter>Tests\notification</Filter>
</None>
<None Include="$(MSBuildThisFileDirectory)Tests\mp\mp_multiple_contexts.lua">
<Filter>Tests\mp</Filter>
</None>
</ItemGroup>
</Project>

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

@ -154,10 +154,24 @@ int XblGetErrorCondition_Lua(lua_State *L)
int XblContextCreateHandle_Lua(lua_State *L)
{
// CODE SNIPPET START: XblContextCreateHandle
HRESULT hr = XblContextCreateHandle(Data()->xalUser, &Data()->xboxLiveContext);
XblContextHandle contextHandle{ nullptr };
HRESULT hr = XblContextCreateHandle(Data()->xalUser, &contextHandle);
// CODE SNIPPET END
// Cache the created handle for use in other APIs if we don't have one already
if (Data()->xboxLiveContext == nullptr)
{
Data()->xboxLiveContext = contextHandle;
}
else
{
LogToFile("XblContextCreateHandle called but an existing handle was cached");
}
lua_pushinteger(L, (int64_t)contextHandle);
LogToFile("XblContextCreateHandle: %s", ConvertHR(hr).c_str());
return LuaReturnHR(L, hr);
return LuaReturnHR(L, hr, 1);
}
int XblContextDuplicateHandle_Lua(lua_State *L)
@ -185,14 +199,21 @@ int XblContextCloseHandle_Lua(lua_State *L)
StopSocialManagerDoWorkHelperCpp();
#endif
// CODE SNIPPET START: XblContextCreateHandle
if (Data()->xboxLiveContext)
// Get the XblContextHandle
XblContextHandle handleToClose = (XblContextHandle)GetUint64FromLua(L, 1, (uint64_t)Data()->xboxLiveContext);
// CODE SNIPPET START: XblContextCloseHandle
if (handleToClose != nullptr)
{
XblContextCloseHandle(Data()->xboxLiveContext);
Data()->xboxLiveContext = nullptr;
XblContextCloseHandle(handleToClose);
}
// CODE SNIPPET END
if (handleToClose == Data()->xboxLiveContext)
{
Data()->xboxLiveContext = nullptr;
}
LogToFile("OnXblContextCloseHandle called.");
return LuaReturnHR(L, S_OK);
}

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

@ -136,12 +136,14 @@ int XblMultiplayerWriteSessionAsync_Lua(lua_State *L)
{
// Params:
// 1) Session handle id returned when the session was created
// 2) write mode (as string)
// 2) XblContextHandle to use. Defaults to Data()->xboxLiveContextse
CreateQueueIfNeeded();
auto sessionIndex{ GetUint64FromLua(L, 1, 0) };
assert(MPState()->sessionHandles.size() > sessionIndex);
XblContextHandle xboxLiveContext = (XblContextHandle)GetUint64FromLua(L, 2, (uint64_t)Data()->xboxLiveContext);
ENSURE_IS_TRUE(MPState()->sessionHandles[static_cast<uint32_t>(sessionIndex)] != nullptr, "No valid multiplayer session.");
XblMultiplayerSessionWriteMode writeMode = ConvertStringToXblMultiplayerSessionWriteMode(GetStringFromLua(L, 2, "XblMultiplayerSessionWriteMode::UpdateOrCreateNew").c_str());
@ -180,7 +182,7 @@ int XblMultiplayerWriteSessionAsync_Lua(lua_State *L)
CallLuaFunctionWithHr(hr, "OnXblMultiplayerWriteSessionAsync"); // CODE SNIP SKIP
};
auto hr = XblMultiplayerWriteSessionAsync(Data()->xboxLiveContext, MPState()->sessionHandles[static_cast<uint32_t>(sessionIndex)], writeMode, asyncBlock.get());
auto hr = XblMultiplayerWriteSessionAsync(xboxLiveContext, MPState()->sessionHandles[static_cast<uint32_t>(sessionIndex)], writeMode, asyncBlock.get());
if (SUCCEEDED(hr))
{
// The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership.
@ -1940,9 +1942,12 @@ int XblMultiplayerGetActivitiesWithPropertiesForUsersAsync_Lua(lua_State *L)
int XblMultiplayerSetSubscriptionsEnabled_Lua(lua_State *L)
{
bool enabled = GetBoolFromLua(L, 1, true);
XblContextHandle xboxLiveContext = (XblContextHandle)GetUint64FromLua(L, 2, (uint64_t)Data()->xboxLiveContext);
// CODE SNIPPET START: XblMultiplayerSetSubscriptionsEnabled
HRESULT hr = XblMultiplayerSetSubscriptionsEnabled(Data()->xboxLiveContext, enabled);
HRESULT hr = XblMultiplayerSetSubscriptionsEnabled(xboxLiveContext, enabled);
// CODE SNIPPET END
LogToFile("XblMultiplayerSetSubscriptionsEnabled: hr=%s", ConvertHR(hr).c_str());

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

@ -20,9 +20,12 @@ end
function common.OnXalTryAddFirstUserSilentlyAsync()
local hr = GetLastError()
local handle = 0
if hr == 0 then
print("SignInSilently Succeeded. Creating XblContext")
hr = XblContextCreateHandle()
handle, hr = XblContextCreateHandle()
print("hr " .. hr)
print("handle " .. handle)
if hr == 0 then
XalUserGetGamertag()
XalUserGetId()

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

@ -14,9 +14,9 @@ function TestMP_Handler()
XblMultiplayerSessionDuplicateHandle()
XblMultiplayerSessionCloseHandle()
XblRealTimeActivityActivate()
--XblRealTimeActivityActivate()
XblMultiplayerSubscriptionsEnabled()
XblMultiplayerSetSubscriptionsEnabled()
--XblMultiplayerSetSubscriptionsEnabled()
XblMultiplayerSubscriptionsEnabled()
XblMultiplayerSessionCreateHandle()

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

@ -0,0 +1,33 @@
local xblContext = 0
function TestFunc()
XblMultiplayerSetSubscriptionsEnabled(1)
XblMultiplayerSessionReferenceCreate()
XblMultiplayerSessionCreateHandle()
XblMultiplayerSessionJoin()
XblMultiplayerWriteSessionAsync()
end
local writeCount = 0;
function OnXblMultiplayerWriteSessionAsync()
writeCount = writeCount + 1
if writeCount == 1 then
print("OnXblMultiplayerWriteSessionAsync 1")
-- first write made using default XblContext should complete successfully
-- change the session and attempt to write with second XblContext
xblContext = XblContextCreateHandle()
XblMultiplayerSetSubscriptionsEnabled(1, xblContext)
XblMultiplayerSessionCurrentUserSetStatus()
XblMultiplayerWriteSessionAsync(0, xblContext)
elseif writeCount == 2 then
print("OnXblMultiplayerWriteSessionAsync 2")
XblMultiplayerSessionCloseHandle()
XblContextCloseHandle(xblContext)
test.stopTest();
end
end
test.TestMPMultipleContexts = function()
common.init(TestFunc)
end

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

@ -14,6 +14,7 @@ function OnXblSocialManagerDoWork_LocalUserAddedEvent()
XblSocialManagerGetLocalUsers()
XblSocialManagerSetRichPresencePollingStatus()
group, hr = XblSocialManagerCreateSocialUserGroupFromFilters()
XblSocialManagerUserGroupGetUsers()
print("group " .. group)
end

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

@ -455,6 +455,15 @@
<CopyFileToFolders>
<DestinationFolders>$(OutDir)Assets</DestinationFolders>
</CopyFileToFolders>
<PostBuildEvent>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Gaming.Xbox.XboxOne.x64'">xcopy /Y /I /E "$(ProjectDir)Assets\*.*" "$(TargetDir)Assets" &amp; xcopy /Y /I /E "$(ProjectDir)Media\*.*" "$(TargetDir)Media" &amp; xcopy /Y /I /E "$(ProjectDir)Media\Fonts\*.*" "$(TargetDir)" &amp; xcopy /Y /I /E "$(ProjectDir)Media\Textures\*.*" "$(TargetDir)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Command Condition="'$(Configuration)|$(Platform)'=='Profile|Gaming.Xbox.XboxOne.x64'">xcopy /Y /I /E "$(ProjectDir)Assets\*.*" "$(TargetDir)Assets" &amp; xcopy /Y /I /E "$(ProjectDir)Media\*.*" "$(TargetDir)Media" &amp; xcopy /Y /I /E "$(ProjectDir)Media\Fonts\*.*" "$(TargetDir)" &amp; xcopy /Y /I /E "$(ProjectDir)Media\Textures\*.*" "$(TargetDir)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Xbox.XboxOne.x64'">xcopy /Y /I /E "$(ProjectDir)Assets\*.*" "$(TargetDir)Assets" &amp; xcopy /Y /I /E "$(ProjectDir)Media\*.*" "$(TargetDir)Media" &amp; xcopy /Y /I /E "$(ProjectDir)Media\Fonts\*.*" "$(TargetDir)" &amp; xcopy /Y /I /E "$(ProjectDir)Media\Textures\*.*" "$(TargetDir)"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\APIRunner.GDK\Kits\ATGTK\ControllerFont.h" />