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

# Identificadores de entidade

> Gerencie as credenciais de PFEntityHandle, a contagem de referências e o tempo de vida dos tokens de entidade para chamadas autenticadas de jogador e de título no SDK do PlayFab para C.

Um **PFEntityHandle** é sua principal credencial para fazer chamadas de serviço do PlayFab. Ele representa uma entidade autenticada (um jogador, title\_player\_account, ou um título) e contém o token de entidade de que o SDK precisa para autorizar as solicitações. Toda chamada de login ou autenticação retorna um **PFEntityHandle**, e toda chamada de serviço exige um.

## Obtendo um identificador de entidade

Você não cria identificadores de entidade diretamente. Em vez disso, obtém um como saída de uma chamada de login ou autenticação bem-sucedida.

**Login de jogador (exemplo do Windows):**

```cpp theme={null}
PFAuthenticationLoginWithXUserRequest request{};
request.createAccount = true;
request.user = userHandle; // XUserHandle from XUserAddAsync

XAsyncBlock async{};
HRESULT hr = PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, &request, &async);
hr = XAsyncGetStatus(&async, true);

PFEntityHandle entityHandle{ nullptr };
size_t bufferSize{};
hr = PFAuthenticationLoginWithXUserGetResultSize(&async, &bufferSize);

std::vector<char> loginResultBuffer(bufferSize);
PFAuthenticationLoginResult const* loginResult{};
hr = PFAuthenticationLoginWithXUserGetResult(
    &async, &entityHandle,
    loginResultBuffer.size(), loginResultBuffer.data(),
    &loginResult, nullptr);
```

**Entidade de título (servidor):**

As entidades de título se autenticam com uma chave secreta em vez de uma credencial de usuário. O **PFEntityHandle** retornado funciona da mesma forma, mas representa o título em vez de um jogador. Consulte [Acessando o PlayFab com uma entidade de título](/pt-BR/services/playfab/sdks/c/server) para obter detalhes.

## Propriedade dos identificadores e contagem de referências

**PFEntityHandle** tem contagem de referências. Quando você recebe um identificador de uma chamada de login, possui uma referência. Você pode criar referências adicionais com [**PFEntityDuplicateHandle**](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityduplicatehandle) e liberá-las com [**PFEntityCloseHandle**](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityclosehandle). O objeto de entidade subjacente só é destruído quando a última referência é fechada.

**Regras:**

* Toda chamada a uma função `GetResult` de login ou a **PFEntityDuplicateHandle** fornece um identificador que você deve fechar.
* Fechar um identificador não invalida outros identificadores da mesma entidade.
* Feche todos os identificadores antes de chamar [**PFServicesUninitializeAsync**](/pt-BR/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync).

```cpp theme={null}
// Duplicate a handle for another component
PFEntityHandle secondHandle{ nullptr };
HRESULT hr = PFEntityDuplicateHandle(entityHandle, &secondHandle);

// Both handles are independently valid
// ...

// Each owner closes their own handle
PFEntityCloseHandle(secondHandle);
PFEntityCloseHandle(entityHandle);
```

## Obtendo informações da entidade

### Chave da entidade

A chave da entidade identifica a entidade (seu tipo e sua ID). Use o padrão de duas chamadas: primeiro obtenha o tamanho e depois obtenha os dados.

```cpp theme={null}
size_t size{};
HRESULT hr = PFEntityGetEntityKeySize(entityHandle, &size);

std::vector<char> buffer(size);
PFEntityKey const* entityKey{};
hr = PFEntityGetEntityKey(entityHandle, buffer.size(), buffer.data(), &entityKey, nullptr);

// entityKey->type is "title_player_account" for players
// entityKey->id is the entity's unique ID
```

### Token de entidade

O token de entidade autoriza as chamadas de serviço. O SDK gerencia os tokens automaticamente, mas você pode recuperar o atual, se necessário.

```cpp theme={null}
XAsyncBlock async{};
HRESULT hr = PFEntityGetEntityTokenAsync(entityHandle, &async);
hr = XAsyncGetStatus(&async, true);

size_t size{};
hr = PFEntityGetEntityTokenResultSize(&async, &size);

std::vector<char> buffer(size);
const PFEntityToken* entityToken{};
hr = PFEntityGetEntityTokenResult(&async, buffer.size(), buffer.data(), &entityToken, nullptr);

// entityToken->token is the token string
// entityToken->expiration is the optional expiration time (UTC)
```

