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

# Biblioteca auxiliar de XBOX Live para PlayFab Party

> Use la biblioteca auxiliar PartyXboxLive para conectar las identidades de XBOX Live, los permisos de chat y la configuración de privacidad con la voz y las redes de PlayFab Party.

# Información general de la biblioteca auxiliar de XBOX Live

La biblioteca auxiliar de XBOX Live para PlayFab Party está diseñada para ayudar a los juegos que usan PlayFab Party a cumplir las [directivas de XBOX Live](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/live/get-started/live-xbl-overview) relacionadas con la comunicación (XR-015 y XR-045). La biblioteca auxiliar de XBOX Live está disponible en [Nuget.org](https://www.nuget.org/profiles/PlayFab).

## Compatibilidad con la biblioteca de PlayFab Party

Aunque nos esforzamos por minimizar los cambios importantes en nuestras API, algunos cambios realizados en la API de PlayFab Party pueden hacer que la biblioteca auxiliar de XBOX Live devuelva valores erróneos. Consulte la tabla siguiente para asegurarse de que las versiones de sus bibliotecas son compatibles.

| Versión de la biblioteca auxiliar <br /> de XBOX Live | Versión 1.0.1 de <br /> PlayFab Party | Versión 1.3.0+ de <br /> PlayFab Party |
| ----------------------------------------------------- | :-----------------------------------: | :------------------------------------: |
| **1.0.1**                                             |                   ✔                   |                                        |
| **1.1.0**                                             |                   ✔                   |                                        |
| **1.2.0**                                             |                                       |                    ✔                   |
| **1.2.5**                                             |                                       |                    ✔                   |

## Seguimiento de los usuarios de XBOX Live

La biblioteca auxiliar de XBOX Live de PlayFab Party debe recibir información explícita sobre los usuarios de XBOX Live que participan actualmente en la sesión de Party. Se recomienda que los títulos informen a la biblioteca escuchando los cambios de su [documento de sesión multijugador](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/live/get-started/live-xbl-overview) y reflejando esa lista en la biblioteca auxiliar de XBOX Live mediante `PartyXblManager::CreateLocalChatUser` y `PartyXblManager::CreateRemoteChatUser`.

Para los usuarios locales:

```cpp theme={null}
void
OnLocalXboxUserAddedToMPSD(
    uint64_t xboxUserId
    )
{
    PartyXblLocalChatUser* localChatUser;
    PartyError err = PartyXblManager::GetSingleton().CreateLocalChatUser(xboxUserId, nullptr, &localChatUser);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("CreateLocalChatUser failed: %s\n", PartyXblManager::GetErrorMessage(err));
        return;
    }
}
```

En este punto, si ya existe un PartyLocalChatControl para el usuario local de XBOX correspondiente, puede asociarlo a este PartyXblLocalChatUser mediante los métodos SetCustomContext.

```cpp theme={null}
    localChatControl->SetCustomContext(localChatUser);
    localChatUser->SetCustomContext(localChatControl);
```

De lo contrario, puede usar este nuevo PartyXblLocalChatUser para generar el control de chat y asociarlos después. Consulte [Creación de PartyLocalChatControls a partir de PartyXblLocalChatUsers](#creating-partylocalchatcontrols-from-partyxbllocalchatusers) para obtener más información.

Para los usuarios remotos:

```cpp theme={null}
void
OnRemoteXboxUserAddedToMPSD(
    uint64_t xboxUserId
    )
{
    PartyXblChatUser* remoteChatUser;
    PartyError err = PartyXblManager::GetSingleton().CreateRemoteChatUser(remoteXboxUserId, &remoteChatUser);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("CreateRemoteChatUser failed: %s\n", PartyXblManager::GetErrorMessage(err));
        return;
    }
```

En este punto, si ya existe un PartyChatControl para el usuario remoto de XBOX correspondiente, puede asociarlo a este PartyXblChatUser mediante los métodos SetCustomContext.

```cpp theme={null}
    remoteChatControl->SetCustomContext(remoteChatUser);
    remoteChatUser->SetCustomContext(remoteChatControl);
```

Tenga en cuenta que las actualizaciones del documento de sesión y las actualizaciones de la lista de controles de chat remotos pueden no estar ordenadas, y es posible que necesite una lógica de asociación similar al procesar las actualizaciones de `PartyChatControlCreatedStateChange` para los controles de chat remotos.

Tanto para los usuarios de chat locales como remotos, es importante tener en cuenta que la biblioteca principal de Party identifica a los usuarios y controles de chat mediante identificadores de entidad de PlayFab, mientras que la biblioteca auxiliar de XBOX Live identifica a los usuarios de chat con identificadores de usuario de XBOX. Por lo tanto, a menudo es necesario traducir entre ambos. Consulte [Asignación entre identificadores de usuario de XBOX Live e identificadores de entidad de PlayFab](#mapping-between-xbox-live-user-ids-and-playfab-entity-ids) para obtener más información.

## Creación de PartyLocalChatControls a partir de PartyXblLocalChatUsers

Los objetos `PartyXblLocalChatUser` a menudo solo son útiles cuando están asociados a objetos `PartyLocalUser` y `PartyLocalChatControl` de la biblioteca de Party. La generación de objetos `PartyLocalUser` y `PartyLocalChatControl` requiere que los títulos inicien la sesión de sus usuarios en PlayFab y recuperen el `entityId` y el `titlePlayerEntityToken` de su usuario. El inicio de sesión se puede realizar mediante el [SDK de C++ de PlayFab](/services/playfab/sdks/playfab-cpp), pero si un título tiene previsto usar las credenciales de XBOX Live para iniciar sesión en PlayFab, puede usar `PartyXblManager::LoginToPlayFab` para evitar incorporar una dependencia adicional.

El ejemplo siguiente muestra cómo la biblioteca auxiliar de XBOX Live puede ayudarle a crear objetos `PartyLocalUser` y `PartyLocalChatControl` a partir de objetos `PartyXblLocalChatUser`. Para obtener más información sobre la creación de objetos `PartyXblLocalChatUser`, consulte [Seguimiento de los usuarios de XBOX Live](#keeping-track-of-xbox-live-users).

```cpp theme={null}
    err = PartyXblManager::GetSingleton().LoginToPlayFab(localChatUser, nullptr);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("LoginToPlayFab failed: %s\n", PartyXblManager::GetErrorMessage(err));
        return;
    }
```

Poco después de llamar a `PartyXblManager::LoginToPlayFab`, recibirá un `PartyXblLoginToPlayFabCompletedStateChange` que contiene el resultado de la operación de inicio de sesión.

```cpp theme={null}
    PartyLocalUser* partyLocalUser;
    if (stateChange->stateChangeType == PartyXblStateChangeType::LoginToPlayFabCompleted)
    {
        auto loginToPlayFabCompleted = static_cast<PartyXblLoginToPlayFabCompletedStateChange*>(stateChange);
        if (loginToPlayFabCompleted->result == PartyXblStateChangeResult::Succeeded)
        {
            err = PartyManager::GetSingleton().CreateLocalUser(
                loginToPlayFabCompleted->entityId,
                loginToPlayFabCompleted->titlePlayerEntityToken,
                partyLocalUser));
            if (PARTY_FAILED(err))
            {
                DEBUGLOG("CreateLocalUser failed: %s\n", PartyManager::GetErrorMessage(err));
                return;
            }
        }
    }

    PartyLocalDevice* localDevice;
    err = PartyManager::GetSingleton().GetLocalDevice(&localDevice);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("GetLocalDevice failed: %s\n", PartyManager::GetErrorMessage(err));
        return;
    }

    PartyLocalChatControl* localChatControl;
    err = localDevice->CreateChatControl(partyLocalUser, nullptr, nullptr, &localChatControl);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("CreateChatControl failed: %s\n", PartyManager::GetErrorMessage(err));
        return;
    }

    // We can use the custom context on the PartyXblLocalChatUser to store the PartyLocalChatControl for easy access
    // in the future.
    localChatUser->SetCustomContext(localChatControl);
```

## Respeto de las preferencias de accesibilidad de un usuario de XBOX Live

El objeto `PartyXblLocalChatUser` expone algunas de las preferencias de accesibilidad del usuario de XBOX Live que son relevantes para las sesiones de chat de Party. Los títulos pueden usar esta información para proporcionar una mejor experiencia a sus jugadores habilitando de inmediato algunas de las características de accesibilidad de Party.

```cpp theme={null}
    PartyXblAccessibilitySettings accessibilitySettings;
    err = localChatUser->GetAccessibilitySettings(&accessibilitySettings);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("GetAccessibilitySettings failed: %s\n", PartyXblManager::GetErrorMessage(err));
        return;
    }

    if (accessibilitySettings.speechToTextEnabled)
    {
        PartyVoiceChatTranscriptionOptions option = PartyVoiceChatTranscriptionOptions::TranscribeOtherChatControlsWithMatchingLanguages;
        m_localChatControl->SetTranscriptionOptions(option, nullptr);
    }
```

## Respeto de la configuración de privacidad y los permisos de un usuario de XBOX Live

Según las directivas de XBOX Live, los títulos no deben permitir la comunicación a través de XBOX Live cuando la privacidad o los permisos del usuario no lo permitan. La biblioteca auxiliar de XBOX Live le ayuda a lograrlo al permitirle consultar el valor de `PartyChatPermissionOptions` más restrictivo entre dos usuarios permitido por las directivas de XBOX Live. Cada vez que este valor cambia, la biblioteca genera un `PartyXblRequiredChatPermissionInfoChangedStateChange`. El valor de `PartyChatPermissionOptions` actualizado se puede obtener mediante una llamada a `PartyXblLocalChatUser::GetRequiredChatPermissionInfo()`.

```cpp theme={null}
    PartyXblChatUser* remoteChatUser;
    PartyError err = PartyXblManager::GetSingleton().CreateRemoteChatUser(remoteXboxUserId, &remoteChatUser);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("CreateRemoteChatUser failed: %s\n", PartyXblManager::GetErrorMessage(err));
        return;
    }

    // Once the chat control representing this remote Xbox Live user joins a network, we can use the custom context
    // on the PartyXblChatUser to store the chat control object for quick access in the future.
    remoteChatUser->SetCustomContext(m_remotePartyChatControl);
```

La biblioteca auxiliar de XBOX Live realiza un seguimiento de la configuración de privacidad y privilegios de cada usuario de chat remoto en relación con cada usuario de chat local comunicándose con los servicios de privacidad de XBOX Live. Además, la biblioteca escuchará los cambios en esta configuración suscribiéndose a las actualizaciones de [Real-Time Activity](/services/xbox-services/fundamentals/rta/live-rta-nav). Cuando se agregan nuevos usuarios de chat remotos o cuando cambia la relación de privacidad y privilegios entre un usuario de chat local y un usuario de chat remoto existente, se genera un `PartyXblRequiredChatPermissionInfoChangedStateChange` para notificarle que ahora hay disponible un valor de `PartyChatPermissionOptions` actualizado.

```cpp theme={null}
    // Wait for PartyXblRequiredChatPermissionInfoChangedStateChange
    if (stateChange->stateChangeType == PartyXblStateChangeType::RequiredChatPermissionInfoChanged)
    {
        auto chatPermissionChanged = static_cast<PartyXblRequiredChatPermissionInfoChangedStateChange*>(stateChange);

        PartyXblLocalChatUser* localChatUser = chatPermissionChanged->localChatUser;
        PartyXblChatUser* targetChatUser = chatPermissionChanged->targetChatUser;

        PartyXblChatPermissionInfo chatPermissionInfo;
        PartyError err = localChatUser->GetRequiredChatPermissionInfo(targetChatUser, &chatPermissionInfo);
        if (PARTY_FAILED(err))
        {
            DEBUGLOG("GetRequiredChatPermissionInfo failed: %s\n", PartyXblManager::GetErrorMessage(err));
            return;
        }

        PartyLocalChatControl* localChatControl;
        localChatUser->GetCustomContext(reinterpret_cast<void**>(&localChatControl));
        if (PARTY_FAILED(err))
        {
            DEBUGLOG("GetCustomContext failed: %s\n", PartyXblManager::GetErrorMessage(err));
            return;
        }

        PartyChatControl* targetChatControl;
        targetChatUser->GetCustomContext(reinterpret_cast<void**>(&targetChatControl));
        if (PARTY_FAILED(err))
        {
            DEBUGLOG("GetCustomContext failed: %s\n", PartyXblManager::GetErrorMessage(err));
            return;
        }

        localChatControl->SetPermission(targetChatControl, chatPermissionInfo.chatPermissionMask);
        if (PARTY_FAILED(err))
        {
            DEBUGLOG("SetPermission failed: %s\n", PartyXblManager::GetErrorMessage(err));
            return;
        }
    }
```

La estructura `PartyXblChatPermissionInfo` contiene dos elementos de información:

* Una máscara de `PartyChatPermissionOptions` que se puede pasar tal cual a `PartyLocalChatControl::SetPermission()` o que se puede usar como máscara binaria si ya tiene un valor de `PartyChatPermissionOptions` que quiere usar pero desea asegurarse de que respeta las directivas de XBOX Live.
* Un valor de `PartyXblChatPermissionMaskReason` que proporciona información adicional sobre el valor de `PartyXblChatPermissionInfo::chatPermissionMask`

| **PartyXblChatPermissionMaskReason** | **Explicación**                                                                                                                           |
| :----------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
| NoRestriction                        | Actualmente no hay ninguna restricción que se aplique a este permiso de chat.                                                             |
| Determining                          | La comunicación está restringida mientras se determinan el privilegio de comunicación y la configuración de privacidad del usuario local  |
| Privilege                            | La comunicación está restringida debido al privilegio de comunicación del usuario local.                                                  |
| Privacy                              | La comunicación está restringida debido a la configuración de privacidad del usuario local en relación con el usuario de chat de destino. |
| InvalidTargetUser                    | La comunicación está restringida porque los servicios de XBOX Live no reconocieron al usuario de destino como válido.                     |
| XboxLiveServiceError                 | El permiso de chat requerido no se pudo determinar correctamente debido a problemas con los servicios de XBOX Live.                       |
| UnknownError                         | El permiso de chat requerido no se pudo determinar correctamente debido a un error interno desconocido.                                   |

## Respeto de los permisos de comunicación entre redes

Los títulos que admiten el juego y la comunicación entre redes entre jugadores de XBOX Live y jugadores que no son de XBOX Live deben comprobar los permisos de comunicación antes de permitir la comunicación entre esos jugadores. La biblioteca auxiliar de XBOX Live proporciona esta información a través de `PartyXblLocalChatUser::GetCrossNetworkCommunicationPrivacySetting()`. Este método devuelve una enumeración `PartyXblCrossNetworkCommunicationPrivacySetting` con tres valores posibles:

| **PartyXblCrossNetworkCommunicationPrivacySetting** | **Explicación**                                                                                                                    |
| :-------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
| Allowed                                             | Los permisos de este usuario de XBOX Live están configurados para permitir la comunicación con todos los jugadores de otras redes. |
| FriendsOnly                                         | Los permisos de este usuario de XBOX Live están configurados para permitir la comunicación solo con amigos de otras redes.         |
| Disallowed                                          | Los permisos de este usuario de XBOX Live no permiten ninguna comunicación con jugadores de otras redes.                           |

```cpp theme={null}
    PartyXblCrossNetworkCommunicationPrivacySetting crossNetworkSetting;
    localChatUser->GetCrossNetworkCommunicationPrivacySetting(&crossNetworkSetting);

    if (crossNetworkSetting == PartyXblCrossNetworkCommunicationPrivacySetting::Disallowed)
    {
        m_localChatControl->SetPermissions(crossNetworkChatControl, PartyChatPermissionOptions::None);
    }
```

Puede encontrar más información sobre XR-015 y cómo se relaciona con el juego y la comunicación entre redes [aquí](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/live/get-started/live-xbl-overview)

## Asignación entre identificadores de usuario de XBOX Live e identificadores de entidad de PlayFab

Muchos títulos de XBOX Live que usan PlayFab Party necesitan traducir entre los identificadores de usuario de XBOX Live (usados en todo el ecosistema de XBOX Live) y los identificadores de entidad de PlayFab (usados por PlayFab Party). Con `PartyXblManager::GetEntityIdsFromXboxLiveUserIds`, los títulos pueden recuperar una lista de identificadores de entidad de PlayFab correspondientes a una lista determinada de identificadores de usuario de XBOX Live. Se espera que los títulos ya tengan una lista de identificadores de usuario de XBOX Live mediante el uso de un servicio de listas externo, como el [Multiplayer Session Directory](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/live/get-started/live-xbl-overview). Al asociar los identificadores de usuario de XBOX Live de la lista con sus identificadores de entidad de PlayFab, podemos construir una asignación de todos los identificadores de entidad de PlayFab correspondientes a la lista de la sesión de juego. Esta asignación se puede usar después para asociar los objetos `PartyEndpoint` y `PartyChatControl` con sus usuarios de XBOX Live correspondientes.

<Note>
  Cada identificador de usuario de XBOX Live solo se asignará a un identificador de entidad de PlayFab si este usuario de XBOX Live ya se ha vinculado a una cuenta de PlayFab. Se crea y vincula automáticamente una cuenta de PlayFab la primera vez que se llama a `PartyXblManager::LoginToPlayFab` para un usuario de XBOX determinado. Como alternativa, los consumidores del SDK de PlayFab pueden usar la API [LoginWithXbox](https://learn.microsoft.com/en-us/rest/api/playfab/client/authentication/login-with-xbox?view=playfab-rest\&preserve-view=true) para lograr los mismos resultados.
</Note>

El `PartyXblLocalChatUser` local se usará para autenticarse en PlayFab. Si el usuario no había iniciado sesión previamente en PlayFab con una llamada a `PartyXblManager::LoginToPlayFab`, la biblioteca auxiliar de XBOX Live tendrá que autenticar al usuario en segundo plano.

```cpp theme={null}
    uint32_t userCount;
    PartyXblChatUserArray chatUsers;
    PartyError err = PartyXblManager::GetSingleton().GetChatUsers(&userCount, &users);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("GetChatUsers failed: %s\n", PartyXblManager::GetErrorMessage(err));
        return;
    }

    // The list of remote Xbox Live User IDs. This can be populated with arbitrary IDs
    // std::vector<uint64_t> remoteXboxLiveUserIds = {2533274792693551, 2814659110958830};
    //
    // but can also be pulled from the list of remote chat users
    std::vector<uint64_t> remoteXboxLiveUserIds;
    for (uint32_t i = 0; i < userCount; ++i)
    {
        PartyXblChatUser* chatUser = users[i];

        PartyXblLocalChatUser* localChatUser;
        err = chatUser->GetLocal(&localChatUser);
        if (PARTY_FAILED(err))
        {
            DEBUGLOG("PartyChatUser(0x%p)::GetLocal failed: %s\n", chatUser, PartyXblManager::GetErrorMessage(err));
            return;
        }

        if (localChatUser != nullptr)
        {
            continue; // ignore local users
        }

        uint64_t userId;
        err = chatUser->GetXboxUserId(&userId);
        if (PARTY_FAILED(err))
        {
            DEBUGLOG("PartyChatUser(0x%p)::GetXboxUserId failed: %s\n", chatUser, PartyXblManager::GetErrorMessage(err));
            return;
        }

        remoteXboxLiveUserIds.push_back(userId);
    }

    err = PartyXblManager::GetSingleton().GetEntityIdsFromXboxLiveUserIds(
        remoteXboxLiveUserIds.size(),
        remoteXboxLiveUserIds.data(),
        localChatUser,
        nullptr);
    if (PARTY_FAILED(err))
    {
        DEBUGLOG("GetEntityIdsFromXboxLiveUserIds failed: %s\n", PartyXblManager::GetErrorMessage(err));
        return;
    }
```

Poco después de llamar a `PartyXblManager::GetEntityIdsFromXboxLiveUserIds`, recibirá un `PartyXblGetEntityIdsFromXboxLiveUserIdsCompletedStateChange` que contiene el resultado de la operación. Este resultado se puede usar para construir o actualizar sus asignaciones.

```cpp theme={null}
    // Wait for PartyXblGetEntityIdsFromXboxLiveUserIdsCompletedStateChange
    if (stateChange->stateChangeType == PartyXblStateChangeType::GetEntityIdsFromXboxLiveUserIdsCompleted)
    {
        std::vector<std::pair<uint64_t, std::string>> cachedXboxUserIdToPlayFabEntityIdMap;

        auto getEntityIdsFromXboxLiveUserIdsResult = static_cast<PartyXblGetEntityIdsFromXboxLiveUserIdsCompletedStateChange*>(stateChange);
        for (uint32_t i = 0; i < getEntityIdsFromXboxLiveUserIdsResult.entityIdMappingCount; ++i)
        {
            const PartyXblXboxUserIdToPlayFabEntityIdMapping& idMapping = getEntityIdsFromXboxLiveUserIdsResult.entityIdMappings[i];

            Log("   Xbox Live User ID: %llu", idMapping.xboxLiveUserId);
            if (strlen(idMapping.playfabEntityId)) != 0)
            {
                Log("    PlayFab Entity ID: %s", idMapping.playfabEntityId);
                cachedXboxUserIdToPlayFabEntityIdMap.emplace_back(idMapping.xboxLiveUserId, idMapping.playfabEntityId);
            }
            else
            {
                // This Xbox Live User did not have a linked PlayFab Account.
                Log("    PlayFab Entity ID: NOT FOUND");
            }
        }

        m_cachedXboxUserIdToPlayFabEntityIdMap = std::move(cachedXboxUserIdToPlayFabEntityIdMap);
```

Con una asignación de este tipo, los títulos pueden reconocer cuándo un objeto de Party representa a un usuario de XBOX Live.

```cpp theme={null}
uint64_t
GetXboxUserIdFromPlayFabEntityId(
    PartyString entityId
    )
{
    for (const std::pair<uint64_t, std::string>& idMapping : m_cachedXboxUserIdToPlayFabEntityIdMap)
    {
        const std::string& entityIdForXboxUserId = idMapping.second;
        if (entityIdForXboxUserId == entityId)
        {
            return idMapping.first;
        }
    }

    // Failed to find a matching Xbox User ID. This Entity ID does not represent an Xbox Live user.
    return 0;
}
```

## Consideraciones especiales para Windows

En Windows, la biblioteca auxiliar de XBOX Live necesita ayuda del título para obtener tokens de XBOX Live. La biblioteca solicitará tokens generando `PartyXblTokenAndSignatureRequestedStateChange`. El título puede usar la [XBOX Authentication Library](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/live/get-started/live-xbl-overview) (XAL) para satisfacer estas solicitudes. Delegar este trabajo en el título garantiza que este mantenga el control total de cualquier gestión de la interfaz de usuario y de las solicitudes de consentimiento que normalmente se asocian a la autenticación de usuarios.

```cpp theme={null}
    if (stateChange->stateChangeType == PartyXblStateChangeType::TokenAndSignatureRequested)
    {
        auto tokenAndSignatureRequested = static_cast<PartyXblTokenAndSignatureRequestedStateChange*>(stateChange);

        // Convert the headers to the format XAL expect
        std::vector<XalHttpHeader> xalHeaders;
        for (uint32_t i = 0; i < stateChange.headerCount; ++i)
        {
            xalHeaders.push_back({stateChange.headers[i].name, stateChange.headers[i].value});
        }

        XalUserGetTokenAndSignatureArgs args = {};
        args.method = stateChange.method;
        args.url = stateChange.url;
        args.headerCount = static_cast<uint32_t>(xalHeaders.size());
        args.headers = xalHeaders.data();
        args.bodySize = stateChange.bodySize;
        args.body = static_cast<const uint8_t*>(stateChange.body);
        args.forceRefresh = stateChange.forceRefresh != 0;
        args.allUsers = stateChange.allUsers != 0;

        XAsyncBlock* asyncBlock = new XAsyncBlock;
        asyncBlock->queue = m_queue;
        HRESULT hr = XalUserGetTokenAndSignatureSilentlyAsync(m_userHandle, &args, asyncBlock);
    }
```

Para obtener más instrucciones sobre cómo recuperar el token y la firma mediante XAL, consulte la [documentación de la XBOX Authentication Library.](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/live/get-started/live-xbl-overview)

Una vez que tenga el token y la firma, se pueden proporcionar a la biblioteca auxiliar de XBOX Live llamando a `PartyXblManager::CompleteGetTokenAndSignatureRequest()` con el mismo `correlationId` que se proporcionó al título a través del cambio de estado.


## Related topics

- [Typedefs del asistente de XBOX Live de PlayFab Party](/es/services/playfab/multiplayer/networking/xblreference/xbltypedefs.md)
- [Requisitos de XBOX](/es/services/playfab/multiplayer/networking/xbox-requirements.md)
- [Notas de la versión del asistente de XBOX Live de PlayFab Party](/es/services/playfab/multiplayer/networking/party-xboxlive-relnotes.md)
- [Códigos de error del asistente XBOX Live de PlayFab Party](/es/services/playfab/multiplayer/networking/xblreference/partyxblerrors.md)
- [Integración de PlayFab para títulos de los servicios XBOX](/es/services/xbox-services/playfab-integration.md)
