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

# Using Server Backfill Tickets - Multiplayer SDK

> Multiplayer SDK を使用して PlayFab のサーバー バックフィル チケットを作成し、進行中のマッチメイキング ゲーム セッションの空き枠を埋める方法について説明します。

サーバー上でホストされているゲームでは、追加のプレイヤーを探す必要が生じることがあります。多くの場合、これはゲームが進行中に 1 人以上のプレイヤーが切断したときに起こります。サーバー バックフィル チケットにより、ゲーム サーバーは現在プレイ中のゲームに適合する追加のプレイヤーを検索できます。

サーバー バックフィル チケットは、通常のマッチメイキング チケットとは以下の点で異なります。

1. マッチング
   * バックフィル チケットは互いにマッチできません。
   * バックフィル チケットは検索時に優先されるため、プレイヤーベースの断片化を軽減します。
2. コントラクト
   * バックフィル チケットは `ServerDetails` フィールド付きで作成できます。これによりサーバーは、マッチしたプレイヤーがどのように接続すべきかを示すことができます。
   * バックフィル チケットはチーム割り当てを伴って作成できます。これによりチームのあるゲームでは、チーム情報を維持できます。
3. キューのプロパティ
   * バックフィル チケットは [Multiplayer Server の割り当て](/services/playfab/multiplayer/matchmaking/multiplayer-servers) をトリガーしません。
   * バックフィル チケットは [キュー統計](/services/playfab/multiplayer/matchmaking/display-statistics) には反映されません。これは、それらのプレイヤーは既にゲームをプレイ中であり、待ち時間を不正確に偏らせるためです。
4. 所有権
   * バックフィル チケットはユーザーではなく、ゲーム サーバーが所有します。ユーザーはバックフィル チケットを表示したり操作したりすることはできません。

## 前提条件

* PlayFab Multiplayer SDK の基本的な理解。詳細については、[マッチメイキング SDK クイックスタート](/services/playfab/multiplayer/matchmaking/quickstart-client-sdk) を参照してください。
* マッチメイキング ヘッダーを含める前に `PFMULTIPLAYER_INCLUDE_SERVER_APIS` を定義してください。例:

```cpp theme={null}
#define PFMULTIPLAYER_INCLUDE_SERVER_APIS
#include <PFMatchmaking.h>
```

## サーバー バックフィル チケットを構成する

必要な詳細を [PFMatchmakingServerBackfillTicketConfiguration](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmatchmakingserverbackfillticketconfiguration) 構造体に作成して設定します。

* **`timeoutInSeconds`**: チケットを埋めようとする時間 (秒単位)。

* **`queueName`**: マッチ キューの名前。

* **`memberCount`**: 現在マッチに含まれるメンバー数。

* **`members`**: 現在マッチに含まれる [PFMatchmakingMatchMember](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmatchmakingmatchmember) のメンバー。

* **`serverDetails`** (任意): クライアントに提供されるサーバー情報 (FQDN、IP アドレス、ポート、リージョン) を [PFMultiplayerServerDetails](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmultiplayerserverdetails) に設定します。

<Note>
  `PFMultiplayerServerDetails::ipv4Address` フィールドは検証されず、クライアントに任意の接続文字列情報を提供するために使用できます。
</Note>

```cpp theme={null}
// Define the server port configuration.
PFMultiplayerPort serverPorts[] = {
    { "portname", 12345, PFMultiplayerProtocolType::Udp }
};

// Populate the server details.
PFMultiplayerServerDetails serverDetails = {};
serverDetails.fqdn = "your.server.fqdn.com";
serverDetails.ipv4Address = "123.234.123.234";
serverDetails.ports = serverPorts;
serverDetails.portCount = sizeof(serverPorts) / sizeof(serverPorts[0]);
serverDetails.region = "EastUS";

// Set up the backfill ticket configuration.
PFMatchmakingServerBackfillTicketConfiguration backfillConfig = {};
backfillConfig.timeoutInSeconds = 60;                 // Try for 60 seconds
backfillConfig.queueName = "YourQueueName";
backfillConfig.memberCount = currentMatchMemberCount; // e.g., 4
backfillConfig.members = currentMatchMembers;         // Pointer to an array of PFMatchmakingMatchMember
backfillConfig.serverDetails = &serverDetails;        // Optional; can be nullptr if not needed
```

## サーバー バックフィル チケットを作成する

[PFMultiplayerCreateServerBackfillTicket](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayercreateserverbackfillticket) を使用してサーバー バックフィル チケットを作成するには、前のステップで作成したバックフィル構成とともに、ゲーム サーバーのエンティティ ([PFEntityKey](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmultiplayer/pfentitykey_clientsdk) として) を渡す必要があります。

```cpp theme={null}
PFMatchmakingTicketHandle backfillTicket = nullptr;
HRESULT hr = PFMultiplayerCreateServerBackfillTicket(
    multiplayerHandle,            // The handle of the PFMultiplayer API instance.
    &serverEntity,                // PFEntityKey for your game server entity
    &backfillConfig,              // The backfill ticket configuration.
    nullptr,                      // Optional async context
    &backfillTicket               // The resulting ticket object.
);

if (FAILED(hr))
{
    // handle ticket creation failure
}
```

