> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Código de exemplo do Multiplayer Activity

> Exemplos em C++ de início rápido do Multiplayer Activity do XBOX para definir atividades, enviar convites e atualizar a lista de jogadores recentes a partir do seu título do GDK.

Este tópico serve como um guia de início rápido para o uso básico das APIs de cliente do Multiplayer Activity. Ele aborda o gerenciamento de atividades, o envio de convites e a adição de jogadores à lista de jogadores recentes.

[Atividades](#activities) [Convites](#invites) [Jogadores recentes](#recent-players)

## Atividades

### Definindo uma atividade

Sempre que um título inicia ou ingressa em uma experiência multiplayer, ele deve criar uma atividade. Isso permite que o shell, junto com outros jogadores do seu título, veja a atividade do jogador e permite que outros jogadores possam ingressar no jogo em andamento. Se um jogador quiser ingressar em uma atividade do seu título e ele não estiver em execução, o título será ativado e a cadeia de conexão será passada a ele.

Os títulos devem atualizar a atividade à medida que os jogadores entram ou saem. Isso oferece uma visão mais rica da atividade para outros jogadores e os informa se a atividade está cheia.

Para obter informações sobre os campos de atividade, consulte [Conteúdo das atividades](https://docs.xbox.com/pt-BR/services/xbox-services/multiplayer/mpa/concepts/live-mpa-activities.md#activity-contents).

Veja a seguir um exemplo de código para definir uma atividade. Ele se aplica tanto à criação de uma atividade quanto à atualização de uma atividade existente.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

XblMultiplayerActivityInfo info{};
info.connectionString = "dummyConnectionString";
info.joinRestriction = XblMultiplayerActivityJoinRestriction::Followed;
info.maxPlayers = 10;
info.currentPlayers = 1;
info.groupId = "dummyGroupId";

HRESULT hr = XblMultiplayerActivitySetActivityAsync(
    xblContext,
    &info,
    false,
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

Para obter mais informações, consulte:

* [XAsyncBlock](https://docs.xbox.com/pt-BR/reference/system/xasync/structs/xasyncblock.md)
* [XAsyncGetStatus](https://docs.xbox.com/pt-BR/reference/system/xasync/functions/xasyncgetstatus.md)
* [XblMultiplayerActivityInfo](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityinfo.md)
* [XblMultiplayerActivityJoinRestriction](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/enums/xblmultiplayeractivityjoinrestriction.md)
* [XblMultiplayerActivitySetActivityAsync](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync.md)

[Voltar ao início deste tópico.](#top)

### Obtendo atividades

Os títulos podem querer saber as atividades de outros jogadores. Por exemplo, um título pode querer exibir uma interface do usuário no jogo com os amigos de um jogador no título, junto com as atividades deles.

Veja a seguir um exemplo de código para recuperar uma atividade.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.

    size_t resultSize{};
    HRESULT hr = XblMultiplayerActivityGetActivityResultSize(async, &resultSize);
    if (SUCCEEDED(hr))
    {
        std::vector<uint8_t> buffer(resultSize);
        XblMultiplayerActivityInfo* activityInfo{};
        size_t resultCount{};
        hr = XblMultiplayerActivityGetActivityResult(async, buffer.size(), buffer.data(), &activityInfo, &resultCount, nullptr);
        if (SUCCEEDED(hr))
        {
            // ...
        }
    }
};

HRESULT hr = XblMultiplayerActivityGetActivityAsync(
    xblContext,
    &xuid,
    1,
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

Para obter mais informações, consulte:

* [XAsyncBlock](https://docs.xbox.com/pt-BR/reference/system/xasync/structs/xasyncblock.md)
* [XblMultiplayerActivityGetActivityResultSize](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityresultsize.md)
* [XblMultiplayerActivityInfo](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityinfo.md)
* [XblMultiplayerActivityGetActivityResult](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityresult.md)
* [XblMultiplayerActivityGetActivityAsync](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitygetactivityasync.md)

[Voltar ao início deste tópico.](#top)

### Excluindo uma atividade

Quando um jogador encerra ou sai de uma atividade multiplayer, o título deve excluir a atividade usando o código a seguir.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivityDeleteActivityAsync(xblContext, async.get());

if (SUCCEEDED(hr))
{
    async.release();
}
```

Para obter mais informações, consulte:

* [XAsyncBlock](https://docs.xbox.com/pt-BR/reference/system/xasync/structs/xasyncblock.md)
* [XAsyncGetStatus](https://docs.xbox.com/pt-BR/reference/system/xasync/functions/xasyncgetstatus.md)
* [XblMultiplayerActivityDeleteActivityAsync](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitydeleteactivityasync.md)

[Voltar ao início deste tópico.](#top)

## Convites

### Enviando convites sem interface do usuário

Os jogadores podem querer enviar convites diretamente para um ou mais outros jogadores. Antes de enviar um convite, o título deve garantir que uma atividade esteja definida. Isso garante a continuidade entre o shell e o seu título, pois o shell envia convites com base na atividade atual.

Para enviar um convite sem interface do usuário, depois que uma atividade for definida usando [XblMultiplayerActivitySetActivityAsync](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync.md) (consulte o exemplo acima), o título deve chamar a API [XblMultiplayerActivitySendInvitesAsync](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysendinvitesasync.md), passando uma matriz de jogadores a serem convidados e a mesma cadeia de conexão usada na atividade atual.

Para obter informações sobre o conteúdo de um convite, consulte [Enviar uma solicitação para que outro jogador ingresse em uma experiência multiplayer.](https://docs.xbox.com/pt-BR/services/xbox-services/multiplayer/mpa/concepts/live-mpa-invites.md).

Veja a seguir um exemplo de código para enviar convites sem interface do usuário.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivitySendInvitesAsync(
    xblContext,
    &xuid,
    1,
    true, // Setting false will send the invite to only players on the sender's platform.
    "dummyConnectionString",
    async.get()
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

Para obter mais informações, consulte:

* [XAsyncBlock](https://docs.xbox.com/pt-BR/reference/system/xasync/structs/xasyncblock.md)
* [XAsyncGetStatus](https://docs.xbox.com/pt-BR/reference/system/xasync/functions/xasyncgetstatus.md)
* [XblMultiplayerActivitySendInvitesAsync](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysendinvitesasync.md)

### Enviando convites com interface do usuário

Os jogadores podem querer enviar convites diretamente para um ou mais outros jogadores. Antes de enviar um convite, o título deve garantir que uma atividade esteja definida. Isso garante a continuidade entre o shell e o seu título, pois o shell envia convites com base na atividade atual.

Para enviar um convite com interface do usuário, depois que uma atividade for definida usando [XblMultiplayerActivitySetActivityAsync](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivitysetactivityasync.md) (consulte o exemplo acima), o título deve chamar a API [XGameUiShowMultiplayerActivityGameInviteAsync](https://docs.xbox.com/pt-BR/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteasync.md), passando o usuário solicitante. Ela usará a atividade atual do título e convidará jogadores usando a cadeia de conexão e as configurações dessa atividade.

Para obter informações sobre o conteúdo de um convite, consulte [Enviar uma solicitação para que outro jogador ingresse em uma experiência multiplayer.](https://docs.xbox.com/pt-BR/services/xbox-services/multiplayer/mpa/concepts/live-mpa-invites.md).

Veja a seguir um exemplo de código para enviar convites com interface do usuário.

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XGameUiShowMultiplayerActivityGameInviteResult(async);
    if (hrAsync == S_OK) 
    { 
        // Handle success 
    } 
    else 
    { 
        // Likely will only happen during development - usually indicates 
        // an invalid user was passed in or that there is no multiplayer activity set
    }     
};

HRESULT hr = XGameUiShowMultiplayerActivityGameInviteAsync(
    async.get()
    requestingUser
);

if (SUCCEEDED(hr))
{
    async.release();
}
```

Para obter mais informações, consulte:

* [XAsyncBlock](https://docs.xbox.com/pt-BR/reference/system/xasync/structs/xasyncblock.md)
* [XAsyncGetStatus](https://docs.xbox.com/pt-BR/reference/system/xasync/functions/xasyncgetstatus.md)
* [XGameUiShowMultiplayerActivityGameInviteAsync](https://docs.xbox.com/pt-BR/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteasync.md)
* [XGameUiShowMultiplayerActivityGameInviteResult](https://docs.xbox.com/pt-BR/reference/system/xgameui/functions/xgameuishowmultiplayeractivitygameinviteresult.md)

[Voltar ao início deste tópico.](#top)

### Recebendo convites

Para ser notificado quando um jogador aceitar um convite, os títulos podem se registrar para notificações de convite usando `XGameInviteRegisterForEvent`. Sempre que um convite é aceito, um URI formatado é passado ao título por meio do retorno de chamada registrado. O URI pode ser analisado para determinar o remetente, o destinatário e a cadeia de conexão do convite. A cadeia de conexão é específica do título e é definida quando a atividade multiplayer é criada. Para títulos que usam o serviço Multiplayer Activity, o formato completo do URI é mostrado na tabela a seguir.

| Plataforma | Formato |
| - | - |
| Microsoft Game Development Kit (GDK) ou XBOX One Software Development Kit no console | `ms-xbl-<titleId>://inviteAccept?invitedUser=<xuid>&sender=<xuid>&connectionString=<connectionString>` |
| Microsoft Game Development Kit (GDK) ou Plataforma Universal do Windows (UWP) no PC | `ms-xbl-multiplayer://inviteAccept?invitedUser=<xuid>&sender=<xuid>&connectionString=<connectionString>` |

Quando as notificações de convite não forem mais necessárias, o registro do retorno de chamada pode ser cancelado usando `XGameInviteUnregisterForEvent`. Veja a seguir um exemplo de código para registrar e tratar convites aceitos.

```cpp theme={null}
void CALLBACK MyXGameInviteEventCallback(
    _In_opt_ void* context,
    _In_ const char* inviteUri)
{
    if (inviteUri != nullptr)
    {
        std::string uri{ inviteUri };
        size_t invitedUserBegin = uri.find("invitedUser=");
        size_t senderBegin = uri.find("sender=");
        std::string invitedUser = uri.substr(invitedUserBegin, uri.find('&', invitedUserBegin) - invitedUserBegin);
        std::string sender = uri.substr(senderBegin, uri.find('&', senderBegin) - senderBegin);
        std::string connectionString = uri.substr(uri.find("connectionString="));

        // ...
    }
}

XTaskQueueRegistrationToken token = { 0 };
HRESULT hr = XGameInviteRegisterForEvent(
    queue,
    nullptr,
    MyXGameInviteEventCallback,
    &token
    );

// ...
bool result = XGameInviteUnregisterForEvent(token, true);
```

Para obter mais informações, consulte:

* [XGameInviteRegisterForEvent](https://docs.xbox.com/pt-BR/reference/system/xgameinvite/functions/xgameinviteregisterforevent.md)
* [XGameInviteUnregisterForEvent](https://docs.xbox.com/pt-BR/reference/system/xgameinvite/functions/xgameinviteunregisterforevent.md)

[Voltar ao início deste tópico.](#top)

## Jogadores recentes

Para atualizar a lista de jogadores recentes do jogador, o título deve enviar listas de outros jogadores que tiveram uma interação significativa com o jogador atual. A lista é unidirecional, o que significa que o cliente de cada jogador é responsável por atualizar sua própria lista, e as listas dos jogadores não afetam as listas uns dos outros.

Por exemplo, suponha que um grupo de jogadores esteja junto em um lobby pré-jogo e seja combinado. Cada jogador atualizaria sua lista com todos os outros `xuids` do lobby quando a partida começasse. Se um novo jogador ingressasse, ele poderia ser gravado individualmente.

> [!NOTE]
>
> Você pode decidir o que define uma interação significativa. Para um título, pode ser estar presente em um lobby. Para outro, pode ser um jogador atirar em outro jogador. Para um terceiro, pode ser simplesmente ter outro jogador visível na tela.

Em cenários em que você não queira que as equipes de jogadores sejam vistas até que uma sessão de partida comece, você pode adiar a gravação da lista de jogadores até o momento em que deseja que eles fiquem visíveis uns para os outros. Para liberar a lista de jogadores recentes do lado do cliente, você pode chamar `XblMultiplayerActivityFlushRecentPlayersAsync` se precisar de uma liberação forçada imediata. Caso contrário, a lista de jogadores recentes será liberada automaticamente a cada cinco segundos.

Veja a seguir exemplos de código para atualizar a lista de jogadores recentes e liberar as atualizações.

### Atualizando os jogadores recentes

```cpp theme={null}
XblMultiplayerActivityRecentPlayerUpdate update{ xuid };
HRESULT hr = XblMultiplayerActivityUpdateRecentPlayers(xblContext, &update, 1);
```

Para obter mais informações, consulte:

* [XblMultiplayerActivityRecentPlayerUpdate](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/structs/xblmultiplayeractivityrecentplayerupdate.md)
* [XblMultiplayerActivityUpdateRecentPlayers](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivityupdaterecentplayers.md)

[Voltar ao início deste tópico.](#top)

### Liberando os jogadores recentes

```cpp theme={null}
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
    HRESULT hr = XAsyncGetStatus(async, false);
};

HRESULT hr = XblMultiplayerActivityFlushRecentPlayersAsync(xblContext, async.get());
if (SUCCEEDED(hr))
{
    async.release();
}
```

Para obter mais informações, consulte:

* [XAsyncBlock](https://docs.xbox.com/pt-BR/reference/system/xasync/structs/xasyncblock.md)
* [XAsyncGetStatus](https://docs.xbox.com/pt-BR/reference/system/xasync/functions/xasyncgetstatus.md)
* [XblMultiplayerActivityFlushRecentPlayersAsync](https://docs.xbox.com/pt-BR/reference/live/xsapi-c/multiplayer_activity_c/functions/xblmultiplayeractivityflushrecentplayersasync.md)

[Voltar ao início deste tópico.](#top)


## Related topics

- [Código de exemplo do Multiplayer Activity](https://docs.xbox.com/pt-BR/services/xbox-services/multiplayer/mpa/how-to/live-mpa-how-to-nav.md)
- [Instruções](https://docs.xbox.com/pt-BR/services/xbox-services/multiplayer/mpa/how-to/index.md)
- [Código de exemplo do serviço Real-Time Activity (RTA) (conteúdo)](https://docs.xbox.com/pt-BR/services/xbox-services/fundamentals/rta/how-to/live-rta-howto-nav.md)
- [Código de exemplo do Multiplayer Manager](https://docs.xbox.com/pt-BR/services/xbox-services/multiplayer/mpm/how-to/live-mm-howto-nav.md)
- [Código de exemplo do Multiplayer Session Directory (MPSD)](https://docs.xbox.com/pt-BR/services/xbox-services/multiplayer/mpsd/how-to/live-mpsd-howto-nav.md)
