> ## 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 のサンプル コード

> GDK タイトルからアクティビティの設定、招待の送信、最近のプレイヤー リストの更新を行うための XBOX Multiplayer Activity C++ クイックスタート例。

<a id="top" />

このトピックは、Multiplayer Activity クライアント API の基本的な使用方法のクイックスタート ガイドです。このトピックでは、アクティビティの管理、招待の送信、および最近のプレイヤー リストへのプレイヤーの追加について説明します。

[アクティビティ](#activities) [招待](#invites) [最近のプレイヤー](#recent-players)

<a id="activities" />

## アクティビティ

### アクティビティの設定

タイトルがマルチプレイヤー体験を開始または参加するときは常に、アクティビティを作成する必要があります。これを行うことにより、シェルは、タイトル内の他のプレイヤーと共に、プレイヤーのアクティビティを見ることができ、他のプレイヤーが進行中のゲームに参加できる可能性があります。プレイヤーがタイトルのアクティビティに参加したいときに、そのタイトルが実行されていない場合、タイトルがアクティブ化され、接続文字列が渡されます。

タイトルは、プレイヤーの参加または離脱時にアクティビティを更新する必要があります。これにより、他のプレイヤーにアクティビティのより充実した情報を提供し、アクティビティが満員かどうかを知らせることができます。

アクティビティ フィールドについては、[アクティビティの内容](/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 なしで招待を送信する

プレイヤーは、1 人以上の他のプレイヤーに直接招待を送信したい場合があります。招待を送信する前に、タイトルはアクティビティが設定されていることを確認する必要があります。これにより、シェルは現在のアクティビティに基づいて招待を送信するため、シェルとタイトルの間に一貫性が保たれます。

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 を使用して招待を送信する

プレイヤーは、1 人以上の他のプレイヤーに直接招待を送信したい場合があります。招待を送信する前に、タイトルはアクティビティが設定されていることを確認する必要があります。これにより、シェルは現在のアクティビティに基づいて招待を送信するため、シェルとタイトルの間に一貫性が保たれます。

UI を使用して招待を送信するには、[XblMultiplayerActivitySetActivityAsync](/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync) (前述の例を参照) を使用してアクティビティを設定した後、タイトルは要求元ユーザーを渡して [XGameUiShowMultiplayerActivityGameInviteAsync](/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteasync) API を呼び出す必要があります。この 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>
  何をもって意味のあるやり取りと定義するかは、あなたが決定できます。あるタイトルでは、ロビーに存在していることかもしれません。別のタイトルでは、プレイヤーが別のプレイヤーを撃つことかもしれません。3 番目のタイトルでは、他のプレイヤーが単に画面上に表示されているだけのことかもしれません。
</Note>

プレイヤーのチームがマッチ セッションが開始するまで見えないようにしたいシナリオでは、プレイヤーのリストの書き込みを、それらのプレイヤーを互いに見えるようにしたい時点まで遅らせることができます。クライアント側の最近のプレイヤー リストをフラッシュするには、即座に強制的にフラッシュする必要がある場合、`XblMultiplayerActivityFlushRecentPlayersAsync` を呼び出すことができます。そうでない場合、最近のプレイヤー リストは 5 秒ごとに自動的にフラッシュされます。

最近のプレイヤー リストの更新および更新のフラッシュのコード例は以下のとおりです。

### 最近のプレイヤーの更新

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