> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XUser 跨平台支持

> XUser 跨平台支持

## 概述

XUser 是 Gaming Runtime API,用于跨平台管理 XBOX 用户账户和认证。它为游戏在 XBOX 主机、Windows PC 和掌机以及非 Microsoft 平台(例如 Steam Deck)上处理用户登录、身份和相关用户流程,提供了统一的接口。

作为 GDK 跨平台计划的一部分,XUser 在所有平台上提供一致的 API 表面,同时兼顾每种环境的不同能力和约束。

### 集成要求

要在你的游戏中使用 XUser,请在你的源文件中包含 `XUser.h`,并链接 `XGameRuntime.lib`。各平台之间的关键差异在于如何处理运行时依赖:

#### XBOX 主机以及 Windows 上的 Microsoft Store / Game Pass

gaming runtime 已内置在操作系统中,由商店处理。你的游戏自动使用系统内置的服务和 UI。

#### Windows 上的其他商店

* 游戏使用操作系统内置的服务和 UI。
* 安装程序应运行 **GamingRepair.exe** 以确保 Gaming Runtime Service 已安装。

**集成 Gaming Repair Tool**

将 Gaming Repair Tool 作为自定义安装步骤添加到你游戏的安装程序中:

1. **将该工具包含在你的游戏包中** —— 它随 GDK 附带,位于 `[GDK]\bin\GamingRepair.exe`。
2. **添加自定义操作** —— 在游戏安装之前运行该工具(例如:start /wait "Installing Gaming Services" GamingRepair.exe scenarioExternal)。这会验证、下载、安装或修复任何缺失的 Gaming Runtime 组件。
3. **处理错误** —— 检查该工具的退出码。如果失败,通知用户并提供手动安装说明。

> [!NOTE]
>
> Steam 游戏必须包含 `XGameRuntime.dll` 及其依赖项,以支持系统服务不可用的平台(例如 Steam Deck)。
> 在 Steam Deck 或其他非 Microsoft 平台上,无法使用 Gaming Repair Tool。相反,将 `XGameRuntime.dll` 及其依赖项打包到你的游戏包中,并将它们放置在与可执行文件同一位置,以便在运行时加载。

## 平台差异与统一 API

在 XBOX 和 Windows 上,操作系统原生处理 XBOX Live 登录和用户管理,提供系统 UI 和用户凭据的安全存储。XUser 在这些平台上利用这些内置的系统服务。在其他游戏平台上(例如 Steam Deck 或第三方环境),这种原生支持不存在。

从 GDK 2510 版本起,XUser 已被增强,可通过一致的 API 在这两类平台上无缝工作,并引入新的 API 和事件驱动模式,使游戏能够在系统支持不可用时提供必要的 UI 和数据处理:

* **在具有原生支持的平台上(XBOX、Windows)** —— XUser 使用操作系统内置的服务进行身份验证、UI 和凭据存储。游戏调用 XUser API,系统会自动处理细节。

* **在没有原生支持的平台上(Steam Deck 等)** —— XUser 暴露相同的核心 API,但游戏必须实现事件处理程序以提供必要的 UI(例如为登录显示 QR 码)和数据存储。这让游戏对认证体验拥有完全的控制。

无论平台如何,游戏都会获得一个代表玩家的 `XUserHandle`,并可用于支持 XBOX 认证的服务(XBOX 服务、PlayFab 服务等)。

## 新的跨平台功能

为 XUser 引入的新 API 专注于实现与平台无关的登录流程和数据处理。关键功能包括:

### Remote Connect 身份验证

允许用户在设备(例如 Steam Deck)上通过辅助设备使用他们的 XBOX 账户登录。用户可以扫描 QR 码或在网站上输入一次性代码来完成身份验证。这是通过新的 XUser 事件处理程序来显示和关闭基于代码的登录提示实现的。

### 单会话强制(SPoP)

确保用户不会同时在多个位置运行同一款游戏。如果检测到冲突,系统会提示用户选择“在此处游玩”或“切换账户”。新的 API 使游戏能够呈现此选择并做出相应响应。

> [!NOTE]
>
> 在 XBOX 主机和 Windows 上,操作系统会继续自动处理大多数身份验证任务。在这些平台上,游戏可能永远不会看到这些事件。然而,在非 XBOX 平台上,游戏可以通过 XUser 的回调机制完全接管控制。

## 使用 Remote Connect 进行跨设备登录

Remote Connect 是一项允许玩家通过另一台设备(例如手机或 PC)进行身份验证,从而在某台设备上登录其 XBOX 账户的功能。这通常通过游戏显示的短代码或 QR 码来完成。

