mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-18 06:41:27 +02:00
324 lines
12 KiB
JavaScript
324 lines
12 KiB
JavaScript
/**
|
|
* Debug Manager Module
|
|
* Handles debug functionality and simulated block height logic for development
|
|
* Keeps debug/development code separate from production logic
|
|
*/
|
|
|
|
const rpc = require('../rpc/rpccalls.js');
|
|
const packageConfig = require('../package.json');
|
|
|
|
class DebugManager {
|
|
constructor(broadcastManager) {
|
|
this.broadcastManager = broadcastManager;
|
|
|
|
// Environment-based configuration
|
|
const nodeEnv = process.env.NODE_ENV || 'production';
|
|
this.IS_PRODUCTION = nodeEnv === 'production';
|
|
this.IS_DEBUG = nodeEnv === 'debug';
|
|
this.IS_DEVELOPMENT = nodeEnv === 'development';
|
|
|
|
// Debug mode is enabled in development or debug environments
|
|
this.DEBUG_MODE = this.IS_DEBUG || this.IS_DEVELOPMENT;
|
|
|
|
// Configuration precedence:
|
|
// 1. Explicit env overrides
|
|
// 2. Package.json config
|
|
const config = this.IS_PRODUCTION ? packageConfig.config.production : packageConfig.config.debug;
|
|
this.CONSOLE_LOGGING = process.env.CONSOLE_LOGGING ? process.env.CONSOLE_LOGGING === 'true' : (config.console_logging || this.DEBUG_MODE);
|
|
this.DEBUG_HOTKEYS = process.env.DEBUG_HOTKEYS ? process.env.DEBUG_HOTKEYS === 'true' : (config.debug_hotkeys || this.DEBUG_MODE);
|
|
// Simulation can be force-disabled by BLOCK_SOURCE=daemon or GAME_MODE paid modes
|
|
const forceSimFlag = process.env.FORCE_SIMULATED_BLOCKS === 'true';
|
|
const blockSource = (process.env.BLOCK_SOURCE || '').toLowerCase(); // 'daemon' | 'simulated'
|
|
let simulatedDefault = config.simulated_blocks || this.DEBUG_MODE;
|
|
if (blockSource === 'daemon') simulatedDefault = false;
|
|
// In paid modes always use real daemon unless explicitly forced (for test)
|
|
const paidMode = ['PAID_SINGLE','PAID_CREDITS'].includes(process.env.GAME_MODE);
|
|
if (paidMode && !forceSimFlag) simulatedDefault = false;
|
|
this.SIMULATED_BLOCKS = process.env.SIMULATED_BLOCKS ? process.env.SIMULATED_BLOCKS === 'true' : simulatedDefault;
|
|
|
|
this.debugBlockHeight = 1;
|
|
this.debugInterval = null;
|
|
this.statusInterval = null;
|
|
this.lastProductionBlockHeight = 0;
|
|
|
|
// Log configuration on startup
|
|
this.logConfig();
|
|
}
|
|
|
|
// ====== CONFIGURATION LOGGING ======
|
|
|
|
/**
|
|
* Log current configuration settings
|
|
*/
|
|
logConfig() {
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log("🔧 DEBUG MANAGER CONFIGURATION:");
|
|
console.log(` NODE_ENV: ${process.env.NODE_ENV || 'production'}`);
|
|
console.log(` DEBUG_MODE: ${this.DEBUG_MODE}`);
|
|
console.log(` CONSOLE_LOGGING: ${this.CONSOLE_LOGGING}`);
|
|
console.log(` DEBUG_HOTKEYS: ${this.DEBUG_HOTKEYS}`);
|
|
console.log(` SIMULATED_BLOCKS: ${this.SIMULATED_BLOCKS}`);
|
|
if (process.env.GAME_MODE && ['PAID_SINGLE','PAID_CREDITS'].includes(process.env.GAME_MODE)) {
|
|
console.log(` GAME_MODE: ${process.env.GAME_MODE} (simulation ${this.SIMULATED_BLOCKS ? 'ENABLED' : 'DISABLED'})`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ====== INITIALIZATION ======
|
|
|
|
/**
|
|
* Initialize debug mode or production mode
|
|
*/
|
|
initialize() {
|
|
if (this.SIMULATED_BLOCKS) {
|
|
this.initializeDebugMode();
|
|
} else {
|
|
this.initializeProductionMode();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize debug mode with simulated blocks
|
|
*/
|
|
initializeDebugMode() {
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log("🐛 DEBUG MODE ENABLED - Simulating blocks every 30 seconds");
|
|
}
|
|
|
|
// Initial debug block broadcast
|
|
this.broadcastManager.broadcastBlockHeight(this.debugBlockHeight);
|
|
|
|
// Debug block height simulator - advances every 30 seconds
|
|
this.debugInterval = setInterval(() => {
|
|
this.debugBlockHeight++;
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log(`🐛 DEBUG: New simulated block: ${this.debugBlockHeight}`);
|
|
}
|
|
this.broadcastManager.broadcastBlockHeight(this.debugBlockHeight);
|
|
|
|
// Notify listeners about new block
|
|
this.onNewBlock(this.debugBlockHeight);
|
|
|
|
}, 30000); // Every 30 seconds
|
|
|
|
// Regular status broadcasting - sends current block height every 5 seconds
|
|
// This ensures all clients stay up-to-date even if they miss a block change
|
|
this.statusInterval = setInterval(() => {
|
|
this.broadcastManager.broadcastBlockHeight(this.debugBlockHeight);
|
|
}, 5000); // Every 5 seconds
|
|
}
|
|
|
|
/**
|
|
* Initialize production mode with real blockchain calls
|
|
*/
|
|
initializeProductionMode() {
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log("🚀 PRODUCTION MODE ENABLED - Using real blockchain RPC calls");
|
|
}
|
|
|
|
// Initialize RPC service if available
|
|
const RpcService = require('../rpc/rpcService');
|
|
this.rpcService = new RpcService();
|
|
|
|
// Real blockchain monitoring with new RPC service
|
|
const poll = async () => {
|
|
try {
|
|
const currentHeight = await this.rpcService.getBlockHeight();
|
|
|
|
if (!currentHeight) {
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log("❌ Failed to get block count from daemon");
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Always broadcast current height to keep clients updated
|
|
this.broadcastManager.broadcastBlockHeight(currentHeight);
|
|
|
|
// If new block found
|
|
if (currentHeight > this.lastProductionBlockHeight) {
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log(`⛏️ New block found: ${currentHeight}`);
|
|
}
|
|
|
|
// Notify listeners about new block
|
|
this.onNewBlock(currentHeight);
|
|
|
|
this.lastProductionBlockHeight = currentHeight;
|
|
}
|
|
} catch (error) {
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.error("❌ RPC Error:", error.message);
|
|
}
|
|
|
|
// Fallback to legacy RPC if new service fails
|
|
rpc.daemonCall("get_block_count", "", (result) => {
|
|
if (result && result.result && result.result.count) {
|
|
const currentHeight = result.result.count;
|
|
this.broadcastManager.broadcastBlockHeight(currentHeight);
|
|
|
|
if (currentHeight > this.lastProductionBlockHeight) {
|
|
this.onNewBlock(currentHeight);
|
|
this.lastProductionBlockHeight = currentHeight;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
// immediate first poll so UI shows real height quickly
|
|
poll();
|
|
this.debugInterval = setInterval(poll, 2000); // Every 2 seconds
|
|
}
|
|
|
|
// ====== BLOCK HEIGHT MANAGEMENT ======
|
|
|
|
/**
|
|
* Get the current block height (debug or production)
|
|
* @returns {number} Current block height
|
|
*/
|
|
getCurrentBlockHeight() {
|
|
if (this.SIMULATED_BLOCKS) return this.debugBlockHeight;
|
|
return this.lastProductionBlockHeight;
|
|
}
|
|
|
|
/**
|
|
* Set debug block height (debug mode only)
|
|
* @param {number} height - New block height
|
|
*/
|
|
setDebugBlockHeight(height) {
|
|
if (this.DEBUG_MODE) {
|
|
this.debugBlockHeight = height;
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log(`🐛 DEBUG: Block height set to: ${height}`);
|
|
}
|
|
this.broadcastManager.broadcastBlockHeight(height);
|
|
} else if (this.CONSOLE_LOGGING) {
|
|
console.warn("Cannot set debug block height in production mode");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Advance debug block height by one (debug mode only)
|
|
*/
|
|
advanceDebugBlock() {
|
|
if (this.DEBUG_MODE) {
|
|
this.debugBlockHeight++;
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log(`🐛 DEBUG: Manually advanced block to: ${this.debugBlockHeight}`);
|
|
}
|
|
this.broadcastManager.broadcastBlockHeight(this.debugBlockHeight);
|
|
this.onNewBlock(this.debugBlockHeight);
|
|
} else if (this.CONSOLE_LOGGING) {
|
|
console.warn("Cannot advance debug block in production mode");
|
|
}
|
|
}
|
|
|
|
// ====== EVENT HANDLING ======
|
|
|
|
/**
|
|
* Called when a new block is detected (debug or production)
|
|
* Override this method or set callbacks to handle new blocks
|
|
* @param {number} blockHeight - The new block height
|
|
*/
|
|
onNewBlock(blockHeight) {
|
|
// This method can be overridden or have callbacks registered
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log(`📦 New block detected: ${blockHeight}`);
|
|
}
|
|
|
|
// Call registered callbacks
|
|
if (this.newBlockCallbacks) {
|
|
this.newBlockCallbacks.forEach(callback => {
|
|
try {
|
|
callback(blockHeight);
|
|
} catch (error) {
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.error("Error in new block callback:", error);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register a callback for when new blocks are detected
|
|
* @param {function} callback - Function to call with new block height
|
|
*/
|
|
onNewBlockCallback(callback) {
|
|
if (!this.newBlockCallbacks) {
|
|
this.newBlockCallbacks = [];
|
|
}
|
|
this.newBlockCallbacks.push(callback);
|
|
}
|
|
|
|
// ====== DEBUG UTILITIES ======
|
|
|
|
/**
|
|
* Get debug status information
|
|
* @returns {object} Debug status object
|
|
*/
|
|
getDebugStatus() {
|
|
return {
|
|
debugMode: this.DEBUG_MODE,
|
|
currentBlockHeight: this.getCurrentBlockHeight(),
|
|
isRunning: !!this.debugInterval,
|
|
lastProductionBlock: this.lastProductionBlockHeight,
|
|
debugBlock: this.debugBlockHeight
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Log debug socket event
|
|
* @param {string} socketId - Socket ID
|
|
* @param {string} eventName - Event name
|
|
* @param {object} data - Event data
|
|
*/
|
|
debugSocket(socketId, eventName, data) {
|
|
if (this.CONSOLE_LOGGING) {
|
|
const shortSocketId = socketId.substring(0, 8);
|
|
console.log(`🔌 SOCKET DEBUG: Sending ${eventName} to ${shortSocketId}...`);
|
|
|
|
// Limit payload logging to prevent console spam
|
|
const dataStr = JSON.stringify(data);
|
|
const shortDataStr = dataStr.length > 300 ? dataStr.substring(0, 300) + "..." : dataStr;
|
|
console.log(`📦 PAYLOAD: ${shortDataStr}`);
|
|
}
|
|
}
|
|
|
|
// ====== CLEANUP ======
|
|
|
|
/**
|
|
* Stop all debug intervals and clean up
|
|
*/
|
|
cleanup() {
|
|
if (this.debugInterval) {
|
|
clearInterval(this.debugInterval);
|
|
this.debugInterval = null;
|
|
}
|
|
|
|
if (this.statusInterval) {
|
|
clearInterval(this.statusInterval);
|
|
this.statusInterval = null;
|
|
}
|
|
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log("🧹 Debug manager cleaned up");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Toggle debug mode (restart required)
|
|
* @param {boolean} enabled - Whether to enable debug mode
|
|
*/
|
|
setDebugMode(enabled) {
|
|
if (this.CONSOLE_LOGGING) {
|
|
console.log(`🔄 Switching debug mode to: ${enabled ? 'ENABLED' : 'DISABLED'}`);
|
|
}
|
|
this.cleanup();
|
|
this.DEBUG_MODE = enabled;
|
|
this.initialize();
|
|
}
|
|
}
|
|
|
|
module.exports = DebugManager;
|