> ## 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

遊戲執行階段內建於作業系統中，並由市集處理。您的遊戲會自動使用系統內建的服務和 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. **處理錯誤** – 檢查工具的結束代碼。如果失敗，請通知使用者並提供手動安裝指示。

<Info>
  Steam 遊戲必須包含 `XGameRuntime.dll` 及其相依性，以支援無法使用系統服務的平台 (例如 Steam Deck)。
  在 Steam Deck 或其他非 Microsoft 平台上，無法使用 Gaming Repair Tool。請改為將 `XGameRuntime.dll` 及其相依性搭配在遊戲套件中，並放在可執行檔旁邊，以便在執行階段載入。
</Info>

## 平台差異與統一 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 services、PlayFab 服務等)。

## 新的跨平台功能

為 XUser 引進的新 API 著重於實現與平台無關的登入流程和資料處理。主要功能包括：

### 遠端連線驗證

允許使用者使用第二部裝置，在某部裝置 (例如 Steam Deck) 上以其 XBOX 帳戶登入。使用者可以掃描 QR 代碼，或在網站上輸入一次性代碼來完成驗證。這是透過新的 XUser 事件處理常式來顯示及關閉以代碼為基礎的登入提示所達成。

### 單一工作階段強制執行 (SPoP)

確保使用者不會同時在多個位置執行相同的遊戲。如果偵測到衝突，系統會提示使用者選擇「在此遊玩」或「切換帳戶」。新的 API 可讓遊戲呈現此選擇並據以回應。

<Note>
  在 XBOX 主機和 Windows 上，作業系統會繼續自動處理大部分的驗證工作。在這些平台上，遊戲可能永遠不會看到這些事件。不過，在非 XBOX 平台上，遊戲可以透過 XUser 的回呼機制完全掌控。
</Note>

## 跨裝置登入的遠端連線

遠端連線 (Remote Connect) 功能可讓玩家透過另一部裝置 (例如手機或 PC) 進行驗證，以在某部裝置上登入其 XBOX 帳戶。這通常是透過遊戲顯示的短代碼或 QR 代碼來完成。

### 運作方式

在 XBOX 主機上，此「代碼流程」由系統 UI 自動處理。不過，在 Steam Deck 或其他協力廠商環境等平台上，並沒有系統管理的 XBOX 登入 UI。XUser 中的 Remote Connect API 可讓遊戲直接促成此流程。

#### 流程

1. **事件處理常式註冊** - 遊戲在開始登入之前，使用 `XUserPlatformRemoteConnectSetEventHandlers(...)` 註冊 Remote Connect 事件處理常式。遊戲會提供回呼來處理兩個主要事件：

   * **顯示事件** - 當 XUser 需要遊戲顯示一次性代碼或 QR 代碼時觸發。處理常式會呈現包含代碼和指示的對話方塊或重疊畫面 (例如：「掃描此 QR 代碼，或造訪 xbox.com/play 並輸入代碼 ABCD 以登入」)。

   * **關閉事件** - 當遠端登入程序完成或取消時觸發，通知遊戲隱藏或關閉代碼對話方塊。

2. **起始使用者登入** - 呼叫 `XUserAddAsync` 新增使用者時，如果尚未有本機使用者登入，XUser 系統可能會使用 Remote Connect 流程 (特別是在無周邊或協力廠商平台上)。

3. **顯示代碼** - XUser 叫用「顯示」回呼，提供驗證代碼或 URL。遊戲的 UI 處理常式 (例如 `OnRemoteConnectShow`) 會向使用者顯示 QR 代碼或代碼字串。

4. **使用者驗證** - 玩家使用手機或網頁瀏覽器，以提供的代碼登入，將其 XBOX 帳戶連結到目前的工作階段。

5. **完成** - 後端完成驗證後，XUser 會叫用「關閉」回呼，表示可以從畫面上移除代碼。此時，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` 時，表示登入程序已完成，遊戲應隱藏提示。

<Info>
  請在呼叫 `XUserAddAsync` 之前 (且通常在 `XUserInitialize` 之前) 呼叫 `XUserPlatformRemoteConnectSetEventHandlers`，以確保正確處理這些事件。
</Info>

### 使用者體驗考量

若要提供良好的使用者體驗：

* **清楚的指示** - 顯示代碼時，清楚說明使用者需要執行的動作。
* **錯誤處理** - 如果使用者在遠端取消或發生錯誤，XUser 會使登入嘗試失敗。請在 `XUserAddAsync` 的一般完成回呼中處理此情況。
* **及時關閉** - 發生關閉事件時立即隱藏代碼，以避免使用者混淆。
* **視覺設計** - 確保 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 提示，例如：「\[玩家代號] 已在另一部裝置上遊玩。您要改為在此遊玩 (這會從其他地方登出)，還是切換到其他帳戶？」並提供「在此遊玩」和「切換帳戶」等選項。

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);
```

<Info>
  * 請在呼叫 `XUserAddAsync` 之前呼叫 `XUserPlatformSpopPromptSetEventHandlers`，以確保正確處理衝突。
  * 對於收到的每個 SPoP 事件，您都必須呼叫 `XUserPlatformSpopPromptComplete` 剛好一次，否則登入會無限期停止回應。
  * 如果未設定處理常式而發生衝突，`XUserAddAsync` 會失敗並傳回錯誤碼，使用者將沒有機會妥善解決衝突。
</Info>

### 使用者體驗考量

若要提供良好的使用者體驗：

* **清楚的訊息** - 顯示使用者的玩家代號，並清楚說明繼續將會使其從另一部裝置登出。
* **明顯的選項** - 讓「在此遊玩」和「切換帳戶」兩個選項都清楚可見且易於理解。
* **避免存檔衝突** - 強調這可避免遊戲存檔衝突和同時遊玩的問題。
* **平台特定行為** - 在 XBOX 和 Windows 上，作業系統會自動處理此情況，永遠不會叫用 SPoP 處理常式。在其他平台上，您的遊戲負責呈現此選擇。

若沒有此 API，登入衝突會導致難以理解的錯誤，或在沒有警告的情況下自動登出，造成不良的使用者體驗。SPoP 提示讓此行為變得明確且由使用者主導，符合 XBOX 的單一工作階段原則，同時讓玩家擁有控制權。

## 另請參閱

[使用者身分識別和 XUser](/zh-TW/build/core-features/common/user/player-identity-xuser)


## Related topics

- [GDK 中的使用者身分識別與 XUser API](/zh-TW/build/core-features/common/user/index.md)
- [語音音訊雜訊抑制](/zh-TW/services/playfab/community/voice-communications/concepts-noise-suppression.md)
- [透過即時音訊操作套用自訂語音效果](/zh-TW/services/playfab/community/voice-communications/concepts-realtime-audio-manipulation.md)
- [帳戶驗證和存取概觀](/zh-TW/services/xbox-services/fundamentals/identity/auth/live-authentication-overview.md)
- [XBOX 服務遊戲的 PlayFab 整合](/zh-TW/services/xbox-services/playfab-integration.md)
