138 lines
4.1 KiB
JavaScript
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;
|