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

# 快速入门 (Windows) - Core SDK 设置

> 将 PlayFab 统一 SDK 添加到 Windows 项目、初始化 Core，并通过 XBOX 或 Steam 对玩家进行身份验证以获取 PFEntityHandle。

本指南向您展示如何将 PlayFab 统一 SDK 集成到 Windows 项目中、初始化 SDK 并对玩家进行身份验证。这是进行 PlayFab API 调用的基础。

## 先决条件

在开始之前，请完成[快速入门设置](/services/playfab/sdks/unified-sdk/quickstart-setup)中的设置步骤，以配置您的开发环境和项目。

## 您将完成的内容

在本快速入门结束时，您将：

* 在 Windows 项目中设置了 PlayFab 统一 SDK
* 使用您的 Title ID 初始化了 SDK
* 使用 XBOX 或 Steam 对玩家进行了身份验证
* 获取了用于进行 API 调用的实体句柄
* 正确清理了资源

## 本快速入门内容

1. [初始化 SDK](#step-1-initialize-the-sdk)
2. [对玩家进行身份验证](#step-2-authenticate-a-player)
3. [清理资源](#step-3-clean-up-resources)

## 步骤 1：初始化 SDK

### 包含所需的头文件

首先在项目中包含必要的 PlayFab 和 XBOX Game Runtime 头文件：

```cpp theme={null}
#include <playfab/core/PFCore.h>
#include <XGameRuntimeInit.h>
```

### 初始化 XBOX Gaming Runtime Services

PlayFab 统一 SDK 需要 XBOX Game Runtime。首先初始化它：

```cpp theme={null}
HRESULT hr = XGameRuntimeInitialize();
if (FAILED(hr))
{
    std::wcerr << L"Failed to initialize Xbox Game Runtime: 0x" << std::hex << hr << std::endl;
    return hr;
}
std::wcout << L"Xbox Game Runtime initialized successfully." << std::endl;
```

### 初始化 PlayFab Core

初始化 PlayFab SDK 并创建服务配置句柄。将 `ABCDEF` 替换为您实际的 PlayFab Title ID：

```cpp theme={null}
// Initialize PlayFab
HRESULT hr = PFInitialize(nullptr);
if (FAILED(hr))
{
    std::wcerr << L"Failed to initialize PlayFab: 0x" << std::hex << hr << std::endl;
    return hr;
}

// Create service configuration handle
PFServiceConfigHandle serviceConfigHandle{ nullptr };
hr = PFServiceConfigCreateHandle(
    "https://ABCDEF.playfabapi.com", // Replace ABCDEF with your Title ID
    "ABCDEF",                        // Replace ABCDEF with your Title ID
    &serviceConfigHandle);
if (FAILED(hr))
{
    std::wcerr << L"Failed to create service config handle: 0x" << std::hex << hr << std::endl;
    return hr;
}
std::wcout << L"PlayFab initialized successfully." << std::endl;
```

<Tip>
  您可以在 [Game Manager 控制面板](https://developer.playfab.com)的游戏设置中找到您的 Title ID。
</Tip>

## 步骤 2：对玩家进行身份验证

PlayFab 要求在进行 API 调用之前完成玩家身份验证。SDK 提供了多种身份验证方法，取决于您的平台和需求。

### 选择身份验证方法

#### 选项 A：使用 XBOX 登录（推荐用于 Windows/XBOX）

使用 `PFAuthenticationLoginWithXUserAsync` 通过 XBOX 用户账户登录。这是 Windows 和 XBOX 应用程序推荐的方法。

```cpp theme={null}
// Assume you have obtained an XUserHandle (userHandle) through XUser APIs
// For details on obtaining XUserHandle, see the Xbox Game Development Kit documentation

PFAuthenticationLoginWithXUserRequest request{};
request.createAccount = true;  // Create account if it doesn't exist
request.user = userHandle;     // XUserHandle obtained from Xbox user APIs

XAsyncBlock async{};
HRESULT hr = PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, &request, &async);
if (FAILED(hr))
{
    std::wcerr << L"Failed to start Xbox login: 0x" << std::hex << hr << std::endl;
    return hr;
}

// Wait for login to complete
hr = XAsyncGetStatus(&async, true); // Blocking wait
if (FAILED(hr))
{
    std::wcerr << L"Xbox login failed: 0x" << std::hex << hr << std::endl;
    return hr;
}

// Get the result
std::vector<char> loginResultBuffer;
PFAuthenticationLoginResult const* loginResult;
size_t bufferSize;
hr = PFAuthenticationLoginWithXUserGetResultSize(&async, &bufferSize);
if (SUCCEEDED(hr))
{
    loginResultBuffer.resize(bufferSize);
    PFEntityHandle entityHandle{ nullptr };
    hr = PFAuthenticationLoginWithXUserGetResult(&async, &entityHandle, 
        loginResultBuffer.size(), loginResultBuffer.data(), &loginResult, nullptr);
    
    if (SUCCEEDED(hr))
    {
        std::wcout << L"Successfully logged in with Xbox. Player ID: " 
                   << loginResult->playFabId << std::endl;
        // entityHandle is now ready for making API calls
    }
}
```

#### 选项 B：使用 Steam 登录

对于集成 Steam 的游戏，使用 `PFAuthenticationLoginWithSteamAsync` 并附带 Steam 身份验证票据。

```cpp theme={null}
// Assume you have obtained a Steam ticket through Steam APIs
PFAuthenticationLoginWithSteamRequest request{};
request.createAccount = true;         // Create account if it doesn't exist
request.steamTicket = steamTicket;    // Steam authentication ticket

XAsyncBlock async{};
HRESULT hr = PFAuthenticationLoginWithSteamAsync(serviceConfigHandle, &request, &async);
if (FAILED(hr))
{
    std::wcerr << L"Failed to start Steam login: 0x" << std::hex << hr << std::endl;
    return hr;
}

// Wait for login to complete
hr = XAsyncGetStatus(&async, true);
if (FAILED(hr))
{
    std::wcerr << L"Steam login failed: 0x" << std::hex << hr << std::endl;
    return hr;
}

// Get the result
std::vector<char> loginResultBuffer;
PFAuthenticationLoginResult const* loginResult;
size_t bufferSize;
hr = PFAuthenticationLoginWithSteamGetResultSize(&async, &bufferSize);
if (SUCCEEDED(hr))
{
    loginResultBuffer.resize(bufferSize);
    PFEntityHandle entityHandle{ nullptr };
    hr = PFAuthenticationLoginWithSteamGetResult(&async, &entityHandle, 
        loginResultBuffer.size(), loginResultBuffer.data(), &loginResult, nullptr);
    
    if (SUCCEEDED(hr))
    {
        std::wcout << L"Successfully logged in with Steam. Player ID: " 
                   << loginResult->playFabId << std::endl;
        // entityHandle is now ready for making API calls
    }
}
```

<Note>
  从登录返回的 `PFEntityHandle` 是所有后续 PlayFab API 调用所必需的。请在应用程序的整个生命周期内保留此句柄。
</Note>

## 步骤 3：清理资源

当应用程序关闭时，正确清理所有资源以防止内存泄漏并确保正常终止：

```cpp theme={null}
// Clean up in reverse order of initialization

// 1. Close the entity handle
if (entityHandle)
{
    PFEntityCloseHandle(entityHandle);
    entityHandle = nullptr;
    std::wcout << L"Entity handle closed." << std::endl;
}

// 2. Close the service config handle
if (serviceConfigHandle)
{
    PFServiceConfigCloseHandle(serviceConfigHandle);
    serviceConfigHandle = nullptr;
    std::wcout << L"Service config handle closed." << std::endl;
}

// 3. Uninitialize PlayFab
XAsyncBlock async{};
HRESULT hr = PFUninitializeAsync(&async);
if (SUCCEEDED(hr))
{
    hr = XAsyncGetStatus(&async, true); // Wait for completion
    if (SUCCEEDED(hr))
    {
        std::wcout << L"PlayFab uninitialized successfully." << std::endl;
    }
    else
    {
        std::wcerr << L"PlayFab uninitialization failed: 0x" << std::hex << hr << std::endl;
    }
}

std::wcout << L"Cleanup complete." << std::endl;
```

<Info>
  始终按照初始化的相反顺序清理资源，以确保正确关闭。
</Info>

## 后续步骤

现在您已初始化 SDK 并对玩家进行了身份验证，可以开始调用 PlayFab 服务：

### 进行第一次 API 调用

* **[调用 PlayFab 服务](/services/playfab/sdks/unified-sdk/quickstart-services)** - 学习如何调用 PlayFab API 来管理玩家数据和使用游戏服务

### 核心概念

* [异步操作](/services/playfab/sdks/unified-sdk/async-model) - 了解 PlayFab 的异步编程模型
* [内存管理](/services/playfab/sdks/unified-sdk/memory-management) - 管理 SDK 内存的最佳实践
* [跟踪与诊断](/services/playfab/sdks/unified-sdk/debug-trace) - 调试和监控您的集成

### 高级身份验证

* **多平台身份验证** - 支持多种身份验证提供商
* **自定义 ID 身份验证** - 使用您自己的身份验证系统
* **账户链接** - 将多种身份验证方式链接到一个账户

### 故障排除

**常见问题及解决方案：**

| 问题         | 解决方案                                          |
| ---------- | --------------------------------------------- |
| 链接错误       | 确保所有必需的 `.lib` 文件已添加到 Additional Dependencies |
| 运行时 DLL 错误 | 将所需的 `.dll` 文件复制到您的输出目录                       |
| 身份验证失败     | 验证您的 Title ID 并检查网络连接                         |
| API 调用失败   | 启用跟踪以查看详细错误信息                                 |

## 参考文档

* [PlayFab 统一 SDK API 参考](/services/playfab/api-references/c/pfauthentication/pfauthentication_members)
* [PlayFab Services API 参考](/services/playfab/api-references)
* [XBOX Game Development Kit 文档](https://docs.microsoft.com/gaming/gdk/)


## Related topics

- [快速入门 (Windows) - 调用 PlayFab 服务](/zh-CN/services/playfab/sdks/unified-sdk/quickstart-services.md)
- [PlayFab 统一 SDK 快速入门设置](/zh-CN/services/playfab/sdks/unified-sdk/quickstart-setup.md)
- [适用于 Windows 的 C++ 快速入门](/zh-CN/services/playfab/sdks/playfab-cpp/quickstart-windows.md)
- [快速入门 (Windows) - Party 和 Multiplayer](/zh-CN/services/playfab/sdks/unified-sdk/quickstart-windows-party.md)
- [Lobby SDK 快速入门](/zh-CN/services/playfab/multiplayer/lobby/lobby-getting-started.md)
