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

# Uso de los datos de publicador del jugador para recompensar el juego en varios títulos

> Use los datos de publicador del jugador de PlayFab y CloudScript para hacer un seguimiento de los inicios de sesión entre títulos y conceder recompensas de moneda virtual a los jugadores que juegan a varios títulos.

Las recompensas suelen implicar a *otros* sistemas ajenos a los datos del jugador, por lo que este ejemplo demuestra la concesión de moneda virtual en aras de la simplicidad.

## Requisitos

* Una [cuenta de desarrollador de PlayFab](https://developer.playfab.com).
* Un jugador debe iniciar sesión en *ambos* títulos con las mismas credenciales. Un enfoque es usar **credenciales recuperables**, como se describe en nuestro tutorial [Conceptos básicos del inicio de sesión y procedimientos recomendados](/services/playfab/identity/player-identity/login/login-basics-best-practices). Para agregar un inicio de sesión **recuperable** a una cuenta anónima, consulte nuestro tutorial de [vinculación de cuentas](/services/playfab/identity/player-identity/login/quickstart).
* Este ejemplo requiere conocimientos prácticos de [CloudScript](/services/playfab/live-service-management/service-gateway/automation/cloudscript/writing-custom-cloudscript):
  * Nuestro ejemplo demuestra la seguridad básica de los datos para evitar que los jugadores hagan trampas. Igualmente se podría usar la API de servidor en un servidor de juego personalizado, si el título hace uso de ellas.
* Las recompensas desencadenadas a través de PlayFab requieren el uso de las características adecuadas de PlayFab. Las recompensas de PlayFab pueden ser en forma de [**moneda virtual**](/services/playfab/economy-monetization/economy-v2/tutorials/currencies), [**artículos de inventario**](/services/playfab/player-progression/player-data/player-inventory), [**datos personalizados del jugador**](/services/playfab/player-progression/player-data/quickstart), [**estadísticas**](/services/playfab/community/leaderboards/tournaments-leaderboards/using-player-statistics), etc. La distribución de recompensas fuera de los sistemas de PlayFab es un tema avanzado y no se trata en este tutorial.

También se recomienda que los desarrolladores usen un buen control de errores en todas las llamadas de API de servidor realizadas desde CloudScript.

## Cada juego notifica un inicio de sesión a los datos del publicador

Cada juego debe notificar que se produjo un inicio de sesión. Para simplificar, nuestro ejemplo solo proporciona *una* recompensa para cada título, por cada otro título del publicador jugado.

No dude en ampliar la idea con contadores, marcas de tiempo u otros mecanismos para proporcionar recompensas progresivas o secuenciales.

El siguiente CloudScript tendría que estar presente en *todos* los juegos de su estudio.

```javascript theme={null}
// CloudScript/Javascript

var PUBLISHER_USED_TITLES_KEY = "playedTitleIds";
handlers.TrackTitleUsage = function () {
    // Get the User Publisher Data for this player, and convert it into our expected format
    var getRequest = { Keys: [PUBLISHER_USED_TITLES_KEY], PlayFabId: currentPlayerId };
    var getResult = server.GetUserPublisherInternalData(getRequest);
    var playedTitlesList = JSON.parse(getResult.Data[PUBLISHER_USED_TITLES_KEY].Value); // format is arbitrary, but this example assumes Array<string>
    if (!playedTitlesList)
        playedTitlesList = [];
    // Check if we've played this title already
    var alreadyPlayed = false;
    for (var i = 0; i < playedTitlesList.length; i++)
        alreadyPlayed = alreadyPlayed || playedTitlesList[i] === script.titleId;
    if (alreadyPlayed)
        return; // Nothing to do
    // Update the list of played titles, and re-save
    playedTitlesList.push(script.titleId);
    var setRequest = { PlayFabId: currentPlayerId, Data: { PUBLISHER_USED_TITLES_KEY: JSON.stringify(playedTitlesList) } };
    server.UpdateUserPublisherInternalData(setRequest);
}
```

En concreto, este ejemplo demuestra el uso de:

* server.[GetUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.getuserpublisherinternaldata)
* server.[UpdateUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.updateuserpublisherinternaldata).

## Cada juego comprueba las recompensas canjeables

Una vez que esté haciendo el seguimiento de los títulos jugados, debe hacer el seguimiento de las recompensas y concederlas. Esta función de CloudScript comprobará y concederá las recompensas disponibles, en función de haber jugado a otros títulos.

```javascript theme={null}
// CloudScript/Javascript

var PUBLISHER_REDEEMED_TITLES_KEY = "redeemedTitleIds";
var MY_CROSS_TITLE_REWARDS = { "AU": 10 };
handlers.CheckCrossTitleRewards = function () {
    // Get the publisher data concerning cross-title rewards for this player
    var getRequest = { Keys: [PUBLISHER_USED_TITLES_KEY, PUBLISHER_REDEEMED_TITLES_KEY], PlayFabId: currentPlayerId };
    var getResult = server.GetUserPublisherInternalData(getRequest);
    var redeemedTitleRewards = JSON.parse(getResult.Data[PUBLISHER_REDEEMED_TITLES_KEY].Value); // format is arbitrary, but this example assumes { [key: string]: Array<string> }
    if (!redeemedTitleRewards)
        redeemedTitleRewards = {};
    var playedTitlesList = JSON.parse(getResult.Data[PUBLISHER_USED_TITLES_KEY].Value); // format is arbitrary, but this example assumes Array<string>
    if (!playedTitlesList)
        playedTitlesList = [];

    // Determine which titles are un-redeemed
    var unredeemedTitleIds = [];
    for (var i = 0; i < playedTitlesList.length; i++) {
        if (!redeemedTitleRewards.hasOwnProperty(playedTitlesList[i]) && playedTitlesList[i] !== script.titleId)
            unredeemedTitleIds.push(playedTitlesList[i]);
    }
    if (unredeemedTitleIds.length === 0)
        return null; // Nothing to redeem

    // Give the cross title rewards
    var multiplier = unredeemedTitleIds.length;
    var actualRewards = {}; // MY_CROSS_TITLE_REWARDS is a global constant, so don't modify it or you'll mess up future calls
    // Please note that the number of API calls that may be made from CloudScript, as well as the total available processing time is limited,
    // and so the number of rewards should be as small as possible (only one VC, in this case)
    for (var eachKey in MY_CROSS_TITLE_REWARDS) {
        actualRewards[eachKey] = MY_CROSS_TITLE_REWARDS[eachKey] * multiplier;
        server.AddUserVirtualCurrency({ PlayFabId: currentPlayerId, VirtualCurrency: eachKey, Amount: MY_CROSS_TITLE_REWARDS[eachKey] }); // Can only add 1 VC at a time
    }

    // Save the Publisher data indicating rewards are claimed
    redeemedTitleRewards[script.titleId] = playedTitlesList;
    var setRequest = { PlayFabId: currentPlayerId, Data: { PUBLISHER_REDEEMED_TITLES_KEY: JSON.stringify(redeemedTitleRewards) } };
    server.UpdateUserPublisherInternalData(setRequest);

    // Tell the client the reward
    return actualRewards;
};
```

<Note>
  Este ejemplo en particular demuestra el uso de server.[GetUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.getuserpublisherinternaldata) (solicitando varias claves), server.[UpdateUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.updateuserpublisherinternaldata) y server.[AddUserVirtualCurrency](xref:titleid.playfabapi.com.server.playeritemmanagement.adduservirtualcurrency).
</Note>

Los bloques de código representan estos pasos:

* Obtener los datos de PlayFab y analizarlos en estructuras de datos locales (llamando a [GetUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.getuserpublisherinternaldata)).
* Examinar los datos y buscar identificadores de títulos sin recompensa.
* Conceder las recompensas (llamando a [AddUserVirtualCurrency](xref:titleid.playfabapi.com.server.playeritemmanagement.adduservirtualcurrency)).
* Actualizar las recompensas reclamadas (llamando a [UpdateUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.updateuserpublisherinternaldata)).
* Poner la cantidad recompensada a disposición del cliente (mediante la instrucción return de CloudScript).

## Conclusión

Los datos de publicador del jugador y los datos del jugador son estructuralmente idénticos.

Los datos del jugador deben ser *específicos del título*, mientras que los datos de publicador del jugador *solo* deben contener información relevante para todos sus títulos.

## Consulte también

[Promoción cruzada sencilla en el juego](https://github.com/PlayFab/PlayFab-Samples/tree/master/Recipes/SimpleCrossPromotion): recompense a los jugadores que participan en más de uno de sus juegos.


## Related topics

- [Información general sobre los datos de jugador de XBOX](/es/services/xbox-services/player-data/live-playerdata-overview.md)
- [Datos de jugador](/es/services/playfab/player-progression/player-data/index.md)
- [Uso de los datos del publicador](/es/services/playfab/live-service-management/game-configuration/titledata/using-publisher-data.md)
- [Casos de prueba de los requisitos de XBOX para juegos de PC y móviles](/es/publishing/certification/pc-policy-tests.md)
- [XR-013 Vinculación de cuentas de Microsoft con cuentas del publicador](/es/publishing/certification/xr/xr-013.md)
