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

# Navegação de sessões multiplayer

> Habilite a navegação de sessões multiplayer do XBOX para que os jogadores consultem, filtrem e ingressem em sessões de jogo abertas usando metadados definidos pelo título em vez do matchmaking.

Use este tópico para habilitar seu título a permitir que os usuários consultem uma lista de sessões de jogo multiplayer abertas que atendam aos critérios especificados, usando a navegação de sessões multiplayer.

A navegação de sessões multiplayer foi introduzida em novembro de 2016.
Em um cenário de navegação de sessões, um usuário em um jogo pode recuperar uma lista de sessões de jogo nas quais é possível ingressar.
Cada entrada de sessão dessa lista contém alguns metadados adicionais sobre o jogo, que o usuário pode usar para ajudar a escolher em qual sessão ingressar.
O usuário também pode filtrar a lista de sessões usando os metadados.
Depois que o usuário encontra uma sessão de jogo que o interessa, ele pode ingressar nela.

Um usuário também pode criar uma nova sessão de jogo e usar o recurso de navegação de sessões para recrutar usuários adicionais em vez de depender do matchmaking.
A navegação de sessões multiplayer e o matchmaking tradicional são diferentes. Com a navegação de sessões multiplayer, o usuário
seleciona em qual sessão de jogo deseja ingressar. Com o matchmaking, o usuário seleciona uma
opção "encontrar um jogo" que tenta colocá-lo automaticamente em uma sessão de jogo apropriada.

Embora a navegação de sessões multiplayer seja um processo manual e mais lento que nem sempre seleciona a melhor experiência de jogo
para o usuário, ele tem mais controle, e o recurso de navegação pode ser percebido como a escolha de jogo subjetivamente melhor.
É comum incluir cenários de navegação de sessões multiplayer e de matchmaking nos jogos.
Normalmente, o matchmaking é usado para modos de jogo jogados com frequência, enquanto a navegação de sessões multiplayer é usada para jogos personalizados.

## Cenário de exemplo

John quer jogar um jogo multiplayer de arena de batalha, mas quer jogar uma partida em que todos os usuários selecionem seu herói aleatoriamente.
Usando a navegação de sessões multiplayer, ele pode recuperar uma lista de sessões de jogo abertas e encontrar as que incluem "random heroes" na descrição.

Se a interface do usuário do título tiver a opção, ele poderá selecionar o modo de jogo "random hero" e recuperar apenas as sessões marcadas para indicar que são jogos "RandomHero".
Quando John encontrar uma sessão de jogo de que goste, ele poderá ingressar nela.
Depois que pessoas suficientes ingressarem, o host da sessão de jogo poderá iniciá-la.

## Funções

Uma sessão que está no recurso de navegação de sessões multiplayer pode especificar que está recrutando usuários para funções específicas.
Por exemplo, um usuário pode querer criar uma sessão de jogo que especifique que ela contém no máximo cinco classes de assalto,
mas deve conter pelo menos duas funções de curandeiro e pelo menos uma função de tanque.

Quando outro usuário se candidata à sessão, ele pode pré-selecionar sua função. Em seguida, o serviço decide se ele pode ingressar na
sessão com base em quantas vagas abertas estão disponíveis para a função selecionada.
Se um usuário quiser reservar duas vagas para que seus amigos ingressem, ele pode designar uma função "amigos" para a sessão, e
somente usuários que são amigos do host poderão preencher as duas vagas dedicadas à função "amigos".

Para obter mais informações sobre funções, consulte [Funções no multiplayer](/pt-BR/services/xbox-services/multiplayer/concepts/live-multiplayer-roles).

## Como funciona a navegação de sessões multiplayer

A navegação de sessões funciona usando identificadores de pesquisa.
Um identificador de pesquisa é um pacote de dados que contém uma referência à sessão, além de metadados adicionais sobre a sessão, como atributos de pesquisa.

