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

# Code source et pratiques exemplaires - Winter Starfall

> Téléchargez le code source du jeu de démonstration PlayFab Winter Starfall et parcourez des exemples de code illustrant les pratiques exemplaires pour les scénarios de connexion des joueurs et d'achat en jeu.

# Code source et scénarios dans Winter Starfall

Ce tutoriel contient des instructions pour télécharger et exécuter le code source de Winter Starfall, ainsi qu'une présentation des exemples de code qui illustrent les pratiques exemplaires pour les scénarios de connexion et d'achat.

## Téléchargement du code source

### Prérequis

* Installer Node JS
* Installer Visual Studio Code

### Configuration pour le développement local

1. Téléchargez le code source à partir de [GitHub](https://github.com/PlayFab/winter-starfall).
2. Dans VS Code, ouvrez le dossier `/website` et choisissez d'installer toutes les extensions recommandées.
3. Dans le répertoire `/website`, exécutez npm install pour installer toutes les dépendances.
4. Utilisez `npm run dev` pour démarrer le site. Sélectionnez le lien proposé pour afficher le site.

### Informations d'identification Azure

Pour mettre à jour les secrets AZURE\_CREDENTIALS, exécutez cette commande dans l'interpréteur de commandes du portail Azure :

`az ad sp create-for-rbac --name "VanguardOutrider2" --role contributor --scopes /subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/YOUR_RESOURCE_GROUP_NAME --json-auth`

## Flux de connexion

Le flux d'authentification des joueurs dans Winter Starfall comporte deux étapes : l'appel de connexion et les fonctions postconnexion qui servent à obtenir les informations du joueur à partir du service et à le charger au bon endroit dans l'histoire.

### Authentification des joueurs

Pour la partie connexion, le fichier [use-login.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-login.ts) définit une fonction wrapper TypeScript qui gère les multiples méthodes d'authentification offertes aux joueurs.

Les lignes 144 à 169 définissent la fonction de rappel pour la connexion avec une adresse courriel et appellent les fonctions postconnexion si la connexion réussit.

```typescript theme={null}
const onLogin = useCallback(() => {
    setIsLoading(true);
    setLoginMethodInProgress("email");

    dispatch(siteSlice.actions.loginSteps(loginEventCount));

    ClientLoginWithEmailAddress({ Email: data.email, Password: data.password })
        .then(result => {
            dispatch(siteSlice.actions.login(result));
            dispatch(siteSlice.actions.loginStepsAdvance());
            // Track logins from returning users
            trackEvent({ name: "Returning User", properties: {} });
        })
        .then(() => {
            return postLoginFunctions();
        })
        .then(() => {
            setIsLoading(false);
            navigate(routes.Explore());
        })
        .catch(problem => {
            dispatch(siteSlice.actions.loginStepsReset());
            onError(problem);
        })
        .finally(() => dispatch(siteSlice.actions.loginStepsReset()));
}, [ClientLoginWithEmailAddress, data.email, data.password, dispatch, navigate, onError, postLoginFunctions]);
```

Le jeu offre 3 méthodes récupérables d'authentification des joueurs : courriel, Google et Facebook, afin que les comptes des joueurs ne soient jamais perdus. Pour plus d'informations, consultez [Pratiques exemplaires de connexion](/fr-CA/services/playfab/identity/player-identity/login/login-basics-best-practices).

### Postconnexion : obtention des données du joueur

Une fois le jeton de sécurité récupéré, il sert à exécuter les fonctions postconnexion pour obtenir l'état de jeu enregistré.

Les lignes 340 à 378 définissent **postLoginFunctions**, qui appelle diverses API Economy et PlayFab Services pour charger le bon emplacement dans l'histoire, les objets d'inventaire, la monnaie, etc. en fonction du joueur.

```typescript theme={null}
return new Promise<void>((resolve, reject) => {
    ClientGetTitleData({ Keys: TITLE_DATA_KEYS_ALL })
        .then(result => {
            dispatch(siteSlice.actions.titleData(result));
            dispatch(siteSlice.actions.loginStepsAdvance());
            loadScripts();
        })
        .then(() =>
            EconomySearchItems({
                Count: SEARCH_ITEMS_MAX_COUNT,
                Filter: "type eq 'currency' or type eq 'catalogItem'",
            })
        )
        .then(result => {
            dispatch(siteSlice.actions.catalog(result.Items));
            dispatch(siteSlice.actions.loginStepsAdvance());
        })
        .then(() => EconomyGetInventoryItems({ Count: SEARCH_ITEMS_MAX_COUNT }))
        .then(result => {
            dispatch(siteSlice.actions.inventory(result.Items));
            dispatch(siteSlice.actions.loginStepsAdvance());
        })
        .then(() => ClientGetUserData({ Keys: USER_DATA_KEYS_PLAYER_ALL }))
        .then(result => {
            dispatch(siteSlice.actions.userDataPlayer(result));
            dispatch(siteSlice.actions.loginStepsAdvance());
        })
        .then(() => ClientGetUserReadOnlyData({ Keys: USER_DATA_KEYS_READONLY_ALL }))
        .then(result => {
            dispatch(siteSlice.actions.userDataReadOnly(result));
            dispatch(siteSlice.actions.loginStepsAdvance());
        })
        .then(() => {
            resolve();
        })
        .catch(problem => {
            dispatch(siteSlice.actions.loginStepsReset());
            reject(problem);
        });
});
```

* D'abord, `ClientGetTitleData` obtient la clé secrète nécessaire à tous les appels d'API
* Ensuite, `EconomySearchItems` recherche les types de monnaie et d'objets dans le catalogue
* Ce résultat sert d'entrée à `EconomyGetInventoryItems` pour retourner les objets d'inventaire du joueur
* Puis, `ClientGetUserData` récupère la valeur qui stocke l'emplacement dans l'histoire dans les données du joueur.

## Flux d'achat

À certains moments du jeu, le joueur a la possibilité d'acheter et de vendre des objets d'inventaire dans la boutique. Le flux d'achat est mis en œuvre dans une autre fonction wrapper. Dans le fichier [use-store.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-store.ts), les lignes 40 à 69 affichent la bonne boutique que le joueur rencontre à un emplacement précis et remplissent les objets à vendre en effectuant une recherche dans le catalogue.

```typescript theme={null}
export function useEconomyStoreSingle(storeName: string): IEconomyStoreSingleResults {
    const dispatch = useDispatch();
    const store = useSelector((state: AppState) => state.site.stores).find(store =>
        store.AlternateIds?.find(friendlyId => friendlyId.Type === FRIENDLYID && friendlyId.Value === storeName)
    );
    const { isLoading, error, setError, EconomyGetItem } = usePlayFab();

    useEffect(() => {
        if (!is.null(store) || isStoreLoading) {
            return;
        }

        isStoreLoading = true;

        EconomyGetItem({
            AlternateId: { Type: FRIENDLYID, Value: storeName },
        })
            .then(results => {
                dispatch(siteSlice.actions.storeAdd(results.Item as PlayFabEconomyModels.CatalogItem));
            })
            .catch(setError)
            .finally(() => {
                isStoreLoading = false;
            });
    }, [EconomyGetItem, dispatch, setError, store, storeName]);

    return {
        error,
        isLoading,
        store,
    };
}
```

`EconomyGetItem` est défini dans [use-playfab.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-playfab.ts) aux lignes 423 à 446, où l'API PlayFab Economy `GetItems` est utilisée pour effectuer une recherche dans le catalogue et retourner des objets.

```typescript theme={null}
const EconomyGetItems = useCallback(
        (request: PlayFabEconomyModels.GetItemsRequest): Promise<PlayFabEconomyModels.GetItemsResponse> => {
            const date = startRequest("EconomyApi", "GetItems", request);

            return new Promise((resolve, reject) => {
                PlayFab.EconomyApi.GetItems(request, (result, problem) => {
                    endRequest(date, problem, result);

                    if (!is.null(problem)) {
                        return reject(problem);
                    }

                    if (result.code !== 200) {
                        return reject(formatPlayFabNon200Error(result));
                    }

                    return resolve(result.data);
                }).catch(reason => {
                    catchRequest(reject, reason);
                });
            });
        },
        [catchRequest, endRequest, startRequest]
    );
```

Lorsqu'un achat est effectué, un appel à l'API `PurchaseInventoryItems` est fait. Celui-ci est défini dans [use-playfab.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-playfab.ts) aux lignes 540 à 565.

### Vente d'objets

Le flux de vente est un exemple d'utilisation de CloudScript basé sur Azure Functions pour étendre les fonctionnalités du système Economy.

[SellItem.cs](https://github.com/PlayFab/winter-starfall/blob/main/azure-functions/SellItem.cs) définit la fonction CloudScript qui s'exécute lors de la vente d'un objet.

Les lignes 49 à 61 sont celles où l'API `GetTitleData` de PlayFab est utilisée pour retourner le multiplicateur de la boutique et calculer le prix de vente.

```csharp theme={null}
 // Get your sell multiplier
var titleData = await PlayFabFunctions.GetTitleDataAsync(player, new List<string> { TitleDataKeys.Multipliers }, log);
var sellMultiplier = JsonConvert.DeserializeObject<Multipliers>(titleData[TitleDataKeys.Multipliers])?.sell ?? 1;
```

La fonction CloudScript est ensuite appelée aux lignes 161 à 187 de [use-store.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-store.ts).

```typescript theme={null}
export function useEconomyStoreSell(): IEconomyStoreSellItemResults {
    const { isLoading, error, setError, CloudScriptExecuteFunction, EconomyGetInventoryItems } = usePlayFab();
    const dispatch = useDispatch();

    const onSell = useCallback(
        (itemId: string, amount: number) => {
            return new Promise<void>((resolve, reject) => {
                CloudScriptExecuteFunction({
                    FunctionName: "SellItem",
                    FunctionParameter: {
                        ItemId: itemId,
                        Amount: amount,
                    },
                })
                    .then(() => EconomyGetInventoryItems({ Count: SEARCH_ITEMS_MAX_COUNT }))
                    .then(data => {
                        dispatch(siteSlice.actions.inventory(data.Items));
                        resolve();
                    })
                    .catch(issue => {
                        setError(issue);
                        reject(issue);
                    });
            });
        },
        [CloudScriptExecuteFunction, EconomyGetInventoryItems, dispatch, setError]
    );
```

<Note>
  Pour exécuter Winter Starfall localement, vous aurez besoin d'un compte Azure pour prendre en charge les fonctions CloudScript. Vous pouvez [vous inscrire pour obtenir un compte Azure gratuit](https://azure.microsoft.com/pricing/purchase-options/azure-account?msockid=1dec68fa155462cb2baa7ca6147963d7) puis suivre les instructions ci-dessus pour réinitialiser correctement les informations d'identification Azure.
</Note>

## Voir aussi

* Flux de connexion
  * [Documentation sur la connexion des joueurs](/fr-CA/services/playfab/identity/player-identity/login)
* Flux d'achat
  * [Documentation d'Economy V2](/fr-CA/services/playfab/economy-monetization/economy-v2/overview)
  * Une autre bonne étape pour en savoir plus sur Economy V2 consiste à essayer le [tutoriel du jeu d'artisanat](/fr-CA/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/game-context), qui porte sur la création d'un exemple de jeu à l'aide des fonctions de boutique et d'inventaire.


## Related topics

- [Vue d'ensemble du jeu de démonstration PlayFab Winter Starfall](/fr-CA/services/playfab/demo-game/overview.md)
- [Vanguard Outrider (hérité)](/fr-CA/services/playfab/demo-game/legacy-vanguard-outrider.md)
- [Pratiques exemplaires](/fr-CA/services/xbox-services/develop/best-practices/index.md)
- [Pratiques exemplaires et liste de vérification du lancement](/fr-CA/services/playfab/multiplayer/servers/best-practices.md)
- [Pratiques exemplaires d'Insights](/fr-CA/services/playfab/data-analytics/legacy/insights/best-practices.md)
