Game-Server/client/src/App.jsx
2026-03-29 00:16:10 -03:00

138 lines
4.1 KiB
JavaScript

import React, { useEffect, useState, useCallback, useRef } from "react";
import MainMenu from "./views/MainMenu/MainMenu";
import GameInterface from "./views/GameInterface/GameInterface";
import LoadingScreen from "./views/LoadingScreen/LoadingScreen.jsx";
import GameDataManager from "./services/GameDataManager";
import { useAuth } from "./hooks/useAuth";
import { useSocket } from "./hooks/useSocket";
function App() {
const { isConnected, connectToServer, socket } = useSocket();
const { user } = useAuth();
const [isInGame, setIsInGame] = useState(false);
const [isBooting, setIsBooting] = useState(false);
const [loadingProgress, setLoadingProgress] = useState(0);
const [statusText, setStatusText] = useState("");
const hasAttemptedBoot = useRef(false);
const fetchMetadata = useCallback(async (serverUrl) => {
try {
const response = await fetch(`${serverUrl}/api/game-metadata`);
if (!response.ok) throw new Error("Metadata fetch failed");
const data = await response.json();
GameDataManager.initialize(data);
return true;
} catch (err) {
console.error("Metadata Sync Error:", err);
return false;
}
}, []);
const bootSequence = useCallback(
async (serverUrl, token) => {
if (isBooting) return;
setIsBooting(true);
setLoadingProgress(10);
setStatusText("Initializing Systems...");
try {
setStatusText("Fetching Galactic Database...");
const success = await fetchMetadata(serverUrl);
if (!success) throw new Error("Initial metadata load failed");
setLoadingProgress(60);
setStatusText("Establishing Neural Link...");
const socketInstance = connectToServer(serverUrl, token);
socketInstance.once("session:ready", () => {
setLoadingProgress(100);
setStatusText("Ready to Launch");
setTimeout(() => {
setIsInGame(true);
setIsBooting(false);
}, 600);
});
socketInstance.once("connect_error", (err) => {
console.error("Socket error:", err);
setStatusText("Neural Link Failed");
setTimeout(() => setIsBooting(false), 2000);
});
} catch (err) {
console.error("Boot error:", err);
setStatusText("System Failure");
setTimeout(() => setIsBooting(false), 2000);
}
},
[connectToServer, isBooting, fetchMetadata],
);
useEffect(() => {
if (!socket || !isConnected) return;
const handleDataUpdate = async () => {
console.log("🔄 [System] Datapacks changed on server. Synchronizing...");
const savedServer = localStorage.getItem("activeServer");
if (!savedServer) return;
const { connectUrl } = JSON.parse(savedServer);
const success = await fetchMetadata(connectUrl);
if (success) {
console.log("✅ [System] Local database updated successfully.");
}
};
socket.on("system:data_updated", handleDataUpdate);
return () => {
socket.off("system:data_updated", handleDataUpdate);
};
}, [socket, isConnected, fetchMetadata]);
useEffect(() => {
if (user && !hasAttemptedBoot.current && !isConnected && !isInGame) {
const savedServer = localStorage.getItem("activeServer");
const token = user?.token;
if (savedServer && token) {
const server = JSON.parse(savedServer);
hasAttemptedBoot.current = true;
bootSequence(server.connectUrl, token);
}
}
}, [user, isConnected, isInGame, bootSequence]);
const handleStartGame = () => {
const savedServer = localStorage.getItem("activeServer");
const token = user?.token;
if (savedServer && token) {
const server = JSON.parse(savedServer);
bootSequence(server.connectUrl, token);
}
};
if (isBooting) {
return <LoadingScreen progress={loadingProgress} statusText={statusText} />;
}
return (
<div className="game-wrapper">
{isInGame && isConnected ? (
<GameInterface onExit={() => setIsInGame(false)} />
) : (
<MainMenu onStartGame={handleStartGame} />
)}
</div>
);
}
export default App;