### 工作原理

在 XBOX 主机上,这种“代码流(code flow)”由系统 UI 自动处理。然而,在 Steam Deck 或其他第三方环境等平台上,并没有由系统管理的 XBOX 登录 UI。XUser 中的 Remote Connect API 让游戏能直接支持此流程。

#### 流程

1. **事件处理程序注册** —— 游戏在发起登录之前,使用 `XUserPlatformRemoteConnectSetEventHandlers(...)` 注册一个 Remote Connect 事件处理程序。游戏提供回调以处理两个关键事件:

   * **Show 事件** —— 当 XUser 需要游戏显示一次性代码或 QR 码时触发。处理程序显示一个带有代码和说明的对话框或叠加层(例如:“扫描此 QR 码或访问 xbox.com/play 并输入代码 ABCD 以登录”)。

   * **Close 事件** —— 当远程登录过程完成或被取消时触发,提示游戏隐藏或关闭代码对话框。

2. **用户登录发起** —— 调用 `XUserAddAsync` 添加新用户时,如果尚无本地用户登录,XUser 系统可能会使用 Remote Connect 流程(尤其是在无头或第三方平台上)。

3. **代码显示** —— XUser 调用“show”回调,提供身份验证代码或 URL。游戏的 UI 处理程序(例如 `OnRemoteConnectShow`)向用户显示 QR 码或代码字符串。

4. **用户身份验证** —— 玩家使用手机或 Web 浏览器通过所提供的代码登录,将其 XBOX 账户关联到当前会话。

5. **完成** —— 身份验证在后端完成后,XUser 调用“close”回调,示意可以从屏幕上移除代码。此时,XUser 已获取用户的 XBOX Live 令牌,并创建 `XUserHandle`。

6. **成功** —— `XUserAddAsync` 任务成功返回,用户在没有直接在设备上输入凭据的情况下即已登录。

### 实现

要使用 Remote Connect,请实现两个回调函数并注册它们:

```cpp theme={null}
XUserPlatformRemoteConnectEventHandlers remoteConnect = {};
remoteConnect.context = nullptr;
remoteConnect.show = &OnRemoteConnectShow;   // Display QR/code dialog
remoteConnect.close = &OnRemoteConnectClose; // Dismiss dialog

HRESULT hr = XUserPlatformRemoteConnectSetEventHandlers(nullptr, &remoteConnect);
```

注册处理程序后,像往常一样调用 `XUserAddAsync` 来添加新用户。在 `OnRemoteConnectShow` 处理程序中,检索所提供的信息(可通过 XUser API 获取 —— 通常是一个 URL 和代码),并在弹窗或叠加层中为用户呈现。当 `OnRemoteConnectClose` 被调用时,登录过程已完成,游戏应隐藏该提示。

> [!NOTE]
>
> 在调用 `XUserAddAsync` 之前(通常在 `XUserInitialize` 之前)调用 `XUserPlatformRemoteConnectSetEventHandlers`,以确保正确处理这些事件。

### 用户体验注意事项

为提供良好的用户体验:

* **清晰的说明** —— 在显示代码时清楚地说明用户需要做什么。
* **错误处理** —— 如果用户在远端取消或发生错误,XUser 会使登录尝试失败。请在 `XUserAddAsync` 的正常完成回调中处理这种情况。
* **及时关闭** —— 当 close 事件发生时立即隐藏代码,以避免用户困惑。
* **视觉设计** —— 确保 QR 码和说明在目标设备上足够大且清晰可见。

## 单会话强制(SPoP)

单会话强制(SPoP,即 Single Point of Presence)是一项策略,确保单个 XBOX Live 用户配置不会在多个设备上同时运行同一款游戏。例如,如果你在你的账户已在 XBOX 上运行该游戏的情况下,又在 PC 上启动该游戏,则应挂起或注销其中一个会话,以防止游戏存档冲突和其他问题。

在 XBOX 主机上,此场景会触发系统对话框,告知用户该游戏已在其他地方运行,并询问他们是否想继续(这会从另一台设备注销)。在非 Microsoft 平台上,没有内置机制来强制执行这一点。XUser SPoP 提示 API 允许游戏检测这种情况并向玩家呈现“在此处游玩或切换账户”的选择。

### 工作原理

SPoP API 使用与 Remote Connect 类似的事件处理程序模式。当检测到登录冲突时,XUser 会调用游戏的处理程序,而不是直接失败,让游戏能够向用户呈现选项。

#### 流程

1. **事件处理程序注册** —— 游戏在发起登录之前,使用 `XUserPlatformSpopPromptSetEventHandlers(...)` 注册 SPoP 提示事件处理程序。

