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

# Início rápido Linux

> Adicione o SDK do PlayFab Services para C a um projeto Linux no Ubuntu ou no WSL e faça sua primeira chamada à API do PlayFab usando a biblioteca de cliente nativa para C.

# Início rápido: Linux

Comece a usar o SDK do PlayFab Services para Linux. Siga estas etapas para incluir as bibliotecas no seu projeto e experimentar o código de exemplo da funcionalidade básica do PlayFab.

Este início rápido ajuda você a fazer sua primeira chamada à API do PlayFab usando o Linux. Antes de continuar, verifique se você concluiu as etapas de [Início rápido: Game Manager](/pt-BR/services/playfab/live-service-management/gamemanager/quickstart), que garantem que você tenha uma conta do PlayFab e esteja familiarizado com o PlayFab Game Manager.

## Requisitos

* Uma [conta de desenvolvedor do PlayFab](https://developer.playfab.com).
* Ubuntu 22.04 ou superior, ou o Subsistema do Windows para Linux com a distribuição Ubuntu 22.04 ou superior. Consulte [Como instalar o Linux no Windows com o WSL](https://learn.microsoft.com/en-us/windows/wsl/install).  Outras distribuições Linux devem funcionar, mas não foram verificadas.

## Configuração do projeto

Baixe o SDK do PlayFab para Linux para o seu projeto na [página de releases do SDK do PlayFab](https://github.com/PlayFab/PlayFabCSdk/releases/latest).

### Integrar o SDK do PlayFab para C ao seu projeto

#### Adicionar os binários ao seu jogo

Você precisará integrar ao seu projeto os arquivos de objeto compartilhado (.so). Você pode compilar os binários por conta própria ou baixá-los da página de releases.

As próximas etapas foram escritas considerando que você criou um novo projeto.

#### Adicionando os arquivos .so

Esses arquivos são integrados ao seu projeto usando o CMake.

1. Descompacte o release do SDK do PlayFab para Linux e coloque o conteúdo no diretório desejado.

2. Usando **target\_include\_directories** ou outra função equivalente, adicione esta lista de cabeçalhos do release do SDK do PlayFab:

Por exemplo:

```cmake theme={null}
target_include_directories(
    [YOUR PROJECT NAME]
    "[LOCATION OF PLAYFAB LINUX SDK]/include"
)
```

3. Usando **target\_link\_libraries** ou outra função equivalente, vincule os locais dos arquivos .so ao seu projeto.

Por exemplo:

```cmake theme={null}
set(PLAYFAB_SERVICES_PATH "[LOCATION OF PLAYFAB LINUX SDK]/bin/PlayFabServices.Linux.so")
set(PLAYFAB_CORE_PATH "[LOCATION OF PLAYFAB LINUX SDK]/bin/PlayFabCore.Linux.so")
set(LIBHTTPCLIENT_PATH "[LOCATION OF PLAYFAB LINUX SDK]/bin/libHttpClient.Linux.so")

target_link_librariesc(
    [YOUR PROJECT NAME]
    ${PLAYFAB_SERVICES_PATH}
    ${PLAYFAB_CORE_PATH}
    ${LIBHTTPCLIENT_PATH}
)
```

Agora seu projeto está totalmente configurado para usar o SDK do PlayFab Services para Linux. Siga as próximas etapas para fazer algumas chamadas de exemplo funcionarem.

## Inicialização e login

### Cabeçalhos

Inclua **PFServices.h** para ter acesso a toda a funcionalidade do PlayFab incluída:

```cpp theme={null}
#include <playfab/services/PFServices.h>
```

### Inicialização

A inicialização do PlayFab requer duas chamadas de função: **PFServicesInitialize** e **PFServiceConfigCreateHandle**. O resultado dessa inicialização é um **PFServiceConfigHandle**. Você fornece esse identificador a uma chamada de login subsequente, direcionando a chamada para o título correto no back-end do PlayFab.

```cpp theme={null}
    HRESULT hr = PFServicesInitialize(nullptr); // Add your own error handling when FAILED(hr) == true

    PFServiceConfigHandle serviceConfigHandle{ nullptr };

    hr = PFServiceConfigCreateHandle(
            "https://ABCDEF.playfabapi.com",    // PlayFab API endpoint - obtained in the Game Manager
            "ABCDEF",                           // PlayFab Title id - obtained in the Game Manager
            &serviceConfigHandle);
```

### Fazendo login

A definir

Depois de ter um **PFServiceConfigHandle**, você pode usá-lo para fazer uma chamada de login de jogador. No SDK, use um método **PFAuthenticationLoginWith\*Async**, como **PFAuthenticationLoginWithCustomIDAsync**. Essa função permite fazer login de um jogador no PlayFab usando uma ID personalizada.

Depois de fazer uma chamada de login, você pode verificar o status da chamada com **XAsyncGetStatus**. O status começa como **E\_PENDING** e muda para **S\_OK** depois que a chamada é concluída com êxito. Se a chamada falhar por algum motivo, o status refletirá essa falha. O tratamento de erros em todas as chamadas do PlayFab Services funciona dessa forma.

Junto com um resultado **S\_OK**, você recebe um **PFEntityHandle**. Use esse identificador para fazer as chamadas subsequentes do PlayFab como o jogador conectado. Ele inclui todo o material necessário para se autenticar no serviço PlayFab como esse jogador.

```cpp theme={null}
    PFAuthenticationLoginWithCustomIDRequest request{};
    request.createAccount = true;
    request.customId = "player1";

    XAsyncBlock async{};
    HRESULT hr = PFAuthenticationLoginWithCustomIDAsync(serviceConfigHandle, &request, &async); // Add your own error handling when FAILED(hr) == true
    hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage

    std::vector<char> loginResultBuffer;
    PFAuthenticationLoginResult const* loginResult;
    size_t bufferSize;
    hr = PFAuthenticationLoginWithCustomIDGetResultSize(&async, &bufferSize);
    loginResultBuffer.resize(bufferSize);

    PFEntityHandle entityHandle{ nullptr };
    hr = PFAuthenticationLoginWithCustomIDGetResult(&async, &entityHandle, loginResultBuffer.size(), loginResultBuffer.data(), &loginResult, nullptr);
```

## Chamadas de serviço

Depois de fazer login do jogador, você pode fazer chamadas ao back-end do PlayFab. Veja um exemplo de chamada para obter os arquivos armazenados no PlayFab para o jogador atual.

### Obtendo a EntityKey

Algo que pode ser útil em algumas chamadas ao PlayFab é conhecer a **PFEntityKey** do jogador. Depois de ter um **PFEntityToken**, você pode recuperar uma **PFEntityKey** com **PFEntityGetEntityKey**.

```cpp theme={null}
    PFEntityKey const* pEntityKey{};
    std::vector<char> entityKeyBuffer;
    size_t size{};
    HRESULT hr = PFEntityGetEntityKeySize(entityHandle, &size); // Add your own error handling when FAILED(hr) == true

    entityKeyBuffer.resize(size);
    hr = PFEntityGetEntityKey(entityHandle, entityKeyBuffer.size(), entityKeyBuffer.data(), &pEntityKey, nullptr);
```

### Chamando GetFiles

Todas as chamadas do PlayFab seguem um padrão semelhante: preparar o objeto de solicitação, fazer a chamada (usando o **PFEntityHandle** do login), criar um objeto para receber a resposta e, em seguida, chamar uma função **GetResult** para preencher o contêiner recém-criado.

```cpp theme={null}
    XAsyncBlock async{};
    PFDataGetFilesRequest requestFiles{};
    requestFiles.entity = pEntityKey;

    HRESULT hr = PFDataGetFilesAsync(entityHandle, &requestFiles, &async); // Add your own error handling when FAILED(hr) == true
    hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage

    size_t resultSize;
    hr = PFDataGetFilesGetResultSize(&async, &resultSize);

    std::vector<char> getFilesResultBuffer(resultSize);
    PFDataGetFilesResponse* getFilesResponseResult{ nullptr };
    hr = PFDataGetFilesGetResult(&async, getFilesResultBuffer.size(), getFilesResultBuffer.data(), &getFilesResponseResult, nullptr);
```

## Limpeza

Quando seu jogo estiver pronto para ser desligado ou você precisar limpar o PlayFab por algum outro motivo, feche todos os identificadores abertos e chame **PFServicesUninitializeAsync**.

```cpp theme={null}
    PFEntityCloseHandle(entityHandle);
    entityHandle = nullptr;

    PFServiceConfigCloseHandle(serviceConfigHandle);
    serviceConfigHandle = nullptr;

    XAsyncBlock async{};
    HRESULT hr = PFServicesUninitializeAsync(&async); // Add your own error handling when FAILED(hr) == true
    hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage
```

## Padrão de API assíncrona

O SDK do PlayFab Services segue o [modelo de programação assíncrona](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/system/overviews/async-programming-model) implementado no GDK. Esse modelo de programação envolve o uso de tarefas e filas de tarefas fornecidas pela [biblioteca XAsync](/pt-BR/build/core-features/common/async/async-libraries/async-library-xasync). Esse modelo é consistente com outras funções e extensões do GDK (como a API do XBOX Services). Embora introduza alguma complexidade, ele também oferece um alto grau de controle sobre as operações assíncronas.

Este exemplo mostra como fazer uma chamada assíncrona a **PFDataGetFilesAsync**.

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

        size_t resultSize;
        HRESULT hr = PFDataGetFilesGetResultSize(async, &resultSize);
        if (SUCCEEDED(hr))
        {
            std::vector<char> getFilesResultBuffer(resultSize);
            PFDataGetFilesResponse* getFilesResponseResult{ nullptr };
            PFDataGetFilesGetResult(async, getFilesResultBuffer.size(), getFilesResultBuffer.data(), &getFilesResponseResult, nullptr);
        }
    };

    PFDataGetFilesRequest requestFiles{};
    requestFiles.entity = m_pEntityKey;
    HRESULT hr = PFDataGetFilesAsync(m_entityHandle, &requestFiles, async.get());
    if (SUCCEEDED(hr))
    {
        async.release(); // at this point, the callback will be called so release the unique ptr
    }

```

## Tratamento de erros

As operações **XAsync** concluídas retornam códigos de status HTTP. Um código de status de erro se manifesta como um **HRESULT** de falha, como **HTTP\_E\_STATUS\_NOT\_FOUND**, ao chamar **XAsyncGetStatus()** ou uma das APIs **PF\*Get()**.

Para ver as mensagens de erro detalhadas retornadas pelo serviço, consulte a próxima seção sobre depuração. Essas mensagens de erro detalhadas podem ser úteis durante o desenvolvimento para entender melhor como o serviço PlayFab reage às solicitações do cliente.

## Depuração

A maneira mais fácil de ver os resultados e depurar qualquer chamada no SDK do PlayFab Services é habilitar o [rastreamento de depuração](/pt-BR/services/playfab/sdks/c/tracing). Habilitar o rastreamento de depuração permite tanto ver os resultados na janela de saída do depurador quanto conectar os resultados aos logs do próprio jogo.

## Referência

[Documentação de referência da API](/pt-BR/services/playfab/api-references/c/pfauthentication/pfauthentication_members)


## Related topics

- [Linguagens compatíveis com o PlayFab](/pt-BR/services/playfab/sdks/languages/index.md)
- [Plataformas compatíveis com o PlayFab](/pt-BR/services/playfab/sdks/platforms/index.md)
- [Início rápido de C++ para Linux](/pt-BR/services/playfab/sdks/playfab-cpp/quickstart-linux.md)
- [Início rápido do Party](/pt-BR/services/playfab/multiplayer/networking/quickstart.md)
- [Início rápido](/pt-BR/services/playfab/economy-monetization/economy-v2/quickstart.md)
