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

# Usar os dados de publicador do jogador para recompensar o jogo em vários títulos

> Use os dados de publicador do jogador e o CloudScript do PlayFab para acompanhar os logins entre títulos e conceder recompensas de moeda virtual aos jogadores que jogam vários títulos.

As recompensas geralmente envolvem *outros* sistemas além dos dados do jogador; por isso, este exemplo demonstra a concessão de moeda virtual por simplicidade.

## Requisitos

* Uma [conta de desenvolvedor do PlayFab](https://developer.playfab.com).
* O jogador deve entrar em *ambos* os títulos usando as mesmas credenciais. Uma abordagem é usar **Recoverable Credentials**, conforme descrito no nosso tutorial [Noções básicas e práticas recomendadas de login](/pt-BR/services/playfab/identity/player-identity/login/login-basics-best-practices). Para adicionar um login **Recoverable** a uma conta anônima, consulte nosso tutorial [Vinculação de contas](/pt-BR/services/playfab/identity/player-identity/login/quickstart).
* Este exemplo exige um conhecimento prático do [CloudScript](/pt-BR/services/playfab/live-service-management/service-gateway/automation/cloudscript/writing-custom-cloudscript):
  * Nosso exemplo demonstra uma segurança de dados básica para evitar trapaças dos jogadores. Também seria possível usar a API de servidor em um servidor de jogo personalizado, se o título os utilizar.
* As recompensas disparadas pelo PlayFab exigem o uso dos recursos apropriados do PlayFab. As recompensas do PlayFab podem estar na forma de [**moeda virtual**](/pt-BR/services/playfab/economy-monetization/economy-v2/tutorials/currencies), [**itens de inventário**](/pt-BR/services/playfab/player-progression/player-data/player-inventory), [**dados personalizados do jogador**](/pt-BR/services/playfab/player-progression/player-data/quickstart), [**estatísticas**](/pt-BR/services/playfab/community/leaderboards/tournaments-leaderboards/using-player-statistics) etc. Distribuir recompensas fora dos sistemas do PlayFab é um tópico avançado e não é abordado neste tutorial.

Também recomendamos que os desenvolvedores usem um bom tratamento de erros em todas as chamadas de API de servidor feitas a partir do CloudScript.

## Cada jogo relata um login nos dados de publicador

Cada jogo precisa relatar que um login ocorreu. Para simplificar, nosso exemplo fornece apenas *uma* recompensa para cada título, para cada outro título do publicador jogado.

Fique à vontade para expandir a ideia com contadores, carimbos de data/hora ou outros mecanismos para fornecer recompensas progressivas ou sequenciais.

O CloudScript a seguir precisaria estar presente em *todos* os jogos do seu estúdio.

```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);
}
```

Em particular, este exemplo demonstra o uso de:

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

## Cada jogo verifica se há recompensas resgatáveis

Depois de acompanhar quais títulos são jogados, você precisa acompanhar e conceder as recompensas. Esta função do CloudScript verificará e concederá as recompensas disponíveis, com base em ter jogado outros 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 exemplo específico demonstra o uso de server.[GetUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.getuserpublisherinternaldata) (solicitando várias chaves), server.[UpdateUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.updateuserpublisherinternaldata) e server.[AddUserVirtualCurrency](xref:titleid.playfabapi.com.server.playeritemmanagement.adduservirtualcurrency).
</Note>

Os blocos de código representam estas etapas:

* Buscar os dados do PlayFab e analisá-los em estruturas de dados locais (chamando [GetUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.getuserpublisherinternaldata)).
* Examinar os dados e procurar IDs de título não recompensadas.
* Conceder as recompensas (chamando [AddUserVirtualCurrency](xref:titleid.playfabapi.com.server.playeritemmanagement.adduservirtualcurrency)).
* Atualizar as recompensas resgatadas (chamando [UpdateUserPublisherInternalData](xref:titleid.playfabapi.com.server.playerdatamanagement.updateuserpublisherinternaldata)).
* Disponibilizar o valor recompensado para o cliente (por meio da instrução return do CloudScript).

## Conclusão

Os dados de publicador do jogador e os dados do jogador são estruturalmente idênticos.

Os dados do jogador devem ser *específicos do título*, enquanto os dados de publicador do jogador devem conter *somente* informações relevantes para todos os seus títulos.

## Confira também

[Promoção cruzada simples no jogo](https://github.com/PlayFab/PlayFab-Samples/tree/master/Recipes/SimpleCrossPromotion): recompense os jogadores que participam de mais de um dos seus jogos.


## Related topics

- [Visão geral dos Dados do jogador do XBOX](/pt-BR/services/xbox-services/player-data/live-playerdata-overview.md)
- [Dados do jogador](/pt-BR/services/playfab/player-progression/player-data/index.md)
- [Usar dados do publicador](/pt-BR/services/playfab/live-service-management/game-configuration/titledata/using-publisher-data.md)
- [Usar objetos de entidade para armazenar dados do jogador](/pt-BR/services/playfab/live-service-management/game-configuration/entities/entity-objects.md)
- [Configurar recompensas de conquistas do XBOX](/pt-BR/services/xbox-services/player-data/achievements/title-managed/concepts/live-achievement-rewards.md)