2. **冲突检测** —— 调用 `XUserAddAsync` 添加用户时,如果 XUser 检测到相同用户已在其他地方在同一款游戏中处于活动状态,则会调用 SPoP 处理程序。

3. **显示提示** —— 游戏的处理程序会接收到用户的现代玩家代号和一个操作句柄。处理程序应显示一个 UI 提示,例如:“\[Gamertag] 正在另一台设备上游玩。你想改在这里游玩(这会在别处注销),还是切换到其他账户?”,并提供“在此处游玩”和“切换账户”等选项。

4. **用户选择** —— 游戏等待用户做出选择。在游戏调用完成 API 之前,操作保持挂起。

5. **完成操作** —— 根据用户的选择,游戏使用相应的结果调用 `XUserPlatformSpopPromptComplete`:

   * **在此处游玩** —— `XUserPlatformSpopOperationResult::SignInHere` —— 在此设备上登录并终止远端会话。
   * **切换账户** —— `XUserPlatformSpopOperationResult::SwitchAccount` —— 取消在此设备上的登录,允许用户选择其他账户。
   * **取消** —— `XUserPlatformSpopOperationResult::Canceled` —— 中止登录尝试。

6. **处置结果** —— XUser 根据结果继续。如果选择了“在此处游玩”,远端会话会被终止(另一台设备会收到注销事件),并且用户在本地处于活动状态。如果选择了“切换账户”,`XUserAddAsync` 会失败,游戏可以提示选择不同的账户。

### 实现

要使用 SPoP,请实现一个回调函数并注册它:

```cpp theme={null}
HRESULT hr = XUserPlatformSpopPromptSetEventHandlers(nullptr, &OnSpopPrompt, nullptr);
```

在 `OnSpopPrompt` 处理程序中,游戏会收到用户标识符和现代玩家代号。处理程序应暂停游戏流程(因为登录处于挂起状态),并呈现带有选项的 UI 提示。处理程序保存操作句柄,不立即完成它。

当用户做出选择时:

```cpp theme={null}
// If user chose "Play here"
XUserPlatformSpopPromptComplete(operation, XUserPlatformSpopOperationResult::SignInHere);

// If user chose "Switch account"
XUserPlatformSpopPromptComplete(operation, XUserPlatformSpopOperationResult::SwitchAccount);

// If dialog was canceled
XUserPlatformSpopPromptComplete(operation, XUserPlatformSpopOperationResult::Canceled);
```

> [!NOTE]
>
> * 在调用 `XUserAddAsync` 之前调用 `XUserPlatformSpopPromptSetEventHandlers`,以确保正确处理冲突。
> * 对每个收到的 SPoP 事件,必须精确地调用 `XUserPlatformSpopPromptComplete` 一次,否则登录会无限期挂起。
> * 如果未设置处理程序且发生冲突,`XUserAddAsync` 将以错误代码失败,让用户没有机会顺畅地解决冲突。

### 用户体验注意事项

为提供良好的用户体验:

* **清晰的信息** —— 显示用户的玩家代号,并清楚地说明继续操作会在另一台设备上将其注销。
* **可见的选项** —— 让“在此处游玩”和“切换账户”这两个选项清晰可见、易于理解。
* **防止存档冲突** —— 强调这样做可以防止游戏存档冲突和并发游玩问题。
* **平台特定行为** —— 在 XBOX 和 Windows 上,操作系统会自动处理这些情况,SPoP 处理程序永远不会被调用。在其他平台上,你的游戏负责呈现此选择。

如果没有此 API,登录冲突会导致模糊的错误或未经警告的自动注销,带来糟糕的用户体验。SPoP 提示使行为变得显式且由用户驱动,与 XBOX 的单会话政策一致,同时让玩家有掌控权。

## 另请参见

[用户身份与 XUser](/zh-CN/build/core-features/common/user/player-identity-xuser)


## Related topics

- [GDK 中的用户身份与 XUser API](/zh-CN/build/core-features/common/user/index.md)
- [语音音频噪声抑制](/zh-CN/services/playfab/community/voice-communications/concepts-noise-suppression.md)
- [使用实时音频操作应用自定义语音效果](/zh-CN/services/playfab/community/voice-communications/concepts-realtime-audio-manipulation.md)
- [账户身份验证和访问概述](/zh-CN/services/xbox-services/fundamentals/identity/auth/live-authentication-overview.md)
- [适用于 XBOX 服务游戏的 PlayFab 集成](/zh-CN/services/xbox-services/playfab-integration.md)
