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

# Multiplayer Activity 示例代码

> XBOX Multiplayer Activity C++ 快速入门示例，用于从您的 GDK 游戏设置活动、发送邀请和更新最近玩家列表。

<a id="top" />

本主题旨在作为使用 Multiplayer Activity 客户端 API 基本用法的快速入门指南。本主题讨论管理活动、发送邀请以及将玩家添加到最近玩家列表。

[活动](#activities) [邀请](#invites) [最近玩家](#recent-players)

<a id="activities" />

## 活动

### 设置活动

每当游戏开始或加入多人游戏体验时，都应创建一个活动。这样做可以让 shell 以及您游戏中的其他玩家看到该玩家的活动，并允许其他玩家可能加入正在进行的游戏。如果玩家想要加入您游戏的活动而它没有运行，将启动它并将连接字符串传递给它。

当玩家加入或离开时，游戏应更新活动。这为其他玩家提供了活动的更丰富视图，并告知他们活动是否已满。

有关活动字段的信息，请参阅[活动内容](/services/xbox-services/multiplayer/mpa/concepts/live-mpa-activities#activity-contents)。

设置活动的代码示例如下。它同样适用于创建活动以及更新现有活动。

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

XblMultiplayerActivityInfo info{};
info.connectionString = "dummyConnectionString";
info.joinRestriction = XblMultiplayerActivityJoinRestriction::Followed;
info.maxPlayers = 10;
info.currentPlayers = 1;
info.groupId = "dummyGroupId";

HRESULT hr = XblMultiplayerActivitySetActivityAsync(
    xblContext,
    &info,
    false,
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

有关更多信息，请参阅以下内容：

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblMultiplayerActivityInfo](/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityinfo)
* [XblMultiplayerActivityJoinRestriction](/reference/live/xsapi-c/multiplayer_activity_c/enums/xblmultiplayeractivityjoinrestriction)
* [XblMultiplayerActivitySetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync)

[返回本主题顶部。](#top)

<a id="getting-an-activity" />

### 获取活动

游戏可能希望了解其他玩家的活动。例如，游戏可能希望显示游戏中好友及其活动的游戏内 UI。

检索活动的代码示例如下。

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.

    size_t resultSize{};
    HRESULT hr = XblMultiplayerActivityGetActivityResultSize(async, &resultSize);
    if (SUCCEEDED(hr))
    {
        std::vector<uint8_t> buffer(resultSize);
        XblMultiplayerActivityInfo* activityInfo{};
        size_t resultCount{};
        hr = XblMultiplayerActivityGetActivityResult(async, buffer.size(), buffer.data(), &activityInfo, &resultCount, nullptr);
        if (SUCCEEDED(hr))
        {
            // ...
        }
    }
};

HRESULT hr = XblMultiplayerActivityGetActivityAsync(
    xblContext,
    &xuid,
    1,
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

有关更多信息，请参阅以下内容：

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XblMultiplayerActivityGetActivityResultSize](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityresultsize)
* [XblMultiplayerActivityInfo](/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityinfo)
* [XblMultiplayerActivityGetActivityResult](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityresult)
* [XblMultiplayerActivityGetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityasync)

[返回本主题顶部。](#top)

### 删除活动

当玩家结束或离开多人游戏活动时，游戏应使用以下代码删除该活动。

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivityDeleteActivityAsync(xblContext, async.get());

if (SUCCEEDED(hr))
{
    async.release();
}
```

有关更多信息，请参阅以下内容：

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblMultiplayerActivityDeleteActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitydeleteactivityasync)

[返回本主题顶部。](#top)

<a id="invites" />

## 邀请

### 无 UI 发送邀请

玩家可能希望直接向一位或多位其他玩家发送邀请。发送邀请之前，游戏应确保已设置活动。这确保了 shell 与您游戏之间的连续性，因为 shell 根据当前活动发送邀请。

若要在无 UI 的情况下发送邀请，在使用 [XblMultiplayerActivitySetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync) 设置活动后（参见上面的示例），游戏应调用 [XblMultiplayerActivitySendInvitesAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysendinvitesasync) API，传入要邀请的玩家数组以及在当前活动中使用的相同连接字符串。

有关邀请内容的信息，请参阅[发送请求以邀请其他玩家加入多人游戏体验。](/services/xbox-services/multiplayer/mpa/concepts/live-mpa-invites)。

无 UI 发送邀请的代码示例如下。

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivitySendInvitesAsync(
    xblContext,
    &xuid,
    1,
    true, // Setting false will send the invite to only players on the sender's platform.
    "dummyConnectionString",
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

有关更多信息，请参阅以下内容：

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblMultiplayerActivitySendInvitesAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysendinvitesasync)

### 使用 UI 发送邀请

玩家可能希望直接向一位或多位其他玩家发送邀请。发送邀请之前，游戏应确保已设置活动。这确保了 shell 与您游戏之间的连续性，因为 shell 根据当前活动发送邀请。

若要使用 UI 发送邀请，在使用 [XblMultiplayerActivitySetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync) 设置活动后（参见上面的示例），游戏应调用 [XGameUiShowMultiplayerActivityGameInviteAsync](/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteasync) API，传入请求用户。它将使用游戏的当前活动，并使用其连接字符串和设置邀请玩家。

有关邀请内容的信息，请参阅[发送请求以邀请其他玩家加入多人游戏体验。](/services/xbox-services/multiplayer/mpa/concepts/live-mpa-invites)。

使用 UI 发送邀请的代码示例如下。

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XGameUiShowMultiplayerActivityGameInviteResult(async);
    if (hrAsync == S_OK) 
    { 
        // Handle success 
    } 
    else 
    { 
        // Likely will only happen during development - usually indicates 
        // an invalid user was passed in or that there is no multiplayer activity set
    }     
};

HRESULT hr = XGameUiShowMultiplayerActivityGameInviteAsync(
    async.get()
    requestingUser
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

有关更多信息，请参阅以下内容：

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XGameUiShowMultiplayerActivityGameInviteAsync](/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteasync)
* [XGameUiShowMultiplayerActivityGameInviteResult](/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteresult)

[返回本主题顶部。](#top)

### 接收邀请

若要在玩家接受邀请时得到通知，游戏可以使用 `XGameInviteRegisterForEvent` 注册邀请通知。每次接受邀请时，都会通过已注册的回调将格式化的 URI 传递给游戏。可以解析该 URI 以确定邀请发送者、接收者和连接字符串。连接字符串是游戏特定的，在创建多人游戏活动时设置。对于使用 Multiplayer Activity 服务的游戏，URI 的完整格式如下表所示。

| 平台                                                                            | 格式                                                                                                       |
| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| 主机上的 Microsoft Game Development Kit (GDK) 或 XBOX One Software Development Kit | `ms-xbl-<titleId>://inviteAccept?invitedUser=<xuid>&sender=<xuid>&connectionString=<connectionString>`   |
| PC 上的 Microsoft Game Development Kit (GDK) 或 Universal Windows Platform (UWP) | `ms-xbl-multiplayer://inviteAccept?invitedUser=<xuid>&sender=<xuid>&connectionString=<connectionString>` |

当不再需要邀请通知时，可以使用 `XGameInviteUnregisterForEvent` 取消注册回调。注册和处理已接受邀请的代码示例如下。

```cpp theme={null}
void CALLBACK MyXGameInviteEventCallback(
    _In_opt_ void* context,
    _In_ const char* inviteUri)
{
    if (inviteUri != nullptr)
    {
        std::string uri{ inviteUri };
        size_t invitedUserBegin = uri.find("invitedUser=");
        size_t senderBegin = uri.find("sender=");
        std::string invitedUser = uri.substr(invitedUserBegin, uri.find('&', invitedUserBegin) - invitedUserBegin);
        std::string sender = uri.substr(senderBegin, uri.find('&', senderBegin) - senderBegin);
        std::string connectionString = uri.substr(uri.find("connectionString="));

        // ...
    }
}

XTaskQueueRegistrationToken token = { 0 };
HRESULT hr = XGameInviteRegisterForEvent(
    queue,
    nullptr,
    MyXGameInviteEventCallback,
    &token
    );

// ...
bool result = XGameInviteUnregisterForEvent(token, true);
```

有关更多信息，请参阅以下内容：

* [XGameInviteRegisterForEvent](/reference/system/xgameinvite/functions/xgameinviteregisterforevent)
* [XGameInviteUnregisterForEvent](/reference/system/xgameinvite/functions/xgameinviteunregisterforevent)

[返回本主题顶部。](#top)

<a id="recent-players" />

## 最近玩家

若要更新玩家的最近玩家列表，游戏应提交与当前玩家有过有意义互动的其他玩家的列表。此列表是单向的，这意味着每个玩家的客户端负责更新自己的列表，玩家的列表不会影响其他人的列表。

例如，假设一组玩家一起在游戏前大厅中并已匹配。当比赛开始时，每位玩家都会用大厅中所有其他 `xuids` 更新其列表。如果有新玩家加入，可以将其单独写入。

<Note>
  您可以决定什么构成有意义的互动。对于一款游戏，它可能是在大厅中的存在。对于另一款游戏，它可能是一位玩家射击另一位玩家。对于第三款游戏，它可能仅仅是屏幕上出现了另一位玩家。
</Note>

在您可能不希望团队玩家在匹配会话开始前被看到的情况下，您可以延迟写入玩家列表，直到您希望他们彼此可见的时间。若要刷新客户端最近玩家列表，如果您需要立即强制刷新，可以调用 `XblMultiplayerActivityFlushRecentPlayersAsync`。否则，最近玩家列表每五秒自动刷新一次。

更新最近玩家列表和刷新更新的代码示例如下。

### 更新最近玩家

```cpp theme={null}
XblMultiplayerActivityRecentPlayerUpdate update{ xuid };
HRESULT hr = XblMultiplayerActivityUpdateRecentPlayers(xblContext, &update, 1);
```

有关更多信息，请参阅以下内容：

* [XblMultiplayerActivityRecentPlayerUpdate](/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityrecentplayerupdate)
* [XblMultiplayerActivityUpdateRecentPlayers](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivityupdaterecentplayers)

[返回本主题顶部。](#top)

### 刷新最近玩家

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivityFlushRecentPlayersAsync(xblContext, async.get());
if (SUCCEEDED(hr))
{
    async.release();
}
```

有关更多信息，请参阅以下内容：

* [XAsyncBlock](/reference/system/xasync/structs/xasyncblock)
* [XAsyncGetStatus](/reference/system/xasync/functions/xasyncgetstatus)
* [XblMultiplayerActivityFlushRecentPlayersAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivityflushrecentplayersasync)

[返回本主题顶部。](#top)


## Related topics

- [Multiplayer Activity 示例代码](/zh-CN/services/xbox-services/multiplayer/mpa/how-to/live-mpa-how-to-nav.md)
- [Multiplayer Manager 示例代码](/zh-CN/services/xbox-services/multiplayer/mpm/how-to/live-mm-howto-nav.md)
- [邀请示例代码](/zh-CN/services/xbox-services/multiplayer/invites/how-to/live-invites-howto-nav.md)
- [Rich Presence 示例代码](/zh-CN/services/xbox-services/community/presence/how-to/live-presence-howto-nav.md)
- [信誉示例代码](/zh-CN/services/xbox-services/community/reputation/how-to/live-reputation-howto-nav.md)