Quando um título cria uma nova sessão de jogo qualificada para a navegação de sessões multiplayer, ele cria um identificador de pesquisa para a sessão.
O identificador de pesquisa é armazenado no [Multiplayer Service Directory (MPSD)](/pt-BR/services/xbox-services/multiplayer/mpsd/live-mpsd-overview), que mantém os identificadores de pesquisa do título.
Quando um título precisa recuperar uma lista de sessões, ele pode enviar uma consulta de pesquisa ao MPSD, que retorna uma lista de identificadores de pesquisa que atendem aos critérios de pesquisa.
Em seguida, o título pode usar a lista de sessões para exibir ao usuário uma lista de jogos nos quais é possível ingressar.
Quando uma sessão está cheia ou não é possível ingressar nela por outro motivo, seu título pode remover o identificador de pesquisa do MPSD para
que a sessão não apareça nas consultas da navegação de sessões multiplayer.

<Note>
  Os identificadores de pesquisa são usados ao exibir uma lista de sessões para um usuário.
</Note>

Não use identificadores de pesquisa para matchmaking em segundo plano. Para matchmaking em segundo plano, recomendamos usar o SmartMatch.
Para obter mais informações, consulte [Encontrando um jogo multiplayer usando o SmartMatch com o Multiplayer Manager](/pt-BR/services/xbox-services/multiplayer/mpm/how-to/live-play-multiplayer-with-matchmaking).

## Configurar uma sessão para a navegação de sessões multiplayer

Para usar identificadores de pesquisa em uma sessão, a sessão deve ter `searchable` e `userAuthorizationStyle` definidos como `true`.
A capacidade `userAuthorizationStyle` só é obrigatória para jogos UWP, mas recomendamos implementá-la em todos os jogos do XBOX, incluindo jogos do Microsoft Game Development Kit (GDK). Isso garante a portabilidade futura do seu título.

<Note>
  Configurar `userAuthorizationStyle` como `true` altera `readRestriction` e `joinRestriction` da sessão para `local` em vez de `none`. Isso significa que os títulos devem usar identificadores de pesquisa ou de transferência para ingressar em uma sessão de jogo.
</Note>

Você pode definir essas capacidades no modelo de sessão ao configurar seus serviços do XBOX.

<Note>
  Para a navegação de sessões multiplayer, crie identificadores de pesquisa somente em sessões usadas para a jogabilidade real. Não os use em sessões de lobby.
</Note>

## Propriedade da sessão de jogo

Muitos tipos de sessão de jogo, como o SmartMatch ou uma sessão somente para amigos, não exigem um host ou proprietário. No entanto, ao configurar jogos de navegação de sessões multiplayer, talvez você queira um proprietário.
Ter uma sessão gerenciada pelo proprietário traz alguns benefícios para o host, como
remover outros membros da sessão ou alterar o status de propriedade de outros membros.
Para usar proprietários em uma sessão, a sessão deve ter `hasOwners` definido como `true`.
Ao usar [Funções no multiplayer](/pt-BR/services/xbox-services/multiplayer/concepts/live-multiplayer-roles), você pode configurar para que somente os proprietários possam atribuir funções aos usuários.

<Note>
  Se um proprietário de uma sessão tiver bloqueado um membro do XBOX, esse membro não poderá ingressar na sessão.
</Note>

Se todos os proprietários saírem de uma sessão, o serviço agirá sobre a sessão com base na política `ownershipPolicy.migration` definida para a sessão.
Se a política for "oldest", o usuário que está na sessão há mais tempo será definido como o novo proprietário.
Se a política for "endsession" (o padrão, se nenhuma for fornecida), o serviço encerrará a sessão e removerá todos os usuários restantes da sessão.

## Identificadores de pesquisa

