API/Client-Server/js/SimpleLocalServer.js

536 lines
21 KiB
JavaScript

/**
* Simple Local Server for Singleplayer Mode
* A mock server that simulates server responses without requiring Node.js dependencies
* This runs entirely in the browser/renderer context
*/
class SimpleLocalServer {
constructor() {
this.isRunning = false;
this.port = 3004;
this.connectedClients = new Map();
this.existingSaveData = null;
// Check for existing save data on initialization
this.loadExistingSaveData();
this.mockData = {
servers: [{
id: 'local-server',
name: 'Local Singleplayer',
description: 'Your personal local server for singleplayer gaming',
type: 'private',
region: 'local',
maxPlayers: 1,
currentPlayers: 0,
owner: 'Local Player',
address: 'localhost',
port: this.port,
status: 'online',
createdAt: new Date().toISOString(),
ping: 0
}],
user: {
id: 'local-user',
email: 'local@player.com',
username: 'Local Player',
token: 'local-token-' + Date.now(),
createdAt: new Date().toISOString()
}
};
console.log('[SIMPLE LOCAL SERVER] SimpleLocalServer initialized');
console.log('[SIMPLE LOCAL SERVER] Existing save data found:', !!this.existingSaveData);
}
// Mock Socket.IO server for local mode
createMockSocket() {
console.log('[SIMPLE LOCAL SERVER] Creating mock Socket.IO connection');
const mockSocket = {
connected: false,
eventHandlers: {},
on: function(event, handler) {
console.log(`[MOCKET SOCKET] Registering event handler for: ${event}`);
if (!this.eventHandlers[event]) {
this.eventHandlers[event] = [];
}
this.eventHandlers[event].push(handler);
},
emit: function(event, data) {
console.log(`[MOCKET SOCKET] Emitting event: ${event}`, data);
},
connect: function() {
console.log('[MOCKET SOCKET] Connecting...');
this.connected = true;
// Simulate successful connection
setTimeout(() => {
if (this.eventHandlers['connect']) {
this.eventHandlers['connect'].forEach(handler => handler());
}
}, 100);
},
disconnect: function() {
console.log('[MOCKET SOCKET] Disconnecting...');
this.connected = false;
if (this.eventHandlers['disconnect']) {
this.eventHandlers['disconnect'].forEach(handler => handler());
}
}
};
// Auto-connect
mockSocket.connect();
return mockSocket;
}
loadExistingSaveData() {
try {
const saveData = localStorage.getItem(`gso_save_slot_1`);
if (saveData) {
this.existingSaveData = JSON.parse(saveData);
console.log('[SIMPLE LOCAL SERVER] Loaded existing save data:', {
hasPlayerData: !!this.existingSaveData.player,
playerLevel: this.existingSaveData.player?.stats?.level,
lastSave: this.existingSaveData.lastSave,
gameTime: this.existingSaveData.gameTime
});
} else {
console.log('[SIMPLE LOCAL SERVER] No existing save data found');
}
} catch (error) {
console.warn('[SIMPLE LOCAL SERVER] Error loading existing save data:', error);
this.existingSaveData = null;
}
}
applyExistingSaveDataToGame() {
if (!this.existingSaveData || !window.game) {
console.log('[SIMPLE LOCAL SERVER] No existing save data or game not available');
return false;
}
try {
console.log('[SIMPLE LOCAL SERVER] Applying existing save data to game...');
// Apply save data to game systems
if (this.existingSaveData.player && window.game.systems.player) {
window.game.systems.player.load(this.existingSaveData.player);
console.log('[SIMPLE LOCAL SERVER] Player data applied');
}
if (this.existingSaveData.inventory && window.game.systems.inventory) {
window.game.systems.inventory.load(this.existingSaveData.inventory);
console.log('[SIMPLE LOCAL SERVER] Inventory data applied');
}
if (this.existingSaveData.economy && window.game.systems.economy) {
window.game.systems.economy.load(this.existingSaveData.economy);
console.log('[SIMPLE LOCAL SERVER] Economy data applied');
}
if (this.existingSaveData.idleSystem && window.game.systems.idleSystem) {
window.game.systems.idleSystem.load(this.existingSaveData.idleSystem);
console.log('[SIMPLE LOCAL SERVER] Idle system data applied');
}
if (this.existingSaveData.dungeonSystem && window.game.systems.dungeonSystem) {
window.game.systems.dungeonSystem.load(this.existingSaveData.dungeonSystem);
console.log('[SIMPLE LOCAL SERVER] Dungeon system data applied');
}
if (this.existingSaveData.skillSystem && window.game.systems.skillSystem) {
window.game.systems.skillSystem.load(this.existingSaveData.skillSystem);
console.log('[SIMPLE LOCAL SERVER] Skill system data applied');
}
if (this.existingSaveData.baseSystem && window.game.systems.baseSystem) {
window.game.systems.baseSystem.load(this.existingSaveData.baseSystem);
console.log('[SIMPLE LOCAL SERVER] Base system data applied');
}
if (this.existingSaveData.questSystem && window.game.systems.questSystem) {
window.game.systems.questSystem.load(this.existingSaveData.questSystem);
console.log('[SIMPLE LOCAL SERVER] Quest system data applied');
}
if (this.existingSaveData.gameTime && window.game) {
window.game.gameTime = this.existingSaveData.gameTime;
console.log('[SIMPLE LOCAL SERVER] Game time applied:', this.existingSaveData.gameTime);
}
console.log('[SIMPLE LOCAL SERVER] All save data applied successfully');
return true;
} catch (error) {
console.error('[SIMPLE LOCAL SERVER] Error applying save data to game:', error);
return false;
}
}
async start(port = 3004) {
if (this.isRunning) {
console.log('[SIMPLE LOCAL SERVER] Server is already running on port', this.port);
return { success: false, error: 'Server already running' };
}
try {
this.port = port;
this.isRunning = true;
// Update mock server data with actual port
this.mockData.servers[0].port = port;
console.log(`[SIMPLE LOCAL SERVER] Mock local server started on port ${port}`);
return {
success: true,
port: port,
url: `http://localhost:${port}`
};
} catch (error) {
console.error('[SIMPLE LOCAL SERVER] Failed to start server:', error);
return { success: false, error: error.message };
}
}
async stop() {
if (!this.isRunning) {
console.log('[SIMPLE LOCAL SERVER] Server is not running');
return { success: false, error: 'Server is not running' };
}
try {
this.isRunning = false;
this.connectedClients.clear();
console.log('[SIMPLE LOCAL SERVER] Mock local server stopped');
return { success: true };
} catch (error) {
console.error('[SIMPLE LOCAL SERVER] Failed to stop server:', error);
return { success: false, error: error.message };
}
}
getStatus() {
return {
isRunning: this.isRunning,
port: this.port,
connectedClients: this.connectedClients.size,
uptime: this.isRunning ? 0 : 0 // Mock uptime
};
}
getUrl() {
return this.isRunning ? `http://localhost:${this.port}` : null;
}
// Mock API methods that simulate server responses
async mockRequest(method, url, data = null) {
console.log(`[SIMPLE LOCAL SERVER] Mock ${method} ${url}`, data);
// Simulate network delay
await new Promise(resolve => setTimeout(resolve, 100));
try {
if (url === '/health') {
return {
status: 200,
ok: true,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
status: 'OK',
timestamp: new Date().toISOString(),
uptime: 0,
mode: 'local'
}),
text: () => Promise.resolve(JSON.stringify({
status: 'OK',
timestamp: new Date().toISOString(),
uptime: 0,
mode: 'local'
}))
};
}
if (url === '/api/ssc/version') {
return {
status: 200,
ok: true,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
version: '1.0.0',
service: 'galaxystrikeonline-local-server',
timestamp: new Date().toISOString(),
mode: 'local'
}),
text: () => Promise.resolve(JSON.stringify({
version: '1.0.0',
service: 'galaxystrikeonline-local-server',
timestamp: new Date().toISOString(),
mode: 'local'
}))
};
}
if (url === '/api/auth/login' && method === 'POST') {
return {
status: 200,
ok: true,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: true,
user: this.mockData.user,
token: this.mockData.user.token,
message: 'Logged in to local mode'
}),
text: () => Promise.resolve(JSON.stringify({
success: true,
user: this.mockData.user,
token: this.mockData.user.token,
message: 'Logged in to local mode'
}))
};
}
if (url === '/api/auth/register' && method === 'POST') {
return {
status: 201,
ok: true,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: true,
user: this.mockData.user,
token: this.mockData.user.token,
message: 'Registered in local mode'
}),
text: () => Promise.resolve(JSON.stringify({
success: true,
user: this.mockData.user,
token: this.mockData.user.token,
message: 'Registered in local mode'
}))
};
}
if (url === '/api/servers') {
return {
status: 200,
ok: true,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: true,
servers: this.mockData.servers
}),
text: () => Promise.resolve(JSON.stringify({
success: true,
servers: this.mockData.servers
}))
};
}
if (url.startsWith('/servers/') && url.endsWith('/join') && method === 'POST') {
// Mock server join response
const serverId = url.split('/')[2];
return {
status: 200,
ok: true,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: true,
server: {
id: serverId,
name: 'Local Singleplayer',
address: 'localhost',
port: this.port,
gamePort: this.port + 1,
maxPlayers: 1,
currentPlayers: 1,
status: 'online'
},
message: 'Joined server successfully'
}),
text: () => Promise.resolve(JSON.stringify({
success: true,
server: {
id: serverId,
name: 'Local Singleplayer',
address: 'localhost',
port: this.port,
gamePort: this.port + 1,
maxPlayers: 1,
currentPlayers: 1,
status: 'online'
},
message: 'Joined server successfully'
}))
};
}
if (url.startsWith('/api/game/player/') && method === 'GET') {
// Return player data from existing save data or localStorage
let saveData = this.existingSaveData;
// If no existing save data, try localStorage
if (!saveData) {
try {
const localStorageData = localStorage.getItem(`gso_save_slot_1`);
if (localStorageData) {
saveData = JSON.parse(localStorageData);
}
} catch (error) {
console.warn('[SIMPLE LOCAL SERVER] Could not access localStorage:', error);
}
}
if (saveData) {
return {
status: 200,
ok: true,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: true,
player: saveData.player
}),
text: () => Promise.resolve(JSON.stringify({
success: true,
player: saveData.player
}))
};
} else {
return {
status: 404,
ok: false,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: false,
error: 'No save data found'
}),
text: () => Promise.resolve(JSON.stringify({
success: false,
error: 'No save data found'
}))
};
}
}
if (url.startsWith('/api/game/player/') && method === 'POST') {
// Save player data to localStorage
try {
let existingSaveData = '{}';
if (typeof localStorage !== 'undefined') {
existingSaveData = localStorage.getItem(`gso_save_slot_1`) || '{}';
}
const parsedExisting = JSON.parse(existingSaveData);
parsedExisting.player = data;
parsedExisting.lastSave = Date.now();
if (typeof localStorage !== 'undefined') {
localStorage.setItem(`gso_save_slot_1`, JSON.stringify(parsedExisting));
}
return {
status: 200,
ok: true,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: true,
message: 'Player data saved locally'
}),
text: () => Promise.resolve(JSON.stringify({
success: true,
message: 'Player data saved locally'
}))
};
} catch (error) {
return {
status: 500,
ok: false,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: false,
error: 'Failed to save player data'
}),
text: () => Promise.resolve(JSON.stringify({
success: false,
error: 'Failed to save player data'
}))
};
}
}
// Default response for unknown endpoints
return {
status: 404,
ok: false,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: false,
error: 'Endpoint not found'
}),
text: () => Promise.resolve(JSON.stringify({
success: false,
error: 'Endpoint not found'
}))
};
} catch (error) {
console.error('[SIMPLE LOCAL SERVER] Mock request error:', error);
return {
status: 500,
ok: false,
headers: {
get: (name) => name === 'content-type' ? 'application/json' : null
},
json: () => Promise.resolve({
success: false,
error: 'Internal server error'
}),
text: () => Promise.resolve(JSON.stringify({
success: false,
error: 'Internal server error'
}))
};
}
}
}
// Export for use in browser environment
if (typeof window !== 'undefined') {
window.SimpleLocalServer = SimpleLocalServer;
}
console.log('[SIMPLE LOCAL SERVER] SimpleLocalServer loaded and exported to window');