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

# Usando tíquetes de preenchimento de servidor - Multiplayer SDK

> Saiba como criar e usar tíquetes de preenchimento de servidor do PlayFab com o Multiplayer SDK para preencher vagas em uma sessão de jogo de matchmaking em andamento.

Jogos hospedados em um servidor às vezes precisam procurar jogadores
adicionais. Na maioria das vezes, isso ocorre quando um ou mais jogadores se desconectam enquanto o
jogo está em andamento. Os tíquetes de preenchimento de servidor permitem que um servidor de jogo procure
jogadores adicionais que se encaixem no jogo que está sendo jogado no momento.

Os tíquetes de preenchimento de servidor diferem dos tíquetes de matchmaking comuns de várias maneiras:

1. Correspondência
   * Tíquetes de preenchimento não podem ser combinados entre si.
   * Tíquetes de preenchimento recebem prioridade durante a pesquisa, reduzindo a
     fragmentação da base de jogadores.
2. Contrato
   * Tíquetes de preenchimento podem ser criados com um campo `ServerDetails`. Isso permite
     que o servidor indique como os jogadores combinados devem se conectar a ele.
   * Tíquetes de preenchimento podem ser criados com atribuições de equipe. Isso permite que jogos
     com equipes mantenham as informações de suas equipes.
3. Propriedades da fila
   * Tíquetes de preenchimento não disparam a [alocação de Multiplayer Server](/pt-BR/services/playfab/multiplayer/matchmaking/multiplayer-servers).
   * Tíquetes de preenchimento não são refletidos nas [estatísticas da fila](/pt-BR/services/playfab/multiplayer/matchmaking/display-statistics), pois seus jogadores
     já estão jogando uma partida e distorceriam o tempo de espera de forma imprecisa.
4. Propriedade
   * Tíquetes de preenchimento pertencem a um servidor de jogo, não a um usuário. Os usuários não podem
     visualizar nem interagir com tíquetes de preenchimento de forma alguma.

## Pré-requisitos

* Familiaridade básica com o PlayFab Multiplayer SDK. Para obter mais informações, confira o [Início rápido do SDK de Matchmaking](/pt-BR/services/playfab/multiplayer/matchmaking/quickstart-client-sdk).
* Defina `PFMULTIPLAYER_INCLUDE_SERVER_APIS` antes de incluir o cabeçalho de matchmaking. Por exemplo:

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

## Configurar um tíquete de preenchimento de servidor

Crie e preencha uma struct [PFMatchmakingServerBackfillTicketConfiguration](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmatchmakingserverbackfillticketconfiguration) com os detalhes necessários:

* **`timeoutInSeconds`**: Por quanto tempo tentar preencher o tíquete, em segundos.

* **`queueName`**: O nome de uma fila de partidas.

* **`memberCount`**: O número de membros que estão atualmente na partida.

* **`members`**: Os membros [PFMatchmakingMatchMember](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmatchmakingmatchmember) que estão atualmente na partida.

* **`serverDetails`** (opcional): Preencha [PFMultiplayerServerDetails](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmultiplayerserverdetails) com informações sobre o seu servidor (FQDN, endereço IP, portas, região) que são fornecidas aos clientes.

<Note>
  O campo `PFMultiplayerServerDetails::ipv4Address` não é validado e pode ser usado para fornecer informações arbitrárias de cadeia de conexão aos clientes.
</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
```

## Criando um tíquete de preenchimento de servidor

Ao usar [PFMultiplayerCreateServerBackfillTicket](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayercreateserverbackfillticket) para criar um tíquete de preenchimento de servidor, precisamos passar a entidade do nosso servidor de jogo (como um [PFEntityKey](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmultiplayer/pfentitykey_clientsdk)) junto com a configuração de preenchimento que criamos na etapa anterior.

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

## Verificar o status do tíquete de matchmaking

Você deve verificar se há atualizações no tíquete chamando [PFMultiplayerStartProcessingMatchmakingStateChanges](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerstartprocessingmatchmakingstatechanges) para receber as alterações de estado e, em seguida, chamando [PFMultiplayerFinishProcessingMatchmakingStateChanges](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerfinishprocessingmatchmakingstatechanges) quando terminar de processar essas alterações de estado.

O SDK retorna uma alteração de estado **TicketStatusChanged** sempre que o status do tíquete muda e uma alteração de estado **TicketCompleted** quando o matchmaking é concluído.

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

## Obter a partida

Depois de receber a alteração de estado **PFMatchmakingStateChangeType::TicketCompleted**, chame [PFMatchmakingTicketGetMatch](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmatchmakingticketgetmatch) para obter os detalhes da partida. Esses detalhes contêm a ID da partida, os usuários que foram combinados, a região preferencial da partida e uma cadeia de caracteres de organização do lobby associado à partida.

Depois de recuperar todas as informações necessárias da struct **PFMatchmakingMatchDetails**, o tíquete deve ser destruído com [PFMultiplayerDestroyMatchmakingTicket](/pt-BR/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);
```

## Cancelando um tíquete

Se quiser cancelar o processo de matchmaking antes do tempo limite definido em `PFMatchmakingServerBackfillTicketConfiguration`, chame [PFMatchmakingTicketCancel](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmatchmakingticketcancel) com o identificador do tíquete.

Chamar essa API não garante que o tíquete seja cancelado. O tíquete ainda pode ser concluído antes que o cancelamento possa ser processado, ou a solicitação de cancelamento pode falhar devido a erros de rede ou do serviço. Você ainda pode processar as alterações de estado de matchmaking para obter o resultado do tíquete, caso queira confirmar que o cancelamento do tíquete foi concluído antes de prosseguir. Caso contrário, você pode chamar imediatamente [PFMultiplayerDestroyMatchmakingTicket](/pt-BR/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerdestroymatchmakingticket).

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

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
```


## Related topics

- [Usando tíquetes de preenchimento de servidor - API REST](/pt-BR/services/playfab/multiplayer/matchmaking/backfill-tickets.md)
- [Obter tíquete de preenchimento do servidor](/pt-BR/services/playfab/api-references/rest/multiplayer/matchmaking/get-server-backfill-ticket.md)
- [Cancelar tíquete de preenchimento do servidor](/pt-BR/services/playfab/api-references/rest/multiplayer/matchmaking/cancel-server-backfill-ticket.md)
- [Criar tíquete de preenchimento do servidor](/pt-BR/services/playfab/api-references/rest/multiplayer/matchmaking/create-server-backfill-ticket.md)
- [Listar tíquetes de preenchimento do servidor do jogador](/pt-BR/services/playfab/api-references/rest/multiplayer/matchmaking/list-server-backfill-tickets-for-player.md)