Um identificador de pesquisa é armazenado no MPSD como uma estrutura JSON.
Além de conter uma referência à sessão, os identificadores de pesquisa também contêm metadados adicionais para pesquisas, conhecidos como atributos de pesquisa.
Uma sessão só pode ter um identificador de pesquisa criado para ela por vez.
Para criar um identificador de pesquisa para uma sessão usando a XBOX Services API (XSAPI), chame o método [XblMultiplayerCreateSearchHandleAsync](/pt-BR/reference/live/xsapi-c/multiplayer_c/functions/xblmultiplayercreatesearchhandleasync).

### Atributos de pesquisa

Os atributos de pesquisa consistem nos componentes a seguir.

* As `tags` são descritores de cadeia de caracteres que as pessoas podem usar para categorizar uma sessão de jogo, como uma hashtag.
  * As tags devem começar com uma letra, não podem conter espaços e devem ter menos de 100 caracteres.
  * Tags de exemplo: "ProRankOnly", "norocketlaunchers", "cityMaps".

* As `strings` são variáveis de texto.
  * Os nomes das strings devem começar com uma letra, não podem conter espaços e devem ter menos de 100 caracteres.
  * Metadados de string de exemplo: "Weapons"="knives+pistols+rifles", "MapName"="UrbanCityAssault", "description"="Fun casual game, new people welcome."

* Os `numbers` são variáveis numéricas. As XSAPIs recuperam valores numéricos como o tipo float.
  * Os nomes dos números devem começar com uma letra, não podem conter espaços e devem ter menos de 100 caracteres.
  * Metadados numéricos de exemplo: "MinLevel" = 25, "MaxRank" = 10.

<Note>
  O uso de maiúsculas e minúsculas nas tags e nos valores de string é preservado no serviço, mas você deve usar a função `tolower()` ao consultar tags. Isso significa que, no momento, as tags e os valores de string são todos tratados como minúsculos, mesmo que contenham caracteres maiúsculos.
</Note>

Nas XSAPIs, você pode definir os atributos de pesquisa, como tags e metadados, usando o método [XblMultiplayerCreateSearchHandleAsync](/pt-BR/reference/live/xsapi-c/multiplayer_c/functions/xblmultiplayercreatesearchhandleasync).

### Detalhes adicionais

Ao recuperar um identificador de pesquisa, os resultados também incluem dados úteis sobre a sessão, como se a sessão está fechada e se há restrições de entrada.
Nas XSAPIs, esses detalhes, junto com os atributos de pesquisa, são incluídos nos resultados `XblMultiplayerSearchHandle` retornados após uma consulta de pesquisa.

### Remover um identificador de pesquisa

Quando quiser remover uma sessão da navegação de sessões multiplayer,
como quando a sessão está cheia ou fechada, você pode excluir o identificador de pesquisa.
Nas XSAPIs, remova um identificador de pesquisa usando o método [XblMultiplayerDeleteSearchHandleAsync](/pt-BR/reference/live/xsapi-c/multiplayer_c/functions/xblmultiplayerdeletesearchhandleasync).

### Criar um identificador de pesquisa com metadados

O código a seguir mostra como criar um identificador de pesquisa para uma sessão usando as APIs multiplayer do XBOX.

#### API C simples

```cpp theme={null}
size_t tagsCount = 1;
XblMultiplayerSessionTag tags[1] = {};
tags[0] = XblMultiplayerSessionTag{ "SessionTag" };

size_t numberAttributesCount = 1;
XblMultiplayerSessionNumberAttribute numberAttributes[1] = {};
numberAttributes[0] = XblMultiplayerSessionNumberAttribute{ "numberattributename", 1.1 };

size_t strAttributesCount = 1;
XblMultiplayerSessionStringAttribute strAttributes[1] = {};
strAttributes[0] = XblMultiplayerSessionStringAttribute{ "stringattributename", "string attribute value" };

auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock*
    XblMultiplayerSearchHandle searchHandle{ nullptr };
    HRESULT hr = XblMultiplayerCreateSearchHandleResult(asyncBlock, &searchHandle);

    if (SUCCEEDED(hr))
    {
        const char* handleId{ nullptr };
        XblMultiplayerSearchHandleGetId(searchHandle, &handleId);
    }
};

HRESULT hr = XblMultiplayerCreateSearchHandleAsync(
    xblContextHandle,
    &xblMultiplayerSessionReference,
    tags,
    tagsCount,
    numberAttributes,
    numberAttributesCount,
    strAttributes,
    strAttributesCount,
    asyncBlock.get()
);

if (SUCCEEDED(hr))
{
    // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership.
    // If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock*
    asyncBlock.release();
}
```

