Xbox 服务 API (XSAPI) 入门

初始化游戏运行时服务。

XSAPI 依赖于游戏运行时服务 (GRTS)。 在调用任何 XSAPI 之前,初始化 GRTS,如下所示。

#include <XGameRuntimeInit.h>
...
HRESULT hr = XGameRuntimeInitialize();

创建 XTaskQueue(可选)

大多数 XSAPI 是异步 API,需要使用任务队列。 它是用于排队工作和完成任务回调的 API。 若要详细了解 XTaskQueue 和不同的调度模式,请参阅 异步任务队列设计

例如,下面的代码使用系统线程池创建一个任务队列。

#include <XTaskQueue.h>
...
XTaskQueueHandle queue = nullptr;

HRESULT hr = XTaskQueueCreate(
    XTaskQueueDispatchMode::ThreadPool,
    XTaskQueueDispatchMode::ThreadPool,
    &queue)

如果所获取的任务队列句柄已不再需要,请确保将其释放回系统。

XTaskQueueCloseHandle(queue);
queue = nullptr;

如果选择不创建自己的任务队列,请确保在需要队列句柄时传入 nullptr。 使用 nullptr 时,任务系统默认使用 ThreadPool。 可以通过调用 XTaskQueueSetCurrentProcessTaskQueue 来重写。

设置 HttpClient 跟踪(可选)

若要查看其他运行时调试信息,请确保设置 HttpClient 的跟踪功能。

以下代码设置 HttpClient 跟踪级别,并为调试程序信息启用输出:

HCSettingsSetTraceLevel(HCTraceLevel::Verbose);
HCTraceSetTraceToDebugger(true);

初始化 XSAPI

在调用任何 XSAPI 之前初始化 XSAPI

#include <xsapi-c/services-c.h>
...
XblInitArgs xblArgs = {};
xblArgs.queue = queue; // TODO: Only include this line if you've chosen to create your own XTaskQueue. Otherwise, by default, this line isn't needed.
xblArgs.scid = "00000000-0000-0000-0000-000000000000"; // TODO: Add your scid here.

HRESULT hr = XblInitialize(&xblArgs);
if (FAILED(hr))
{
    // TODO: Handle failure.
}

将用户登录到 Xbox 网络

大多数 XSAPI 要求用户首先登录到 Xbox 网络(也称为 Xbox Live)。
若要将用户登录到 Xbox 网络,请参阅 XUserAddAsync API 的代码示例。

创建 XboxLiveContext 对象

XboxLiveContext 对象表示与特定用户关联的服务上下文。

大多数 XSAPI 要求传入表示调用用户上下文的 XboxLiveContextHandle
若要创建 Xbox Live(网络)上下文,请使用 XblContextCreateHandle API,并传入从上一步获取的 XUserHandle 对象。

对 Xbox 服务进行服务调用

现在,你拥有与已登录用户 XUserHandle 对象关联的 XboxLiveContext 对象,你可以对 Xbox 服务进行服务调用。

例如,若要检索用户的朋友列表,可以执行以下操作:

#include <xsapi-c/services-c.h>
...
auto asyncBlock = std::make_unique<XAsyncBlock>(); 
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock*.

    XblSocialRelationshipResultHandle relationshipResult{ nullptr };
    HRESULT hr = XblSocialGetSocialRelationshipsResult(asyncBlock, &state.socialResultHandle);

    // Use the result in the game.

    XblSocialRelationshipResultCloseHandle(relationshipResult);
};

HRESULT hr = XblSocialGetSocialRelationshipsAsync(
    xboxLiveContext,
    xboxUserId,
    socialRelationshipFilter,
    0,
    0,
    asyncBlock.get()
);

if (SUCCEEDED(hr))
{
    // The call succeeded. Release the std::unique_ptr ownership of XAsyncBlock* because the callback will take over ownership.
    // If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock*.
    asyncBlock.release();
}
// End of code example.

清理 XSAPI

在任何方案中都不需要调用 XblCleanupAsync()

在应用终止方案中,目前没有可以调用的同步 XblCleanup() API。 应用终止(其生命周期性质)需要立即同步处理。 因此,这种情况需依赖于正常的操作系统级别清理(在应用程序进程终止时发生),且此类清理已经足够。

在应用挂起的情况下,XSAPI 处理释放和还原操作所需的系统资源,以便在恢复后保持功能。

XblCleanupAsync() 在你的游戏选择特意释放分配给 XSAPI 的资源的情况下,仍可使用。