### Verificando o tipo de entidade

Use [**PFEntityIsTitlePlayer**](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityistitleplayer) como uma verificação rápida, em vez de inspecionar a cadeia de caracteres do tipo da chave da entidade:

```cpp theme={null}
bool isTitlePlayer{};
HRESULT hr = PFEntityIsTitlePlayer(entityHandle, &isTitlePlayer);
```

## Entidades de jogador e entidades de título

As entidades de jogador e de título usam **PFEntityHandle**, mas diferem no que podem fazer:

| | Entidade de jogador | Entidade de título |
| - | - | - |
| **Como obtê-la** | Chamada de login (por exemplo, `PFAuthenticationLoginWithXUserAsync`) | `PFAuthenticationGetEntityWithSecretKeyAsync` |
| **Tipo de entidade** | `title_player_account` | `title` |
| [**PFEntityIsTitlePlayer**](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityistitleplayer) | Retorna `true` | Retorna `false` |
| [**PFEntityGetSecretKey**](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetsecretkey) | Falha com `E_PF_NOSECRETKEY` | Retorna a chave secreta |
| **APIs disponíveis** | APIs com prefixo Client e sem prefixo | APIs com prefixo Server e sem prefixo |

As APIs sem prefixo (por exemplo, Inventory, Leaderboards, Data) geralmente podem ser chamadas tanto por entidades de jogador quanto de título, a menos que indicado de outra forma na documentação delas. As APIs com prefixo Client são exclusivas de jogadores, e as APIs com prefixo Server são exclusivas de títulos.

**PFEntityGetSecretKey** recupera a chave secreta associada a uma entidade de título. Ela falha para entidades de jogador, pois elas não têm uma.

```cpp theme={null}
size_t keySize{};
HRESULT hr = PFEntityGetSecretKeySize(entityHandle, &keySize);
if (SUCCEEDED(hr))
{
    std::vector<char> secretKey(keySize);
    hr = PFEntityGetSecretKey(entityHandle, secretKey.size(), secretKey.data(), nullptr);
}
```

<Note>
  **PFEntityGetSecretKey** está disponível apenas nas plataformas Windows, Linux e macOS.
</Note>

## Manipuladores de eventos de token

O SDK atualiza automaticamente os tokens de entidade antes que expirem. Você pode registrar retornos de chamada para observar esses eventos.

### Token expirado

Se a atualização automática falhar (por exemplo, se a credencial de login original não for mais válida), o SDK disparará o evento de token expirado. Registre um manipulador para fornecer uma nova credencial e tentar o login novamente.

```cpp theme={null}
PFRegistrationToken registrationToken{};
HRESULT hr = PFEntityRegisterTokenExpiredEventHandler(
    nullptr,  // XTaskQueueHandle, or nullptr for default
    nullptr,  // optional context
    [](void* ctx, PFEntityKey const* entityKey)
    {
        // Re-authenticate the player with a fresh credential
        // See relogin.md for a complete example
    },
    &registrationToken);
```

### Token atualizado

Registre um manipulador de token atualizado se quiser saber quando o SDK atualizar um token em segundo plano com êxito. Isso é informativo; você não precisa realizar nenhuma ação.

```cpp theme={null}
PFRegistrationToken registrationToken{};
HRESULT hr = PFEntityRegisterTokenRefreshedEventHandler(
    nullptr,  // XTaskQueueHandle, or nullptr for default
    nullptr,  // optional context
    [](void* ctx, PFEntityKey const* entityKey, const PFEntityToken* newToken)
    {
        // Log the refresh or update cached token references
    },
    &registrationToken);
```

### Quando registrar e cancelar o registro

* **Registre** os manipuladores cedo, logo após a inicialização do SDK e antes do login. Isso garante que você não perca nenhum evento.
* **Cancele o registro** dos manipuladores durante o desligamento, antes de fechar os identificadores de entidade.

