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

# Integración del complemento de PlayFab del Marketplace de Unreal Engine

> Instrucciones sobre cómo integrar el complemento del SDK de PlayFab del Marketplace de UE en su proyecto existente con PlayFab Online Subsystem integrado.

# Guía de inicio rápido: Integración de PlayFab Online Subsystem con el complemento de PlayFab del Marketplace de Unreal Engine

Esta guía de inicio rápido le ayuda a integrar el [complemento del SDK de PlayFab del Marketplace de Unreal Engine (UE)](/services/playfab/sdks/unreal) en su proyecto existente con PlayFab Online Subsystem (OSS) integrado.

El complemento del SDK de PlayFab se usa para realizar operaciones de administración, cliente y servidor de PlayFab, como la autenticación de jugadores, la administración de artículos virtuales y monedas, y la creación de características sociales. Usado junto con PlayFab Online Subsystem, su proyecto puede acceder al conjunto completo de características de PlayFab para proyectos de Unreal Engine.

Cuando se usa el PlayFab OSS o el complemento del SDK de PlayFab de forma independiente, el primer paso es autenticar a un usuario. Usar ambos en el mismo proyecto sin la configuración adecuada significa que el PlayFab OSS y el complemento del SDK de PlayFab realizarán cada uno una llamada de autenticación independiente para el mismo usuario.

Esta guía de inicio rápido le ayuda a autenticarse a través del PlayFab OSS y a reutilizar esa autenticación con el complemento del SDK de PlayFab, para lograr una experiencia de autenticación de usuario fluida.

## Requisitos previos

* Asegúrese de integrar el PlayFab OSS como complemento en el archivo `<game>.build.cs`. En el ejemplo siguiente, creamos una opción de alternancia para permitir la integración y establecemos una definición para permitir la protección con `#ifdef`.
  ```cs theme={null}
  // PlayFab OnlineSubsystem Plugin Settings.
  //
  // While the PlayFab OSS is integrated with the game at an engine level, we cannot directly access
  // PF OSS headers unless we integrate it as a plugin.
  //
  // `bOSSPlayFabAsPlugin` must be set to true to expose the PlayFab OSS headers directly to the game.
  bool bOSSPlayFabAsPlugin = false;
  if (bOSSPlayFabAsPlugin)
  {
      PublicDependencyModuleNames.AddRange(new string[] { "OnlineSubsystemPlayFab" });
      PublicDefinitions.Add("WITH_OSS_PLAYFAB=1");
  }
  ```

* Asegúrese de integrar el complemento del SDK de PlayFab en el archivo `<game>.build.cs`. En el ejemplo siguiente, creamos una opción de alternancia para permitir la integración y establecemos una definición para permitir la protección con `#ifdef`.
  ```cs theme={null}
  // PlayFab SDK Plugin Settings.
  //
  // `bPlayFabPlugin` must be set to true to enable compilation and integration with the PlayFab
  // SDK Plugin.
  // Ensure that the PF SDK Plugin is installed via Engine plugin or as a local game plugin.
  bool bPlayFabPlugin = false;
  if (bPlayFabPlugin)
  {
      PrivateDependencyModuleNames.AddRange(new string[] { "PlayFab", "PlayFabCpp", "PlayFabCommon" });
      PublicDefinitions.Add("WITH_PLAYFAB_PLUGIN=1");
  }
  ```

* Después de actualizar el archivo `<game.build.cs>` (y cada vez que lo actualice posteriormente), asegúrese de regenerar los archivos de proyecto de Visual Studio de su juego haciendo clic con el botón derecho en el archivo `.uproject` y seleccionando `Generate Visual Studio Project Files`.