Para obter mais informações sobre as funções usadas no exemplo de código, consulte [multiplayer\_c](/pt-BR/reference/live/xsapi-c/multiplayer_c/multiplayer_c_members).

## Criar uma consulta de pesquisa de sessões

Ao recuperar uma lista de identificadores de pesquisa, você pode usar uma consulta de pesquisa para restringir os resultados às sessões que atendem a critérios específicos.

A sintaxe da consulta de pesquisa é no estilo [OData](https://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398092), com suporte apenas aos operadores a seguir.

| Operador | Descrição |
| - | - |
| eq | igual a |
| ne | diferente de |
| gt | maior que |
| ge | maior ou igual a |
| lt | menor que |
| le | menor ou igual a |
| and | AND lógico |
| or | OR lógico (consulte a observação abaixo) |

<Note>
  Você também pode usar expressões lambda e a função canônica `tolower`.
</Note>

No momento, não há suporte para nenhuma outra função OData.

Ao pesquisar tags ou valores de string, você deve usar a função `tolower` na consulta de pesquisa.
O serviço só oferece suporte à pesquisa de cadeias de caracteres em minúsculas.
O serviço do XBOX retorna apenas os primeiros 100 resultados que correspondem à consulta de pesquisa.
Garanta que os usuários possam refinar a consulta de pesquisa se os resultados forem muito amplos.

<Note>
  Instruções `OR` lógicas são compatíveis com consultas de cadeia de caracteres de filtro.
</Note>

No entanto, apenas um `OR` é permitido, e ele deve estar na raiz da consulta.
Você não pode ter várias instruções `OR` na consulta, nem criar uma
consulta que resulte em `OR` não estar no nível mais alto da estrutura da consulta.

### Exemplos de consulta de identificadores de pesquisa

Em uma chamada RESTful, "Filter" é onde você especifica uma cadeia de caracteres na linguagem OData Filter que é executada na consulta em todos os identificadores de pesquisa.
Nas APIs do Multiplayer 2015, você pode especificar a cadeia de caracteres do filtro de pesquisa usando o parâmetro `searchFilter` do método [XblMultiplayerGetSearchHandlesAsync](/pt-BR/reference/live/xsapi-c/multiplayer_c/functions/xblmultiplayergetsearchhandlesasync).

No momento, há suporte para os cenários de filtro a seguir.

| Filtrar por | Cadeia de caracteres do filtro de pesquisa |
| - | - |
| Um único xuid de membro '1234566' | "session/memberXuids/any(d:d eq '1234566')" |
| Um único xuid de proprietário '1234566' | "session/ownerXuids/any(d:d eq '1234566')" |
| Uma string 'forzacarclass' igual a 'classb' | "tolower(strings/forzacarclass) eq 'classb'" |
| Um número 'forzaskill' igual a 6 | "numbers/forzaskill eq 6" |
| Um número 'halokdratio' maior que 1.5 | "numbers/halokdratio gt 1.5" |
| Uma tag 'coolpeopleonly' | "tags/any(d:tolower(d) eq 'coolpeopleonly')" |
| Sessões que não contêm a tag 'cursingallowed' | "tags/any(d:tolower(d) ne 'cursingallowed')" |
| Sessões que não contêm um número 'rank' igual a 0 | "numbers/rank ne 0" |
| Sessões que não contêm uma string 'forzacarclass' igual a 'classa' | "tolower(strings/forzacarclass) ne 'classa'" |
| Uma tag 'coolpeopleonly' e um número 'halokdratio' igual a 7.5 | "tags/any(d:tolower(d) eq 'coolpeopleonly') eq true and numbers/halokdratio eq 7.5" |
| Um número 'halokdratio' maior ou igual a 1.5, um número 'rank' menor que 60 e um número 'customnumbervalue' menor ou igual a 5 | "numbers/halokdratio ge 1.5 and numbers/rank lt 60 and numbers/customnumbervalue le 5" |
| Um ID de conquista '123456' | "achievementIds/any(d:d eq '123456')" |
| O código de idioma 'en' | "language eq 'en'" |
| Horário agendado; retorna todos os horários agendados menores ou iguais ao horário especificado | "session/scheduledTime le '2009-06-15T13:45:30.0900000Z'" |
| Horário de publicação; retorna todos os horários de publicação menores que o horário especificado | "session/postedTime lt '2009-06-15T13:45:30.0900000Z'" |
| Estado de registro da sessão | "session/registrationState eq 'registered'" |
| Em que o número de membros da sessão é igual a 5 | "session/membersCount eq 5" |
| Em que a contagem de destino de membros da sessão é maior que 1 | "session/targetMembersCount gt 1" |
| Em que a contagem máxima de membros da sessão é menor que 3 | "session/maxMembersCount lt 3" |
| Em que a diferença entre a contagem de destino de membros da sessão e o número de membros da sessão é menor ou igual a 5 | "session/targetMembersCountRemaining le 5" |
| Em que a diferença entre a contagem máxima de membros da sessão e o número de membros da sessão é maior que 2 | "session/maxMembersCountRemaining gt 2" |
| Em que a diferença entre a contagem de destino de membros da sessão e o número de membros da sessão é menor ou igual a 15.<br /> Se a função não tiver um destino especificado, essa consulta filtrará pela diferença entre a contagem máxima de membros da sessão e o número de membros da sessão. | "session/needs le 15" |
| Função "confirmed" do tipo de função "lfg" em que o número de membros com essa função é igual a 5 | "session/roles/lfg/confirmed/count eq 5" |
| Função "confirmed" do tipo de função "lfg" em que o destino dessa função é maior que 1.<br /> Se a função não tiver um destino especificado, o máximo da função será usado. | "session/roles/lfg/confirmed/target gt 1" |
| Função "confirmed" do tipo de função "lfg" em que a diferença entre o destino da função e o número de membros com essa função é menor ou igual a 15.<br /> Se a função não tiver um destino especificado, essa consulta filtrará pela diferença entre o máximo da função e o número de membros com essa função. | "session/roles/lfg/confirmed/needs le 15" |
| Todos os identificadores de pesquisa que apontam para uma sessão que contém uma palavra-chave específica | "session/keywords/any(d:tolower(d) eq 'level2')" |
| Todos os identificadores de pesquisa que apontam para uma sessão que pertence a um SCID específico | "session/scid eq '151512315'" |
| Todos os identificadores de pesquisa que apontam para uma sessão que usa um nome de modelo específico | "session/templateName eq 'mytemplate1'" |
| Todos os identificadores de pesquisa que têm a tag 'elite' ou têm um número 'guns' maior que 15 e a string 'clan' igual a 'purple' | "tags/any(a:tolower(a) eq 'elite') or number/guns gt 15 and string/clan eq 'purple'" |

### Atualizando os resultados da pesquisa

Seu jogo deve evitar atualizar automaticamente uma lista de sessões. Dê ao usuário a opção de atualizar a lista manualmente por meio da interface do usuário.
Isso é útil se o usuário refinar os critérios de pesquisa para filtrar melhor os resultados.
Se um usuário tentar ingressar em uma sessão, mas essa sessão estiver cheia ou fechada, seu jogo também deverá atualizar os resultados da pesquisa.

<Note>
  Atualizações de pesquisa em excesso podem levar à limitação do serviço.
</Note>

Seu título deve limitar a frequência com que a consulta pode ser atualizada.

Para reduzir o volume de chamadas ao serviço, os identificadores de pesquisa incluem propriedades de sessão personalizadas que podem ser usadas para armazenar e consultar
atributos de sessão que mudam rapidamente. Esses atributos não devem ser armazenados nos atributos de pesquisa.

### Consultar identificadores de pesquisa

O código a seguir mostra como consultar identificadores de pesquisa.
A API retorna uma coleção de objetos `XblMultiplayerSearchHandle` que representam todos os identificadores de pesquisa que correspondem à consulta.

#### API C simples

```cpp theme={null}
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock*
    size_t resultCount{ 0 };
    auto hr = XblMultiplayerGetSearchHandlesResultCount(asyncBlock, &resultCount);
    if (SUCCEEDED(hr) && resultCount > 0)
    {
        auto handles = new XblMultiplayerSearchHandle[resultCount];

        hr = XblMultiplayerGetSearchHandlesResult(asyncBlock, handles, resultCount);

        if (SUCCEEDED(hr))
        {
            // Process handles
            for (auto i = 0u; i < resultCount; ++i)
            {
                const char* handleId{ nullptr };
                XblMultiplayerSearchHandleGetId(handles[i], &handleId);

                XblMultiplayerSearchHandleCloseHandle(handles[i]);
            }
        }
    }

};

const char* sessionName{ "MinGameSession" };
const char* orderByAttribute{ nullptr };
bool orderAscending{ false };
const char* searchFilter{ nullptr };
const char* socialGroup{ nullptr };

HRESULT hr = XblMultiplayerGetSearchHandlesAsync(
    xblContextHandle,
    scid,
    sessionName,
    orderByAttribute,
    orderAscending,
    searchFilter,
    socialGroup,
    asyncBlock.get()
);
if (SUCCEEDED(hr))
{
    // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership.
    // If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock*
    asyncBlock.release();
}
```

Para obter mais informações sobre as funções usadas no exemplo de código, consulte [multiplayer\_c](/pt-BR/reference/live/xsapi-c/multiplayer_c/multiplayer_c_members).

## Ingressar em uma sessão usando um identificador de pesquisa

Depois que um usuário recuperar um identificador de pesquisa de uma sessão na qual deseja ingressar,
garanta que ele possa se adicionar à sessão usando [XblMultiplayerWriteSessionByHandleAsync](/pt-BR/reference/live/xsapi-c/multiplayer_c/functions/xblmultiplayerwritesessionbyhandleasync).

<Note>
  Os métodos [XblMultiplayerWriteSessionAsync](/pt-BR/reference/live/xsapi-c/multiplayer_c/functions/xblmultiplayerwritesessionasync) não podem ser usados para ingressar em uma sessão de navegação de sessões multiplayer.
</Note>


## Related topics

- [Perguntas frequentes e solução de problemas de multiplayer](/pt-BR/services/xbox-services/multiplayer/mpsd/concepts/live-multiplayer-2015-faq.md)
- [Conceitos de multiplayer](/pt-BR/services/xbox-services/multiplayer/concepts/live-multiplayer-concepts-nav.md)
- [Conceitos](/pt-BR/services/xbox-services/multiplayer/concepts/index.md)
- [Tópicos avançados de sessões multiplayer](/pt-BR/services/xbox-services/multiplayer/mpsd/concepts/live-mpsd-details.md)
- [Gerenciamento de sessões multiplayer de serviço para serviço](/pt-BR/services/xbox-services/fundamentals/s2s-auth-calls/s2s-calls/s2s-call-patterns/live-mpsd-service-to-service.md)
