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

# Código fuente y procedimientos recomendados - Winter Starfall

> Descargue el código fuente del juego de demostración de PlayFab Winter Starfall y recorra ejemplos de código con procedimientos recomendados para los escenarios de inicio de sesión de jugadores y compras en el juego.

# Código fuente y escenarios en Winter Starfall

Este tutorial contiene instrucciones para descargar y ejecutar el código fuente de Winter Starfall, y un recorrido por los ejemplos de código que muestran procedimientos recomendados para los escenarios de inicio de sesión y compra.

## Descarga del código fuente

### Requisitos previos

* Instalar Node JS
* Instalar Visual Studio Code

### Configuración para el desarrollo local

1. Descargue el código fuente desde [GitHub](https://github.com/PlayFab/winter-starfall).
2. En VS Code, abra la carpeta `/website` y acepte instalar todas las extensiones que recomienda.
3. En el directorio `/website`, ejecute npm install para instalar todas las dependencias.
4. Use `npm run dev` para iniciar el sitio. Seleccione el vínculo que ofrece para ver el sitio.

### Credenciales de Azure

Para actualizar los secretos AZURE\_CREDENTIALS, ejecute este comando en el shell de Azure Portal:

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

## Flujo de inicio de sesión

El flujo de autenticación de jugadores en Winter Starfall tiene dos pasos: la llamada de inicio de sesión y las funciones posteriores al inicio de sesión que se usan para obtener la información del jugador desde el servicio y cargarlo en la ubicación correcta de la historia.

### Autenticación de jugadores

Para la parte de inicio de sesión, el archivo [use-login.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-login.ts) define una función contenedora de TypeScript que gestiona los múltiples métodos de autenticación disponibles para los jugadores.

Las líneas 144-169 definen la función de devolución de llamada para iniciar sesión con una dirección de correo electrónico, y llaman a las funciones posteriores al inicio de sesión si este se realiza correctamente.

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

El juego ofrece 3 métodos recuperables para la autenticación de jugadores: correo electrónico, Google y Facebook, de modo que las cuentas de los jugadores nunca se pierdan. Para obtener más información, consulte [Procedimientos recomendados de inicio de sesión](/services/playfab/identity/player-identity/login/login-basics-best-practices).

### Después del inicio de sesión: Obtención de los datos del jugador

Una vez recuperado el token de seguridad, se usa para ejecutar las funciones posteriores al inicio de sesión y obtener el estado guardado del juego.

Las líneas 340-378 definen **postLoginFunctions**, que llama a varias API de Economy y de PlayFab Services para cargar la ubicación correcta de la historia, los artículos del inventario, la moneda, etc., en función del jugador.

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

* Primero, `ClientGetTitleData` obtiene la clave secreta necesaria para todas las llamadas a la API
* Después, `EconomySearchItems` busca en el catálogo los tipos de moneda y de artículo
* Lo que se usa como entrada para `EconomyGetInventoryItems` para devolver los artículos del inventario del jugador
* A continuación, `ClientGetUserData` recupera el valor que almacena la ubicación de la historia como parte de los datos del jugador.

## Flujo de compra

En ciertos puntos del juego, el jugador tiene la opción de comprar y vender artículos del inventario en la tienda. El flujo de compra se implementa en otra función contenedora. En el archivo [use-store.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-store.ts), las líneas 40-69 muestran la tienda correcta que el jugador encuentra en una ubicación específica y rellenan los artículos a la venta buscando en el catálogo.

```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` se define en [use-playfab.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-playfab.ts) en las líneas 423-446, dentro de las cuales se usa la API `GetItems` de PlayFab Economy para buscar en el catálogo y devolver artículos.

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

Cuando se realiza una compra, se hace una llamada a la API `PurchaseInventoryItems`. Esta se define en [use-playfab.ts](https://github.com/PlayFab/winter-starfall/blob/main/website/src/hooks/use-playfab.ts) en las líneas 540-565.

### Venta de artículos

El flujo de venta es un ejemplo de cómo usar CloudScript basado en Azure Functions para ampliar la funcionalidad del sistema de economía.

[SellItem.cs](https://github.com/PlayFab/winter-starfall/blob/main/azure-functions/SellItem.cs) define la función de CloudScript que se ejecuta al vender un artículo.

Las líneas 49-61 son donde se usa la API `GetTitleData` de PlayFab para devolver el multiplicador de la tienda y calcular el precio de venta.

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

A continuación, la función de CloudScript se llama en las líneas 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>
  Para ejecutar Winter Starfall localmente necesitará una cuenta de Azure que admita las funciones de CloudScript. Puede [registrarse para obtener una cuenta gratuita de Azure](https://azure.microsoft.com/pricing/purchase-options/azure-account?msockid=1dec68fa155462cb2baa7ca6147963d7) y después seguir las instrucciones anteriores para restablecer correctamente las credenciales de Azure.
</Note>

## Consulte también

* Flujo de inicio de sesión
  * [Documentación de inicio de sesión de jugadores](/services/playfab/identity/player-identity/login)
* Flujo de compra
  * [Documentación de Economy V2](/services/playfab/economy-monetization/economy-v2/overview)
  * Otro buen paso siguiente para obtener más información sobre Economy V2 es probar el [tutorial del juego de fabricación](/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/game-context), que se centra en crear un juego de ejemplo usando las funciones de tienda e inventario.


## Related topics

- [Información general del juego de demostración de PlayFab Winter Starfall](/es/services/playfab/demo-game/overview.md)
- [Vanguard Outrider (heredado)](/es/services/playfab/demo-game/legacy-vanguard-outrider.md)
- [Procedimientos recomendados](/es/services/xbox-services/develop/best-practices/index.md)
- [Página de resumen de la configuración de los servicios XBOX](/es/services/xbox-services/fundamentals/portal-config/live-portal-summary-tab.md)
- [Procedimientos recomendados y pruebas para gamertags modernos](/es/services/xbox-services/fundamentals/identity/user-profile/gamertags/live-modern-gamertags-best-practices-and-testing.md)