```cpp theme={null}
PFEntityUnregisterTokenExpiredEventHandler(expiredRegistrationToken);
PFEntityUnregisterTokenRefreshedEventHandler(refreshedRegistrationToken);
```

Para ver um passo a passo completo do tratamento da expiração de tokens e do novo login, consulte [Tratando a expiração de tokens](/pt-BR/services/playfab/sdks/c/relogin).

## Acessadores utilitários

Você pode recuperar o ponto de extremidade da API e a ID do título de um identificador de entidade. Eles vêm do **PFServiceConfigHandle** usado durante o login.

```cpp theme={null}
// Get API endpoint
size_t endpointSize{};
HRESULT hr = PFEntityGetAPIEndpointSize(entityHandle, &endpointSize);

std::vector<char> endpoint(endpointSize);
hr = PFEntityGetAPIEndpoint(entityHandle, endpoint.size(), endpoint.data(), nullptr);

// Get title ID
size_t titleIdSize{};
hr = PFEntityGetTitleIdSize(entityHandle, &titleIdSize);

std::vector<char> titleId(titleIdSize);
hr = PFEntityGetTitleId(entityHandle, titleId.size(), titleId.data(), nullptr);
```

## Exemplo completo

Este exemplo demonstra como criar, duplicar, consultar e fechar identificadores de entidade:

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

