5180 fichiers 38.5 Mo 0 téléchargements 255 vues mis à jour il y a 5 heures ui
useGameCenter.ts 5.2 Ko Télécharger le fichier
import {
    Game2AccountGameStatusMessageEvent,
    Game2AccountGameStatusMessageParser,
    Game2CheckGameDirectoryStatusMessageComposer,
    Game2GameDirectoryStatusMessageEvent,
    Game2UserBlockedMessageEvent,
    GameConfigurationData,
    GameListMessageEvent,
    GameStatusMessageEvent,
    GetGameListMessageComposer,
    GetSnowWarGameTokensOfferComposer,
    SnowWarGameTokenOffer,
    SnowWarGameTokensMessageEvent,
    LoadGameUrlEvent,
    RoomEnterEvent
} from '@octane/renderer';
import { useCallback, useEffect, useState } from 'react';
import { registerSharedHook, useSharedHook } from '@/state/useSharedHook';
import { GetRoomSession, SendMessageComposer, setSnowWarReturnRoom, snowWarBlockDeadline, VisitDesktop } from '../../api';
import { useMessageEvent } from '../events';

const useGameCenterState = () => {
    const [isVisible, setIsVisible] = useState<boolean>(false);
    const [games, setGames] = useState<GameConfigurationData[]>(null);
    const [selectedGame, setSelectedGame] = useState<GameConfigurationData>(null);
    const [accountStatus, setAccountStatus] = useState<Game2AccountGameStatusMessageParser>(null);
    const [gameOffline, setGameOffline] = useState<boolean>(false);
    const [gameURL, setGameURL] = useState<string>(null);
    // Wall-clock end of the leave block (0 = not blocked).
    const [blockedUntil, setBlockedUntil] = useState<number>(0);
    // AIR games_main "How To Play" pages replace the tile grid while open.
    const [instructionsOpen, setInstructionsOpen] = useState<boolean>(false);
    // The "get more games" token offers (GetSnowWarGameTokensOffer).
    const [tokenOffers, setTokenOffers] = useState<SnowWarGameTokenOffer[]>([]);

    useMessageEvent<SnowWarGameTokensMessageEvent>(SnowWarGameTokensMessageEvent, (event) => {
        const parser = event.getParser();

        if (!parser) return;

        setTokenOffers(parser.offers ?? []);
    });

    // Leaving a running match blocks starting a new one; the hub shows the
    // countdown on the play button.
    useMessageEvent<Game2UserBlockedMessageEvent>(Game2UserBlockedMessageEvent, (event) => {
        const parser = event.getParser();

        if (!parser) return;

        setBlockedUntil(snowWarBlockDeadline(parser.playerBlockLength, Date.now()));
    });

    useMessageEvent<Game2GameDirectoryStatusMessageEvent>(Game2GameDirectoryStatusMessageEvent, (event) => {
        const parser = event.getParser();

        if (!parser) return;

        setBlockedUntil(snowWarBlockDeadline(parser.blockLength, Date.now()));
    });

    useMessageEvent<GameListMessageEvent>(GameListMessageEvent, (event) => {
        let parser = event.getParser();

        if (!parser || (parser && !parser.games.length)) return;

        setSelectedGame(parser.games[0]);

        setGames(parser.games);
    });

    useMessageEvent<Game2AccountGameStatusMessageEvent>(Game2AccountGameStatusMessageEvent, (event) => {
        let parser = event.getParser();

        if (!parser) return;

        setAccountStatus(parser);
    });

    useMessageEvent<GameStatusMessageEvent>(GameStatusMessageEvent, (event) => {
        let parser = event.getParser();

        if (!parser) return;

        setGameOffline(parser.isInMaintenance);
    });

    // Entering a room while the hub is open (e.g. the SnowWar arena editor
    // forwarding the player) must close the fullscreen hub overlay, or the
    // loaded room sits invisible behind it. Normal hub usage never enters a
    // room (opening it calls VisitDesktop), so this only fires on forwards.
    const onRoomEnter = useCallback(() => setIsVisible(false), []);

    useMessageEvent<RoomEnterEvent>(RoomEnterEvent, onRoomEnter);

    useMessageEvent<LoadGameUrlEvent>(LoadGameUrlEvent, (event) => {
        let parser = event.getParser();

        if (!parser) return;

        switch (parser.gameTypeId) {
            case 2:
                // SnowWar runs natively (SnowWarView + useSnowWar), not in an
                // iframe — the server drives it via the SnowWar packets.
                return;
            default:
                return setGameURL(parser.url);
        }
    });

    useEffect(() => {
        if (isVisible) {
            // Remember the room we're leaving so SnowWar can return us to it on
            // exit; VisitDesktop() below drops the room session. Overwrites any
            // stale value (null when we open the hub from outside a room).
            setSnowWarReturnRoom(GetRoomSession()?.roomId ?? null);
            SendMessageComposer(new GetGameListMessageComposer());
            SendMessageComposer(new Game2CheckGameDirectoryStatusMessageComposer());
            SendMessageComposer(new GetSnowWarGameTokensOfferComposer());
            VisitDesktop();
        } else {
            setInstructionsOpen(false);
        }
    }, [isVisible]);

    return {
        isVisible,
        setIsVisible,
        games,
        accountStatus,
        selectedGame,
        setSelectedGame,
        gameOffline,
        gameURL,
        setGameURL,
        blockedUntil,
        instructionsOpen,
        setInstructionsOpen,
        tokenOffers
    };
};

export const useGameCenter = () => useSharedHook(useGameCenterState);

registerSharedHook(useGameCenterState);
15Sujets
1Dépôts
20Membres
2En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser