API/Client-Server/js/GameInitializer.js

721 lines
29 KiB
JavaScript

/**
* Game Initializer
* Handles initialization of multiplayer game modes
*/
console.log('[GAME INITIALIZER] GameInitializer.js script loaded');
class GameInitializer {
constructor() {
console.log('[GAME INITIALIZER] Constructor called');
this.gameMode = 'multiplayer';
this.serverData = null;
this.authToken = null;
this.currentUser = null;
this.socket = null;
this.apiBaseUrl = 'https://api.korvarix.com/api'; // API Server
this.gameServerUrl = 'https://dev.gameserver.galaxystrike.online'; // Game Server for Socket.IO (local dev server)
console.log('[GAME INITIALIZER] Constructor - gameServerUrl set to:', this.gameServerUrl);
}
updateServerUrls(apiUrl, gameUrl) {
console.log('[GAME INITIALIZER] Updating server URLs:', { apiUrl: apiUrl, gameUrl: gameUrl });
console.log('[GAME INITIALIZER] Previous gameServerUrl:', this.gameServerUrl);
this.apiBaseUrl = apiUrl;
this.gameServerUrl = gameUrl;
console.log('[GAME INITIALIZER] New gameServerUrl:', this.gameServerUrl);
}
initializeMultiplayer(server, serverData, authToken, currentUser) {
console.log('[GAME INITIALIZER] Initializing multiplayer game mode');
this.gameMode = 'multiplayer';
this.serverData = { ...server, ...serverData };
this.authToken = authToken;
this.currentUser = currentUser;
// Initialize Socket.IO connection
this.initializeSocketConnection();
// Set SmartSaveManager to multiplayer mode
if (window.smartSaveManager) {
window.smartSaveManager.setMultiplayerMode(true, this);
}
// Update UI for multiplayer mode
this.updateUIForMultiplayerMode();
console.log('[GAME INITIALIZER] Multiplayer game initialized');
}
initializeSocketConnection() {
if (!this.serverData) {
console.error('[GAME INITIALIZER] No server data for socket connection');
return;
}
console.log('[GAME INITIALIZER] Initializing Socket.IO connection');
console.log('[GAME INITIALIZER] Using gameServerUrl:', this.gameServerUrl);
// Check if we're in local mode and should use mock socket
if (this.gameServerUrl.includes('localhost') && window.localServerManager && window.localServerManager.localServer) {
console.log('[GAME INITIALIZER] Using mock socket for local mode');
this.socket = window.localServerManager.localServer.createMockSocket();
// Trigger connected event immediately since mock socket auto-connects
setTimeout(() => {
this.onSocketConnected();
}, 200);
return;
}
// FORCE THE URL - Override any undefined issues
const FORCED_URL = 'https://dev.gameserver.galaxystrike.online';
console.log('[GAME INITIALIZER] FORCING URL to:', FORCED_URL);
console.log('[GAME INITIALIZER] Original this.gameServerUrl:', this.gameServerUrl);
// Connect to the game server with FORCED URL
this.socket = io(FORCED_URL, {
auth: {
token: this.authToken,
serverId: this.serverData.id
}
});
console.log('[GAME INITIALIZER] Socket.IO connection initiated to FORCED URL:', FORCED_URL);
// Socket event handlers
this.socket.on('connect', () => {
console.log('[GAME INITIALIZER] Connected to server');
this.onSocketConnected();
});
this.socket.on('disconnect', () => {
console.log('[GAME INITIALIZER] Disconnected from server');
this.onSocketDisconnected();
});
this.socket.on('error', (error) => {
console.error('[GAME INITIALIZER] Socket error:', error);
});
this.socket.on('force_disconnect', (data) => {
console.warn('[GAME INITIALIZER] Force disconnected:', data);
this.onForceDisconnect(data);
});
// Game-specific events
this.socket.on('playerJoined', (data) => {
console.log('[GAME INITIALIZER] Player joined:', data);
this.onPlayerJoined(data);
});
this.socket.on('playerLeft', (data) => {
console.log('[GAME INITIALIZER] Player left:', data);
this.onPlayerLeft(data);
});
this.socket.on('gameUpdate', (data) => {
console.log('[GAME INITIALIZER] Game update:', data);
this.onGameUpdate(data);
});
this.socket.on('chatMessage', (data) => {
console.log('[GAME INITIALIZER] Chat message:', data);
this.onChatMessage(data);
});
// Server data events
this.socket.on('authenticated', (data) => {
console.log('[GAME INITIALIZER] Authentication response:', data);
this.onAuthenticated(data);
});
this.socket.on('gameDataLoaded', (data) => {
console.log('[GAME INITIALIZER] Game data loaded:', data);
this.onGameDataLoaded(data);
});
this.socket.on('updatePlayerStats', (data) => {
console.log('[GAME INITIALIZER] Player stats updated on server:', data);
this.onGameDataSaved(data);
});
this.socket.on('gameDataSaved', (data) => {
console.log('[GAME INITIALIZER] Game data saved:', data);
this.onGameDataSaved(data);
});
}
onSocketConnected() {
// Join the server room
this.socket.emit('joinServer', {
serverId: this.serverData.id,
userId: this.currentUser.userId,
username: this.currentUser.username
});
// Authenticate with server to get player data
this.authenticateWithServer();
// Show connected status
this.showConnectionStatus('Connected', 'success');
}
onSocketDisconnected() {
console.log('[GAME INITIALIZER] Socket disconnected - switching to singleplayer mode');
// Show disconnected status
this.showConnectionStatus('Disconnected', 'error');
// Switch SmartSaveManager back to singleplayer mode
if (window.smartSaveManager) {
window.smartSaveManager.setMultiplayerMode(false);
console.log('[GAME INITIALIZER] SmartSaveManager set to singleplayer mode');
}
// Clear socket reference
this.socket = null;
console.log('[GAME INITIALIZER] Socket reference cleared');
}
// Force disconnect from multiplayer server
forceDisconnect() {
console.log('[GAME INITIALIZER] Force disconnect called');
if (this.socket) {
console.log('[GAME INITIALIZER] Disconnecting socket...');
this.socket.disconnect();
this.socket = null;
}
// Switch to singleplayer mode
if (window.smartSaveManager) {
window.smartSaveManager.setMultiplayerMode(false);
console.log('[GAME INITIALIZER] Force switched to singleplayer mode');
}
this.showConnectionStatus('Disconnected', 'error');
console.log('[GAME INITIALIZER] Force disconnect completed');
}
onPlayerJoined(data) {
// Handle player joining
this.updatePlayerList();
this.showNotification(`${data.username} joined the server`, 'info');
}
onPlayerLeft(data) {
// Handle player leaving
this.updatePlayerList();
this.showNotification(`${data.username} left the server`, 'info');
}
onGameUpdate(data) {
// Handle game state updates
if (window.game && window.game.handleServerUpdate) {
window.game.handleServerUpdate(data);
}
}
onChatMessage(data) {
// Handle chat messages
if (window.game && window.game.handleChatMessage) {
window.game.handleChatMessage(data);
}
}
onAuthenticated(data) {
console.log('[GAME INITIALIZER] Authentication successful:', data);
if (data.success && data.playerData) {
// Store server player data from authentication (this is our primary source)
this.serverPlayerData = data.playerData;
console.log('[GAME INITIALIZER] Using authentication data as primary source:', this.serverPlayerData);
// NOW create GameEngine AFTER authentication is successful
if (!window.game) {
console.log('[GAME INITIALIZER] Creating GameEngine after successful authentication');
this.createGameEngineForMultiplayer();
}
// Set SmartSaveManager to multiplayer mode
if (window.smartSaveManager) {
window.smartSaveManager.setMultiplayerMode(true, this);
console.log('[GAME INITIALIZER] SmartSaveManager set to multiplayer mode');
// Apply authentication data immediately
window.smartSaveManager.applyServerDataToGame(data.playerData);
}
// Fallback: Apply authentication data to game if game is running
if (window.game && window.game.loadServerPlayerData) {
console.log('[GAME INITIALIZER] Applying authentication data to GameEngine:', data.playerData);
window.game.loadServerPlayerData(data.playerData);
console.log('[GAME INITIALIZER] Authentication data applied to GameEngine');
// Force UI refresh when authentication data is applied
if (window.game.systems && window.game.systems.ui && window.game.systems.ui.forceRefreshAllUI) {
console.log('[GAME INITIALIZER] Forcing UI refresh after authentication data application');
window.game.systems.ui.forceRefreshAllUI();
}
}
this.showNotification(`Welcome back! Level ${data.playerData.stats?.level || 1}`, 'success');
} else {
this.showNotification(data.error || 'Authentication failed', 'error');
}
}
createGameEngineForMultiplayer() {
console.log('[GAME INITIALIZER] Creating GameEngine for multiplayer mode');
console.log('[GAME INITIALIZER] Server player data available:', !!this.serverPlayerData);
try {
// Create GameEngine instance
window.game = new GameEngine();
// Initialize the game engine
console.log('[GAME INITIALIZER] About to call window.game.init()');
const initPromise = window.game.init();
console.log('[GAME INITIALIZER] GameEngine.init() returned:', typeof initPromise, initPromise);
initPromise.then(() => {
console.log('[GAME INITIALIZER] GameEngine initialized successfully for multiplayer');
// Apply server data immediately after initialization
if (this.serverPlayerData && window.game.loadServerPlayerData) {
console.log('[GAME INITIALIZER] Applying server player data to GameEngine:', this.serverPlayerData);
window.game.loadServerPlayerData(this.serverPlayerData);
console.log('[GAME INITIALIZER] Server player data applied to GameEngine');
// Force UI refresh
if (window.game.systems && window.game.systems.ui && window.game.systems.ui.forceRefreshAllUI) {
console.log('[GAME INITIALIZER] Forcing UI refresh after data application');
window.game.systems.ui.forceRefreshAllUI();
}
} else {
console.warn('[GAME INITIALIZER] No server player data or loadServerPlayerData method available');
}
// Start the game
if (window.game.start) {
window.game.start();
}
}).catch((error) => {
console.error('[GAME INITIALIZER] GameEngine init failed:', error);
console.error('[GAME INITIALIZER] Error details:', error.stack);
this.showNotification('Failed to initialize game engine', 'error');
});
} catch (error) {
console.error('[GAME INITIALIZER] Error creating GameEngine:', error);
this.showNotification('Error creating game engine', 'error');
}
}
onGameDataLoaded(data) {
console.log('[GAME INITIALIZER] Server game data loaded:', data);
console.log('[GAME INITIALIZER] Data success:', data.success);
console.log('[GAME INITIALIZER] Data content:', data.data);
console.log('[GAME INITIALIZER] Data keys:', data.data ? Object.keys(data.data) : 'No data object');
if (data.success && data.data && Object.keys(data.data).length > 0) {
// Store server player data
this.serverPlayerData = data.data;
console.log('[GAME INITIALIZER] Applying server data to game systems');
// Apply server data to game if game is running
if (window.game && window.game.loadServerPlayerData) {
window.game.loadServerPlayerData(data.data);
// Force UI refresh when server data is applied
if (window.game.systems && window.game.systems.ui && window.game.systems.ui.forceRefreshAllUI) {
window.game.systems.ui.forceRefreshAllUI();
}
} else {
console.warn('[GAME INITIALIZER] No game or loadServerPlayerData method available');
}
} else {
console.log('[GAME INITIALIZER] Ignoring empty game data - no player data to load');
console.log('[GAME INITIALIZER] Data analysis:', {
success: data.success,
hasData: !!data.data,
dataKeys: data.data ? Object.keys(data.data) : [],
dataLength: data.data ? JSON.stringify(data.data).length : 0
});
}
}
onGameDataSaved(data) {
console.log('[GAME INITIALIZER] Server game data saved:', data);
if (data.success) {
this.showNotification('Game saved to server!', 'success');
} else {
this.showNotification(data.error || 'Failed to save to server', 'error');
}
}
onForceDisconnect(data) {
// Handle forced disconnection from server
console.warn('[GAME INITIALIZER] Force disconnected by server:', data);
// Show notification to user
if (window.game && window.game.showNotification) {
window.game.showNotification(
`Disconnected: ${data.reason}`,
'warning',
10000
);
}
// Disconnect the socket
if (this.socket) {
this.socket.disconnect();
}
// Clean up multiplayer mode
if (window.game) {
window.game.setMultiplayerMode(false);
}
// Return to main menu after a delay
setTimeout(() => {
if (window.liveMainMenu) {
window.liveMainMenu.showLoginSection();
}
}, 2000);
}
initializeGameSystems() {
console.log('[GAME INITIALIZER] Initializing game systems');
// Wait for the main game script to be ready
if (typeof window.game !== 'undefined') {
console.log('[GAME INITIALIZER] window.game is available, calling setupGameSystems');
this.setupGameSystems();
} else {
console.log('[GAME INITIALIZER] window.game not available, waiting 100ms');
// Wait for the game to be initialized
setTimeout(() => this.initializeGameSystems(), 100);
}
}
setupGameSystems() {
if (!window.game) {
console.error('[GAME INITIALIZER] Game not available');
return;
}
console.log('[GAME INITIALIZER] Setting up game systems for multiplayer mode');
// Configure game for multiplayer mode
console.log('[GAME INITIALIZER] Configuring for multiplayer mode');
window.game.setMultiplayerMode(true, this.socket, this.serverData, this.currentUser);
window.game.gameInitializer = this; // Store reference for server polling
// DISABLE game logic in multiplayer - server is authoritative
if (window.game) {
console.log('[GAME INITIALIZER] Disabling client game logic - server is authoritative');
// Override game logic methods to do nothing in multiplayer
const originalUpdateGameLogic = window.game.updateGameLogic;
window.game.updateGameLogic = function() {
// In multiplayer mode, client does NO game logic
// Server is authoritative for ALL game data including credits
// Client is display-only
};
const originalStart = window.game.start;
window.game.start = function() {
console.log('[GAME ENGINE] Multiplayer mode - client does not run game logic, server is authoritative');
console.log('[GAME ENGINE] GameInitializer reference:', !!this.gameInitializer);
console.log('[GAME ENGINE] Socket reference:', !!(this.gameInitializer && this.gameInitializer.socket));
console.log('[GAME ENGINE] Game mode:', this.gameInitializer ? this.gameInitializer.gameMode : 'no gameInitializer');
this.isRunning = true;
// NO game logic timer - client is display-only
// Server handles all game logic including credit generation
// Start server data polling for UI updates
if (this.gameInitializer && this.gameInitializer.socket) {
console.log('[GAME ENGINE] Starting server data polling for UI updates');
this.serverPollTimer = setInterval(() => {
console.log('[GAME ENGINE] Polling server for data...');
this.gameInitializer.loadGameDataFromServer();
}, 5000); // Request updates every 5 seconds
} else {
console.warn('[GAME ENGINE] Cannot start server polling - no gameInitializer or socket');
}
// Only start UI updates that use server data (every second)
if (this.systems.ui) {
console.log('[GAME ENGINE] Starting multiplayer UI updates');
this.uiUpdateTimer = setInterval(() => {
if (this.systems && this.systems.ui && this.systems.ui.updateUI) {
console.log('[GAME ENGINE] Updating multiplayer UI with server data');
this.systems.ui.updateUI();
}
}, 1000);
}
};
}
// Game is already set up with save data, just start the game loop
if (window.game.start) {
// console.log('[GAME INITIALIZER] Calling start() to begin game loop');
window.game.start();
} else if (window.game.startGame) {
// console.log('[GAME INITIALIZER] Calling startGame(false) - save data already applied');
window.game.startGame(false); // false = don't load again (save data already applied)
} else {
console.error('[GAME INITIALIZER] No start method available on window.game');
}
console.log('[GAME INITIALIZER] Game systems configured');
}
updateUIForMultiplayerMode() {
// Update UI elements to show multiplayer mode
const playerName = document.getElementById('playerName');
if (playerName && this.currentUser) {
playerName.textContent = this.currentUser.username;
}
// Show multiplayer-specific UI elements
this.showMultiplayerUI();
// Show server info
this.showServerInfo();
}
hideMultiplayerUI() {
// Hide elements that are only relevant in multiplayer
const chatContainer = document.getElementById('chatContainer');
if (chatContainer) {
chatContainer.classList.add('hidden');
}
const playerList = document.getElementById('playerList');
if (playerList) {
playerList.classList.add('hidden');
}
}
showMultiplayerUI() {
// Show multiplayer-specific elements
const chatContainer = document.getElementById('chatContainer');
if (chatContainer) {
chatContainer.classList.remove('hidden');
}
const playerList = document.getElementById('playerList');
if (playerList) {
playerList.classList.remove('hidden');
}
}
showServerInfo() {
// Add server information to the UI
const header = document.querySelector('.game-header');
if (header && !header.querySelector('.server-info')) {
const serverInfo = document.createElement('div');
serverInfo.className = 'server-info';
serverInfo.innerHTML = `
<i class="fas fa-server"></i>
<span>${this.serverData.name} (${this.serverData.currentPlayers}/${this.serverData.maxPlayers})</span>
`;
serverInfo.style.cssText = `
background: rgba(0, 212, 255, 0.2);
color: #00d4ff;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.8rem;
margin-left: 10px;
`;
header.appendChild(serverInfo);
}
}
showConnectionStatus(status, type) {
// Show connection status in the UI
const statusElement = document.getElementById('connectionStatus');
if (statusElement) {
statusElement.textContent = status;
statusElement.className = `connection-status ${type}`;
}
}
updatePlayerList() {
// Update the player list UI
if (this.socket && this.serverData) {
// Request updated player list from server
this.socket.emit('getPlayerList', { serverId: this.serverData.id });
}
}
showNotification(message, type = 'info') {
// Show a notification to the user
if (window.game && window.game.showNotification) {
window.game.showNotification(message, type, 3000);
} else {
// Fallback to alert
console.log(`[GAME INITIALIZER] Notification: ${message}`);
}
}
// Method to send actions to the server
sendGameAction(actionType, actionData) {
if (this.socket && this.gameMode === 'multiplayer') {
this.socket.emit('gameAction', {
type: actionType,
data: actionData,
userId: this.currentUser.userId,
serverId: this.serverData.id
});
}
}
// Method to send chat messages
sendChatMessage(message) {
if (this.socket && this.gameMode === 'multiplayer') {
this.socket.emit('chatMessage', {
message: message,
userId: this.currentUser.userId,
username: this.currentUser.username,
serverId: this.serverData.id
});
}
}
// Method to save game data to server (SECURE: only send specific updates)
saveGameDataToServer(gameData) {
if (this.socket && this.gameMode === 'multiplayer') {
console.log('[GAME INITIALIZER] Sending secure game updates to server');
// Only send specific, validated updates - not entire game state
const secureUpdates = {
playerStats: {
credits: gameData.player?.credits || 0,
level: gameData.player?.level || 1,
experience: gameData.player?.experience || 0,
playTime: gameData.player?.playTime || 0
},
timestamp: Date.now()
};
// Send only the specific updates for server validation
this.socket.emit('updatePlayerStats', secureUpdates);
}
}
// Method to load game data from server
loadGameDataFromServer() {
if (this.socket && this.gameMode === 'multiplayer') {
console.log('[GAME INITIALIZER] Loading game data from server');
console.log('[GAME INITIALIZER] Socket available:', !!this.socket);
console.log('[GAME INITIALIZER] Game mode:', this.gameMode);
console.log('[GAME INITIALIZER] Current user:', this.currentUser);
console.log('[GAME INITIALIZER] Emitting loadGameData event with username');
// Get username from current user or fallback to stored user
let username = 'anonymous'; // default fallback
if (this.currentUser?.username) {
username = this.currentUser.username;
} else {
// Try to get from localStorage as fallback
const storedUser = localStorage.getItem('currentUser');
if (storedUser) {
try {
const user = JSON.parse(storedUser);
username = user.username || 'anonymous';
} catch (e) {
console.warn('[GAME INITIALIZER] Failed to parse stored user, using default');
}
}
}
console.log('[GAME INITIALIZER] Using username for data load:', username);
// Send the username to load the correct player data
this.socket.emit('loadGameData', {
username: username
});
} else {
console.log('[GAME INITIALIZER] Cannot load game data - socket or multiplayer mode not available');
console.log('[GAME INITIALIZER] Socket available:', !!this.socket);
console.log('[GAME INITIALIZER] Game mode:', this.gameMode);
}
}
// Method to authenticate with server
authenticateWithServer() {
console.log('[GAME INITIALIZER] authenticateWithServer called');
console.log('[GAME INITIALIZER] Socket available:', !!this.socket);
console.log('[GAME INITIALIZER] Game mode:', this.gameMode);
console.log('[GAME INITIALIZER] Current user:', this.currentUser);
if (this.socket && this.currentUser) {
console.log('[GAME INITIALIZER] Sending authentication to server');
this.socket.emit('authenticate', {
userId: this.currentUser.userId,
username: this.currentUser.username
});
} else {
console.warn('[GAME INITIALIZER] Cannot authenticate - missing socket or user data');
if (!this.socket) {
console.warn('[GAME INITIALIZER] Socket is null/undefined');
}
if (!this.currentUser) {
console.warn('[GAME INITIALIZER] Current user is null/undefined');
}
}
}
// Cleanup method
cleanup() {
console.log('[GAME INITIALIZER] Cleaning up');
// Reset SmartSaveManager to singleplayer mode
if (window.smartSaveManager) {
window.smartSaveManager.setMultiplayerMode(false);
}
if (this.socket) {
this.socket.disconnect();
this.socket = null;
}
this.gameMode = null;
this.serverData = null;
this.authToken = null;
this.currentUser = null;
this.serverPlayerData = null;
}
}
// Create global instance
window.gameInitializer = new GameInitializer();
// Make force disconnect available globally for testing
window.forceDisconnectMultiplayer = function() {
if (window.gameInitializer && window.gameInitializer.forceDisconnect) {
window.gameInitializer.forceDisconnect();
} else {
console.log('[GAME INITIALIZER] GameInitializer not available for force disconnect');
}
};
// Debug: Log the global instance immediately
console.log('[GAME INITIALIZER] Global instance created:', window.gameInitializer);
console.log('[GAME INITIALIZER] Global instance gameServerUrl:', window.gameInitializer.gameServerUrl);
// Export for use in other scripts
if (typeof module !== 'undefined' && module.exports) {
module.exports = GameInitializer;
}