void EntityHandleExample(PFServiceConfigHandle serviceConfigHandle, XUserHandle userHandle)
{
    //
    // Log in and get an entity handle
    //
    PFAuthenticationLoginWithXUserRequest request{};
    request.createAccount = true;
    request.user = userHandle;

    XAsyncBlock asyncLogin{};
    HRESULT hr = PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, &request, &asyncLogin);
    hr = XAsyncGetStatus(&asyncLogin, true);

    PFEntityHandle entityHandle{ nullptr };
    size_t resultSize{};
    hr = PFAuthenticationLoginWithXUserGetResultSize(&asyncLogin, &resultSize);

    std::vector<char> loginBuffer(resultSize);
    PFAuthenticationLoginResult const* loginResult{};
    hr = PFAuthenticationLoginWithXUserGetResult(
        &asyncLogin, &entityHandle,
        loginBuffer.size(), loginBuffer.data(),
        &loginResult, nullptr);

    //
    // Register token event handlers
    //
    PFRegistrationToken expiredToken{};
    hr = PFEntityRegisterTokenExpiredEventHandler(nullptr, nullptr,
        [](void* ctx, PFEntityKey const* entityKey)
        {
            // Handle re-authentication
        }, &expiredToken);

    PFRegistrationToken refreshedToken{};
    hr = PFEntityRegisterTokenRefreshedEventHandler(nullptr, nullptr,
        [](void* ctx, PFEntityKey const* entityKey, const PFEntityToken* newToken)
        {
            // Log token refresh
        }, &refreshedToken);

    //
    // Duplicate the handle for a subsystem
    //
    PFEntityHandle subsystemHandle{ nullptr };
    hr = PFEntityDuplicateHandle(entityHandle, &subsystemHandle);

    //
    // Query entity info
    //
    bool isTitlePlayer{};
    hr = PFEntityIsTitlePlayer(entityHandle, &isTitlePlayer);

    size_t keySize{};
    hr = PFEntityGetEntityKeySize(entityHandle, &keySize);

    std::vector<char> keyBuffer(keySize);
    PFEntityKey const* entityKey{};
    hr = PFEntityGetEntityKey(entityHandle, keyBuffer.size(), keyBuffer.data(), &entityKey, nullptr);

    //
    // ... make service calls with entityHandle or subsystemHandle ...
    //

    //
    // Cleanup: unregister handlers, then close all handles
    //
    PFEntityUnregisterTokenExpiredEventHandler(expiredToken);
    PFEntityUnregisterTokenRefreshedEventHandler(refreshedToken);

    PFEntityCloseHandle(subsystemHandle);
    PFEntityCloseHandle(entityHandle);
}
```

## Referência de API

| Função | Descrição |
| - | - |
| [PFEntityDuplicateHandle](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityduplicatehandle) | Duplica um identificador, incrementando a contagem de referências. Ambos os identificadores devem ser fechados de forma independente. |
| [PFEntityCloseHandle](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityclosehandle) | Fecha um identificador, decrementando a contagem de referências. A entidade é destruída quando o último identificador é fechado. |
| [PFEntityGetEntityKeySize](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetentitykeysize) | Obtém o tamanho do buffer necessário para armazenar a chave da entidade. |
| [PFEntityGetEntityKey](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetentitykey) | Obtém a chave (tipo e ID) da entidade. |
| [PFEntityGetEntityTokenAsync](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetentitytokenasync) | Recupera de forma assíncrona o token de entidade armazenado em cache. |
| [PFEntityGetEntityTokenResultSize](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetentitytokenresultsize) | Obtém o tamanho do buffer necessário para o resultado do token de entidade. |
| [PFEntityGetEntityTokenResult](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetentitytokenresult) | Obtém o token de entidade de uma chamada PFEntityGetEntityTokenAsync concluída. |
| [PFEntityIsTitlePlayer](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityistitleplayer) | Retorna se a entidade é um title\_player\_account. |
| [PFEntityGetSecretKeySize](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetsecretkeysize) | Obtém o tamanho do buffer necessário para a chave secreta. Falha se a entidade não for uma entidade de título. |
| [PFEntityGetSecretKey](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetsecretkey) | Obtém a chave secreta de uma entidade de título. Disponível apenas no Windows, Linux e macOS. |
| [PFEntityGetAPIEndpointSize](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetapiendpointsize) | Obtém o tamanho do buffer necessário para a cadeia de caracteres do ponto de extremidade da API. |
| [PFEntityGetAPIEndpoint](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentitygetapiendpoint) | Obtém o ponto de extremidade da API da configuração de serviço associada à entidade. |
| **PFEntityGetTitleIdSize** | Obtém o tamanho do buffer necessário para a cadeia de caracteres da ID do título. |
| **PFEntityGetTitleId** | Obtém a ID do título da configuração de serviço associada à entidade. |
| [PFEntityRegisterTokenExpiredEventHandler](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityregistertokenexpiredeventhandler) | Registra um retorno de chamada para quando a atualização automática do token falhar. |
| [PFEntityUnregisterTokenExpiredEventHandler](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityunregistertokenexpiredeventhandler) | Cancela o registro de um retorno de chamada de token expirado. |
| [PFEntityRegisterTokenRefreshedEventHandler](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityregistertokenrefreshedeventhandler) | Registra um retorno de chamada para quando o SDK atualizar um token com êxito. |
| [PFEntityUnregisterTokenRefreshedEventHandler](/pt-BR/services/playfab/api-references/c/pfentity/functions/pfentityunregistertokenrefreshedeventhandler) | Cancela o registro de um retorno de chamada de token atualizado. |

Para ver a referência de API completa, consulte [Membros de PFEntity](/pt-BR/services/playfab/api-references/c/pfentity/pfentity_members).

## Confira também

* [Tratando a expiração de tokens](/pt-BR/services/playfab/sdks/c/relogin)
* [Acessando o PlayFab com uma entidade de título](/pt-BR/services/playfab/sdks/c/server)
* [Ciclo de vida do SDK](/pt-BR/services/playfab/sdks/c/lifecycle)
* [Início rápido: Windows](/pt-BR/services/playfab/sdks/c/quickstart-gdk)
* [Início rápido: Win32](/pt-BR/services/playfab/sdks/c/quickstart-win32)


## Related topics

- [Migrar do SDK autônomo v1 do PlayFab para o SDK unificado v2](/pt-BR/services/playfab/sdks/unified-sdk/migrating-from-v1.md)
- [PFProfilesGetEntityProfilesRequest](/pt-BR/services/playfab/api-references/c/pfprofilestypes/structs/pfprofilesgetentityprofilesrequest.md)
- [PFProfilesGetProfilesAsync](/pt-BR/services/playfab/api-references/c/pfprofiles/functions/pfprofilesgetprofilesasync.md)
- [Início rápido (Windows) - Party e Multiplayer](/pt-BR/services/playfab/sdks/unified-sdk/quickstart-windows-party.md)
- [Modelo de programação de entidades](/pt-BR/services/playfab/live-service-management/game-configuration/entities/index.md)
