Freigeben über


Verwenden von Serverbackfill Tickets – Multiplayer SDK

Spiele, die auf einem Server gehostet werden, finden manchmal, dass sie nach zusätzlichen Spielern suchen müssen. Am häufigsten tritt dies auf, wenn ein oder mehrere Spieler die Verbindung trennen, während das Spiel ausgeführt wird. Server-Backfill-Tickets ermöglichen es einem Spielserver, nach zusätzlichen Spielern zu suchen, die in das gerade gespielte Spiel passen.

Serverbackfill-Tickets unterscheiden sich in vielerlei Hinsicht von regulären Matchmaking-Tickets:

  1. Passend
    • Backfill-Tickets können nicht miteinander übereinstimmen.
    • Backfill-Tickets werden während der Suche prioritär festgelegt, wodurch die Fragmentierung der Spielerbasis reduziert wird.
  2. Vertrag
    • Backfill-Tickets können mit einem ServerDetails Feld erstellt werden. Dadurch kann der Server angeben, wie übereinstimmende Spieler eine Verbindung mit dem Server herstellen sollen.
    • Backfill-Tickets können mit Teamzuweisungen erstellt werden. Dadurch können Spiele mit Teams ihre Teaminformationen verwalten.
  3. Warteschlangeneigenschaften
  4. Besitzer
    • Backfill-Tickets sind im Besitz eines Spieleservers und nicht eines Benutzers. Benutzer können Keine Rückfülltickets anzeigen oder damit interagieren.

Voraussetzungen

  • Grundlegende Vertrautheit mit dem PlayFab Multiplayer SDK. Weitere Informationen finden Sie im Schnellstart zum Matchmaking SDK .
  • Definieren Sie PFMULTIPLAYER_INCLUDE_SERVER_APIS , bevor Sie den Matchmaking-Header einschließen. Beispiel:
#define PFMULTIPLAYER_INCLUDE_SERVER_APIS
#include <PFMatchmaking.h>

Konfigurieren eines Serverbackfill-Tickets

Erstellen Sie eine PFMatchmakingServerBackfillTicketConfiguration-Struktur , und füllen Sie sie mit den erforderlichen Details auf:

  • timeoutInSeconds: Gibt an, wie lange versucht werden soll, das Ticket zu füllen, in Sekunden.

  • queueName: Der Name einer Übereinstimmungswarteschlange.

  • memberCount: Die Anzahl der Mitglieder, die sich derzeit in der Übereinstimmung befindet.

  • members: Die PFMatchmakingMatchMember-Mitglieder , die sich derzeit in der Übereinstimmung befindet.

  • serverDetails (optional): Füllen Sie PFMultiplayerServerDetails mit Informationen zu Ihrem Server (FQDN, IP-Adresse, Ports, Region) auf, die clients bereitgestellt werden.

Notiz

Das PFMultiplayerServerDetails::ipv4Address Feld wird nicht überprüft und kann verwendet werden, um beliebige Verbindungszeichenfolge Informationen für Clients bereitzustellen.

// 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

Erstellen eines Serverbackfill-Tickets

Wenn Sie PFMultiplayerCreateServerBackfillTicket verwenden, um ein Serverbackfill-Ticket zu erstellen, müssen wir die Entität des Spielservers (als PFEntityKey) zusammen mit der Im vorherigen Schritt erstellten Abgleichskonfiguration übergeben.

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
}

Überprüfen der status des Matchmaking-Tickets

Sie müssen nach Updates für das Ticket suchen, indem Sie PFMultiplayerStartProcessingMatchmakingStateChanges aufrufen, um Zustandsänderungen zu empfangen, und dann PFMultiplayerFinishProcessingMatchmakingStateChanges aufrufen, wenn Sie mit der Verarbeitung dieser Zustandsänderungen fertig sind.

Das SDK gibt eine TicketStatusChanged-Zustandsänderung zurück, wenn sich die status des Tickets ändert, und eine TicketCompleted-Zustandsänderung, wenn die Matchmaking abgeschlossen ist.

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;  
}  

Abrufen der Übereinstimmung

Nachdem Sie die Zustandsänderung PFMatchmakingStateChangeType::TicketCompleted erhalten haben, rufen Sie PFMatchmakingTicketGetMatch auf, um die Details der Übereinstimmung abzurufen. Diese Details enthalten die Übereinstimmungs-ID, die Benutzer, die zusammen abgeglichen wurden, und die bevorzugte Region für die Übereinstimmung sowie eine Anordnungszeichenfolge für den Wartebereich, der der Übereinstimmung zugeordnet ist.

Nachdem Sie alle benötigten Informationen aus der PFMatchmakingMatchDetails-Struktur abgerufen haben, sollte das Ticket mit PFMultiplayerDestroyMatchmakingTicket gelöscht werden.

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

Stornieren eines Tickets

Wenn Sie den Matchmaking-Prozess vor dem in PFMatchmakingServerBackfillTicketConfigurationfestgelegten Timeout abbrechen möchten, rufen Sie PFMatchmakingTicketCancel mit dem Tickethandle auf.

Das Aufrufen dieser API garantiert nicht, dass das Ticket storniert wird. Das Ticket kann trotzdem abgeschlossen werden, bevor die Stornierung verarbeitet werden kann, oder die Stornierungsanforderung kann aufgrund von Netzwerk- oder Dienstfehlern fehlschlagen. Sie können weiterhin Änderungen des Matchmakingzustands verarbeiten, um das Ergebnis des Tickets zu erhalten, wenn Sie bestätigen möchten, dass die Ticketstornierung abgeschlossen ist, bevor Sie fortfahren. Andernfalls können Sie PFMultiplayerDestroyMatchmakingTicket sofort aufrufen.

HRESULT hr = PFMatchmakingTicketCancel(ticket);

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);