* PlayFab OSS ahora ofrece un delegado público `AuthenticateUserComplete` que se desencadena al completarse el flujo de autenticación de usuario de PlayFab OSS. Enlácese a este delegado para recuperar los detalles de su autenticación de PlayFab OSS.
  ```cpp theme={null}
  /**
  * Delegate used on the completion of FOnlineIdentityPlayFab::AuthenticateUser().
  *
  * @param LocalUserNum the controller number of the associated user that made the request
  * @param bWasSuccessful true if authentication was successful, false if there was an error
  * @param PlatformUserIdStr user identifier returned from the service.
  * @param ErrorStr string representing the error condition
  */
  DECLARE_MULTICAST_DELEGATE_FourParams(FOnAuthenticateUserComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FString& /*PlatformUserIdStr*/, const FString& /*ErrorStr*/);
  typedef FOnAuthenticateUserComplete::FDelegate FOnAuthenticateUserCompleteDelegate;
  ```

## Pasos

También puede ir directamente al [ejemplo de código completo](#full-code-example).

1. **Incluya los encabezados correctos**
   ```cpp theme={null}
   #ifdef WITH_OSS_PLAYFAB
   #include "OnlineSubsystemPlayFab.h"
   #endif // WITH_OSS_PLAYFAB

   #ifdef WITH_PLAYFAB_PLUGIN
   #include "PlayFab.h"
   #include "PlayFabCommon.h"
   #include "Core/PlayFabClientDataModels.h"
   #endif // WITH_PLAYFAB_PLUGIN
   ```

2. **Recupere el PlayFab OSS**
   ```cpp theme={null}
   FOnlineSubsystemPlayFab* PFOnlineSub = static_cast<FOnlineSubsystemPlayFab*>(IOnlineSubsystem::Get(TEXT("PLAYFAB")));
   ```

3. **Enlácese al delegado `AuthenticateUserComplete`**

   ```cpp theme={null}
   const FOnlineIdentityPlayFabPtr PlayFabIdentityInterface = PFOnlineSub->GetIdentityInterfacePlayFab();
   PlayFabIdentityInterface->AddOnAuthenticateUserCompleteDelegate_Handle
   (
       0, // LocalUserNum
       FOnAuthenticateUserCompleteDelegate::CreateUObject(this, &UGameInstance::OnAuthenticateUserComplete)
   );
   ```

   Las funciones que se enlazan a este delegado deben tener la misma firma que el delegado. Por ejemplo:

   ```cpp theme={null}
   void UGameInstance::OnAuthenticateUserComplete(int32 localUserNum, bool bWasSuccessful, const FString& platformUserIdStr, const FString& error)
   ```

   También puede enlazar una expresión lambda al delegado. Por ejemplo:

   ```cpp theme={null}
   // We don't pass the `FOnlineIdentityPlayFabPtr` pointer through the lambda capture since the original
   // local isn't guaranteed to live longer than the lambda and we want to avoid dangling references.
   //
   // You can retrieve `FOnlineIdentityPlayFabPtr` again inside the lambda.
   PlayFabIdentityInterface->AddOnAuthenticateUserCompleteDelegate_Handle
   (
       0, // LocalUserNum
       FOnAuthenticateUserCompleteDelegate::CreateLambda([this](int32 localUserNum, bool bWasSuccessful, const FString& platformUserIdStr, const FString& error)
       {
           // lambda execution
       });
   )
   ```

4. **Controle el resultado de la autenticación**: en la función enlazada al delegado, controle el resultado de la autenticación. Si la autenticación se realiza correctamente, recupere el usuario local autenticado mediante el `platformUserIdStr` del desencadenador del delegado. Después, construya un `LoginResult` de PlayFab a partir del `LocalUser` del PlayFab OSS.
   ```cpp theme={null}
   void UGameInstance::OnAuthenticateUserComplete(int32 localUserNum, bool bWasSuccessful, const FString& platformUserIdStr, const FString& error)
   {
       if (!bWasSuccessful)
       {
           UE_LOG(LogOnlineGame, Error, TEXT("OSS PlayFab AuthenticateLocalUser Failed. Error: %s"), *error);
           return;
       }

       UE_LOG(LogOnlineGame, Display, TEXT("[%s] AuthenticateLocalUser Complete"), ANSI_TO_TCHAR(__FUNCTION__));

       FOnlineSubsystemPlayFab* PFOnlineSub = static_cast<FOnlineSubsystemPlayFab*>(IOnlineSubsystem::Get(TEXT("PLAYFAB")));
       const FOnlineIdentityPlayFabPtr PlayFabIdentityInterface = PFOnlineSub->GetIdentityInterfacePlayFab();

       if (PlayFabIdentityInterface)
       {
           if (const auto LocalUser = PlayFabIdentityInterface->GetPartyLocalUserFromPlatformIdString(platformUserIdStr))
           {
               // Setting PlayFab SDK Settings for future API calls
               auto& PFCommonModule = IPlayFabCommonModuleInterface::Get();
               PFCommonModule.SetClientSessionTicket(LocalUser->GetSessionTicket());
               PFCommonModule.SetEntityToken(LocalUser->GetEntityToken());

               // Create EntityKey
               auto LocalEntityKey = MakeShared<PlayFab::ClientModels::FEntityKey>();
               LocalEntityKey->Id = LocalUser->GetEntityId();
               LocalEntityKey->Type = LocalUser->GetEntityType();

               // Create EntityToken
               auto LocalEntityToken = MakeShared<PlayFab::ClientModels::FEntityTokenResponse>();
               LocalEntityToken->Entity = LocalEntityKey;
               LocalEntityToken->EntityToken = LocalUser->GetEntityToken();

               // Create LoginResult
               PlayFab::ClientModels::FLoginResult LoginResult;
               LoginResult.EntityToken = LocalEntityToken;
               LoginResult.LastLoginTime = LocalUser->GetEntityTokenUpdateTime();
               LoginResult.PlayFabId = LocalUser->GetPlayFabId();
               LoginResult.SessionTicket = LocalUser->GetSessionTicket();

               // With `LoginResult` populated, we can now use the PlayFab SDK Plugin APIs
               // however we wish. This state is considered "authenticated".
               //
               // This delegate signature functions does not return anything. You can pass `LoginResult`
               // out of this function however you wish.
               // 
               // Example psuedocode for a non-existent function that takes `LoginResult` as a parameter:
               // void UGameInstance::OnAPILoginSuccess(PlayFab::ClientModels::FLoginResult LoginResult);
           }
       }
   }
   ```

5. **Use las API del complemento del SDK de PlayFab**: con `LoginResult` rellenado, ahora puede usar las API del complemento del SDK de PlayFab como desee. Este estado se considera "authenticated".

## Ejemplo de código completo

```cpp theme={null}
#ifdef WITH_OSS_PLAYFAB
#include "OnlineSubsystemPlayFab.h"
#endif // WITH_OSS_PLAYFAB

#ifdef WITH_PLAYFAB_PLUGIN
#include "PlayFab.h"
#include "PlayFabCommon.h"
#include "Core/PlayFabClientDataModels.h"
#endif // WITH_PLAYFAB_PLUGIN

...

void UGameInstance::Init()
{
    Super::Init();
    ...

    // This is an example scenario of integrating the PlayFab OnlineSubsystem with the
    // PlayFab SDK Plugin.
    //
    // In this scenario, you can authenticate via the PlayFab OSS,
    // and then re-use that authentication with the PlayFab SDK Plugin.
    // 
    // PF OSS offers a public `AuthenticateUserComplete` delegate that can be bound;
    // this delegate triggers on completion of the PF OSS user authentication flow.
    // 
    // Below is an example of a game binding to that delegate, retrieving the
    // authenticated local user via the `platformUserIdStr` from the delegate
    // trigger, and then constructing a PlayFab `LoginResult` from the PF OSS
    // `LocalUser.`
    // 
    // These definitions are defined in `<game>.build.cs`.
#if defined(WITH_OSS_PLAYFAB) && defined(WITH_PLAYFAB_PLUGIN)
    // Explicitly retrieve the PlayFab OSS - we can't assume it's the default OSS.
    FOnlineSubsystemPlayFab* PFOnlineSub = static_cast<FOnlineSubsystemPlayFab*>(IOnlineSubsystem::Get(TEXT("PLAYFAB")));

    UE_LOG(LogOnlineGame, Warning, TEXT("Retrieved PFOnlineSub"));

    if (PFOnlineSub)
    {
        const FOnlineIdentityPlayFabPtr PlayFabIdentityInterface = PFOnlineSub->GetIdentityInterfacePlayFab();

        PlayFabIdentityInterface->AddOnAuthenticateUserCompleteDelegate_Handle
        (
            0, // LocalUserNum
            FOnAuthenticateUserCompleteDelegate::CreateUObject(this, &UGameInstance::OnAuthenticateUserComplete)
        );
    }
    else
    {
        UE_LOG(LogOnlineGame, Error, TEXT("UGameInstance::Init: Unable to find OnlineSubsystemPlayFab"));
    }
#endif // WITH_OSS_PLAYFAB && WITH_PLAYFAB_PLUGIN

    ...
}

void UGameInstance::OnAuthenticateUserComplete(int32 localUserNum, bool bWasSuccessful, const FString& platformUserIdStr, const FString& error)
{
    if (!bWasSuccessful)
    {
        UE_LOG(LogOnlineGame, Error, TEXT("OSS PlayFab AuthenticateLocalUser Failed. Error: %s"), *error);
        return;
    }

    UE_LOG(LogOnlineGame, Display, TEXT("[%s] AuthenticateLocalUser Complete"), ANSI_TO_TCHAR(__FUNCTION__));

    FOnlineSubsystemPlayFab* PFOnlineSub = static_cast<FOnlineSubsystemPlayFab*>(IOnlineSubsystem::Get(TEXT("PLAYFAB")));
    const FOnlineIdentityPlayFabPtr PlayFabIdentityInterface = PFOnlineSub->GetIdentityInterfacePlayFab();

    if (PlayFabIdentityInterface)
    {
        if (const auto LocalUser = PlayFabIdentityInterface->GetPartyLocalUserFromPlatformIdString(platformUserIdStr))
        {
            // Setting PlayFab SDK Settings for future API calls
            auto& PFCommonModule = IPlayFabCommonModuleInterface::Get();
            PFCommonModule.SetClientSessionTicket(LocalUser->GetSessionTicket());
            PFCommonModule.SetEntityToken(LocalUser->GetEntityToken());

            // Create EntityKey
            auto LocalEntityKey = MakeShared<PlayFab::ClientModels::FEntityKey>();
            LocalEntityKey->Id = LocalUser->GetEntityId();
            LocalEntityKey->Type = LocalUser->GetEntityType();

            // Create EntityToken
            auto LocalEntityToken = MakeShared<PlayFab::ClientModels::FEntityTokenResponse>();
            LocalEntityToken->Entity = LocalEntityKey;
            LocalEntityToken->EntityToken = LocalUser->GetEntityToken();

            // Create LoginResult
            PlayFab::ClientModels::FLoginResult LoginResult;
            LoginResult.EntityToken = LocalEntityToken;
            LoginResult.LastLoginTime = LocalUser->GetEntityTokenUpdateTime();
            LoginResult.PlayFabId = LocalUser->GetPlayFabId();
            LoginResult.SessionTicket = LocalUser->GetSessionTicket();

            // With `LoginResult` populated, we can now use the PlayFab SDK Plugin APIs
            // however we wish. This state is considered "authenticated".
            //
            // This delegate signature functions does not return anything. You can pass `LoginResult`
            // out of this function however you wish.
            // 
            // Example psuedocode for a non-existent function that takes `LoginResult` as a parameter:
            // void UGameInstance::OnAPILoginSuccess(PlayFab::ClientModels::FLoginResult LoginResult);
        }
    }
}
```


## Related topics

- [Notas de la versión de PlayFab OnlineSubsystem para Unreal Engine](/es/services/playfab/multiplayer/networking/unreal-release-notes.md)
- [Uso del GDK con Unreal Engine](/es/build/gdk-and-engines/unreal/unreal.md)
- [Inicio rápido de Unreal Engine](/es/services/playfab/sdks/unreal/quickstart.md)
- [Información general del complemento GSDK de Unreal de PlayFab](/es/services/playfab/multiplayer/servers/server-sdks/unreal-gsdk/index.md)
- [Información general de PlayFab para Unreal Engine](/es/services/playfab/sdks/unified-unreal/overview.md)
