XUserAddAsync
将用户异步添加到游戏会话。
语法
HRESULT XUserAddAsync(
XUserAddOptions options,
XAsyncBlock* async
)
参数
options _In_
类型:XUserAddOptions
将用户添加到游戏会话的选项。
async _Inout_
类型:XAsyncBlock*
用于轮询调用的状态和检索调用结果的 XAsyncBlock。
返回值
类型:HRESULT
HRESULT 成功或错误代码。 有关错误代码的列表,请参阅错误代码。
备注
XUserAddAsync 启动一个异步操作来将用户添加到游戏。 使用 XUserAddResult 检索该操作的结果。
XUserAddAsync 始终显示帐户选取器 UI,除非你将 XUserAddOptions::AddDefaultUserSilently 或 XUserAddOptions::AddDefaultUserAllowingUI 传递到 options 参数。
如果使用 XUserAddOptions::AddDefaultUserSilently,XUserAddAsync 将不显示任何 UI。
使用简化用户模型(NDA 主题)要求授权时,此函数有一些注意事项:
- 使用简化的用户模型时,开发人员应确保将选项设置为 XUserAddOptions::AddDefaultUserSilently:
- 在主机上,不允许使用简化用户模型的松散部署的游戏启动,除非已有默认用户登录。
- 在电脑上,无需用户即可启动使用简化用户模型的松散部署游戏;但是,当游戏调用 XUserAddAsync 时,如果没有人登录,游戏将终止,电脑引导程序将启动以帮助用户登录。 只要用户完全登录到 Xbox Live,后续启动就可以正常运行。
在某些极端情况下,开发者应该知道是否在将 options 设置为 XUserAddOptions::AddDefaultUserSilently 的情况下重复调用 XUserAddAsync:
- 如果反复调用此操作,并且我们知道启动游戏的默认用户,它将返回该用户。
- 如果先前已知的默认用户已注销,并且只有一个用户登录到设备,则会将该用户标记为新的“默认”用户并返回该用户。
- 如果先前已知的默认用户已注销,并且有多个用户登录到设备,它将返回 E_GAMEUSER_NO_DEFAULT_USER。
如果默认用户不可用,XUserAddResult 将返回 E_GAMEUSER_NO_DEFAULT_USER。 必须在 options 未设置为 XUserAddOptions::AddDefaultUserSilently 的情况下调用 XUserAddAsync。
在某些极端情况下,开发者应该知道是否在将 options 设置为 XUserAddOptions::AddDefaultUserAllowingUI 的情况下重复调用 XUserAddAsync。 这些与无提示 UI 情况非常相似(但不完全相同):
- 如果反复调用此操作,并且我们知道启动游戏的默认用户,它将返回该用户。
- 如果先前已知的默认用户已注销,并且只有一个用户登录到设备,则会将该用户标记为新的“默认”用户并返回该用户。
- 如果用户注销了最初启动游戏的用户,并且用户数为 0 或大于 1,则系统将显示 UI 用于获取用户,然后将该用户设置为默认用户。
不能将 XUserAddOptions::AllowGuests 与 XUserAddOptions::AddDefaultUserSilently 一起使用。 访客不能是默认用户。 可以安全地使用 XUserAddOptions::AllowGuests,无论当前平台是否支持访客。
必须通过调用 XUserCloseHandle 关闭从 XUser API 检索到的每个 XUserHandle 句柄,且仅关闭一次。
成功完成 XUserAddAsync 后,将执行输入设备配对。 如果由于 XUserAddOptions::AddDefaultUserSilently 或 XUserAddOptions::AddDefaultUserAllowingUI 选项而在没有 UI 的情况下自动发生登录,然后将分配给系统中用户的输入设备传播到游戏。 如果显示用于登录的 UI,则将选择用户的输入设备分配给该用户。
可通过 XUserRegisterForDeviceAssociationChanged 方法跟踪设备关联。
下面的示例演示如何将用户异步添加到游戏会话。
HRESULT AddUserComplete(XAsyncBlock* ab)
{
unique_user_handle user;
RETURN_IF_FAILED(XUserAddResult(ab, &user));
XUserLocalId userLocalId;
XUserGetLocalId(user.get(), &userLocalId);
auto iter = std::find_if(
_users.begin(),
_users.end(),
[&userLocalId](const User& candidate)
{
XUserLocalId candidateUserLocalId;
XUserGetLocalId(candidate.Handle(), &candidateUserLocalId);
return candidateUserLocalId == userLocalId;
});
// User already known
if (iter != _users.end())
{
appLog.AddLog("User already in list\n");
return S_OK;
}
try
{
_users.emplace_back(user.get());
_users.back().LoadGamerPicAsync(_queue);
}
CATCH_RETURN();
return S_OK;
}
HRESULT AddUser(bool allowGuests, bool silent)
{
auto asyncBlock = std::make_unique<XAsyncBlock>();
ZeroMemory(asyncBlock.get(), sizeof(*asyncBlock));
asyncBlock->queue = _queue;
asyncBlock->context = this;
asyncBlock->callback = [](XAsyncBlock* ab)
{
auto asyncBlock = std::unique_ptr<XAsyncBlock>(ab);
LOG_IF_FAILED(static_cast<UserWindow*>(ab->context)->AddUserComplete(ab));
};
XUserAddOptions options = XUserAddOptions::None;
if (allowGuests)
{
WI_SET_FLAG(options, XUserAddOptions::AllowGuests);
}
if (silent)
{
WI_SET_FLAG(options, XUserAddOptions::AddDefaultUserSilently);
}
if (SUCCEEDED_LOG(XUserAddAsync(
options,
asyncBlock.get())))
{
// The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership.
// If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock*
asyncBlock.release();
}
return S_OK;
}
要求
头文件:XUser.h
库:xgameruntime.lib
支持平台:Windows、Xbox One 系列主机和 Xbox Series 主机