## マッチメイキング チケットのステータスを確認する

チケットの更新を確認するには、[PFMultiplayerStartProcessingMatchmakingStateChanges](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerstartprocessingmatchmakingstatechanges) を呼び出して状態変更を受信し、それらの状態変更の処理が終わったら [PFMultiplayerFinishProcessingMatchmakingStateChanges](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerfinishprocessingmatchmakingstatechanges) を呼び出す必要があります。

SDK は、チケットのステータスが変わるたびに **TicketStatusChanged** 状態変更を返し、マッチメイキングが完了したときに **TicketCompleted** 状態変更を返します。

```cpp theme={null}
HRESULT hrTicketError = S_OK;

uint32_t stateChangeCount;
const PFMatchmakingStateChange * const * stateChanges;
HRESULT hr = PFMultiplayerStartProcessingMatchmakingStateChanges(g_pfmHandle, &stateChangeCount, &stateChanges);
if (FAILED(hr))  
{  
    return;  
}  

for (uint32_t i = 0; i < stateChangeCount; ++i)
{
    const PFMatchmakingStateChange& stateChange = *stateChanges[i];

    switch (stateChange.stateChangeType)
    {
        case PFMatchmakingStateChangeType::TicketStatusChanged:
        {
            const auto& ticketStatusChanged = static_cast<const PFMatchmakingTicketStatusChangedStateChange&>(stateChange);

            PFMatchmakingTicketStatus status;
            if (SUCCEEDED(PFMatchmakingTicketGetStatus(ticketStatusChanged.ticket, &status)))
            {
                printf("Ticket status is now: %i.\n", status);
            }

            break;
        }
        case PFMatchmakingStateChangeType::TicketCompleted:
        {
            const auto& ticketCompleted = static_cast<const PFMatchmakingTicketCompletedStateChange&>(stateChange);

            printf("PFMatchmaking completed with Result 0x%08x.\n", ticketCompleted.result);

            if (FAILED(ticketCompleted.result))
            {
                // On failure, we must record the HRESULT so we can return the state change(s) and then bail
                // out of this function.
                hrTicketError = ticketCompleted.result;
            }

            break;
        }
    }
}

hr = PFMultiplayerFinishProcessingMatchmakingStateChanges(g_pfmHandle, stateChangeCount, stateChanges);
if (FAILED(hr))  
{  
    return;  
}  

// Now that we've returned the state change(s), bail out if we detected ticket failure.
if (FAILED(hrTicketError))  
{  
    return;  
}  
```

## マッチを取得する

**PFMatchmakingStateChangeType::TicketCompleted** 状態変更を受信した後、[PFMatchmakingTicketGetMatch](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmatchmakingticketgetmatch) を呼び出してマッチの詳細を取得します。これらの詳細には、マッチ ID、マッチした状態のユーザー、そのマッチに推奨されるリージョン、およびマッチに関連付けられたロビーの arrangement string が含まれます。

**PFMatchmakingMatchDetails** 構造体から必要な情報を取得したら、[PFMultiplayerDestroyMatchmakingTicket](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerdestroymatchmakingticket) でチケットを破棄する必要があります。

```cpp theme={null}
const PFMatchmakingMatchDetails* match;
HREULT hr = PFMatchmakingTicketGetMatch(ticket, &match);
if (FAILED(hr))  
{  
    return;  
}  

std::string matchId = match->matchId;
std::string lobbyArrangementString = match->lobbyArrangementString;

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
```

## チケットをキャンセルする

`PFMatchmakingServerBackfillTicketConfiguration` で設定したタイムアウト前にマッチメイキング処理をキャンセルしたい場合は、チケット ハンドルを指定して [PFMatchmakingTicketCancel](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmatchmakingticketcancel) を呼び出します。

この API を呼び出しても、チケットがキャンセルされることは保証されません。キャンセルが処理される前にチケットが完了する場合や、ネットワークやサービスのエラーによりキャンセル要求が失敗する場合があります。次に進む前にチケットのキャンセルが完了したことを確認したい場合は、引き続きマッチメイキングの状態変更を処理してチケットの結果を取得できます。それ以外の場合は、即座に [PFMultiplayerDestroyMatchmakingTicket](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerdestroymatchmakingticket) を呼び出すことができます。

```cpp theme={null}
HRESULT hr = PFMatchmakingTicketCancel(ticket);

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
```


## Related topics

- [Using Server Backfill Tickets - REST API](/ja-jp/services/playfab/multiplayer/matchmaking/backfill-tickets.md)
- [CreateServerBackfillTicket](/ja-jp/services/playfab/multiplayer/lobby/unity-multiplayer-api-reference/PlayFab.Multiplayer/PlayFabMultiplayer.PlayFabMultiplayerServer/CreateServerBackfillTicket.md)
- [PFMultiplayerCreateServerBackfillTicket](/ja-jp/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayercreateserverbackfillticket.md)
- [PFMatchmakingServerBackfillTicketConfiguration](/ja-jp/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmatchmakingserverbackfillticketconfiguration.md)
- [PlayFab リリースノート 2020](/ja-jp/services/playfab/release-notes/2020.md)
