次の方法で共有


サーバー バックフィル チケットの使用 - マルチプレイヤー SDK

サーバーでホストされているゲームでは、追加のプレイヤーの検索が必要な場合があります。 ほとんどの場合、ゲームの進行中に 1 人または複数のプレイヤーが切断されたときにプレイヤーの検索が発生します。 サーバー バックフィル チケットを使用すると、ゲーム サーバーは、現在プレイ中のゲームに適切な追加のプレイヤーを検索できます。

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

  1. マッチング
    • バックフィル チケットは互いに一致できません。
    • バックフィル チケットは検索中に優先され、プレイヤー ベースの断片化が減少します。
  2. コントラクト
    • バックフィル チケットは、ServerDetails フィールドを使用して作成できます。 これにより、サーバーは、マッチしたプレイヤーがどのように接続するかを表示できます。
    • バックフィル チケットは、チームの割り当てを使用して作成できます。 これにより、ゲーム チームはチームの情報を保持できるようになります。
  3. キュー プロパティ
  4. 所有権
    • バックフィル チケットは、ユーザーではなく、ゲーム サーバーによって所有されます。 ユーザーは、バックフィル チケットを表示または操作することはできません。

前提条件

  • PlayFab マルチプレイヤー SDK に関する基本的な知識。 詳細については、マッチメイキング SDK クイックスタートを参照してください。
  • マッチメイキング ヘッダーを含める前に PFMULTIPLAYER_INCLUDE_SERVER_APIS を定義します。 次に例を示します。
#define PFMULTIPLAYER_INCLUDE_SERVER_APIS
#include <PFMatchmaking.h>

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

PFMatchmakingServerBackfillTicketConfiguration 構造体を作成し、必要な詳細を設定します:

  • timeoutInSeconds: チケットの入力を試行する時間 (秒単位)。

  • queueName: 一致キューの名前。

  • memberCount: 現在一致しているメンバーの数。

  • members: 現在一致しているPFMatchmakingMatchMember メンバー。

  • serverDetails (省略可能): PFMultiplayerServerDetails クライアントに提供されるサーバー (FQDN、IP アドレス、ポート、リージョン) に関する情報を入力します。

注意

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

// 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 を使用してサーバー バックフィル チケットを作成するには、前の手順で作成したバックフィル構成と共にゲーム サーバーのエンティティ (PFEntityKey) を渡す必要があります。

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 を呼び出して状態の変更を受け取り、これらの状態変更の処理が完了したら PFMultiplayerFinishProcessingMatchmakingStateChanges を呼び出して、チケットの更新をチェックする必要があります。

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

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 を呼び出して一致の詳細を取得します。 これらの詳細には、一致 ID、一緒に一致したユーザー、一致の優先リージョン、一致に関連付けられたロビーの並べ替え文字列が含まれます。

PFMatchmakingMatchDetails 構造体から必要な情報を取得したら、PFMultiplayerDestroyMatchmakingTicket でチケットを破棄する必要があります。

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 を呼び出します。

この API を呼び出しても、チケットが取り消されることが保証されるわけではありません。 取り消しを処理する前に引き続きチケットが完了する可能性があります。または、ネットワークまたはサービス エラーが原因でキャンセル要求が失敗する可能性があります。 続行する前にチケットの取り消しが完了したことを確認する場合は、マッチメイキング状態の変更を処理してチケットの結果を取得することもできます。 それ以外の場合は、PFMultiplayerDestroyMatchmakingTicket をすぐに呼び出すことができます。

HRESULT hr = PFMatchmakingTicketCancel(ticket);

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);