From 2c781ec043d1c5e3ddb053215f9dbdac18b96bb9 Mon Sep 17 00:00:00 2001 From: jwinterm Date: Wed, 24 Dec 2025 20:03:26 -0500 Subject: [PATCH] fix payout calcs --- html/js/network/socketHandlers.js | 24 ++++++++++++++++++++++++ src/game/gameModeManager.js | 9 ++++++--- src/network/broadcastManager.js | 13 +++++++++++++ src/network/connectionHandler.js | 6 ++++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/html/js/network/socketHandlers.js b/html/js/network/socketHandlers.js index 267270a..8d71e52 100644 --- a/html/js/network/socketHandlers.js +++ b/html/js/network/socketHandlers.js @@ -94,6 +94,7 @@ const SocketHandlers = { socket.on('payment_detected', this.onPaymentDetected); socket.on('show_payment_options', this.onShowPaymentOptions); socket.on('credits_update', this.onCreditsUpdate); + socket.on('user_count', this.onUserCount); // Block height handler socket.on('blockheight', this.onBlockHeight); @@ -704,6 +705,29 @@ const SocketHandlers = { } }, + onUserCount: function(data) { + if (!data || typeof data.count !== 'number') return; + SocketHandlers._updateUserCountDisplay(data.count); + }, + + _updateUserCountDisplay: function(count) { + let el = document.getElementById('userCountDisplay'); + if (!el) { + // Create display element next to connection status + const statusDiv = document.querySelector('.status') || document.getElementById('connectionStatus')?.parentElement; + if (statusDiv) { + el = document.createElement('div'); + el.id = 'userCountDisplay'; + el.style.cssText = 'font-size:12px;color:#0af;margin-top:2px;'; + statusDiv.appendChild(el); + } + } + if (el) { + const plural = count === 1 ? '' : 's'; + el.innerHTML = `👥 ${count} player${plural} online`; + } + }, + // ====== SPECTATOR HANDLERS ====== _spectatorMode: false, diff --git a/src/game/gameModeManager.js b/src/game/gameModeManager.js index 002ce87..71526b7 100644 --- a/src/game/gameModeManager.js +++ b/src/game/gameModeManager.js @@ -73,8 +73,8 @@ class GameModeManager { this.singleGamePrice = parseAtomicEnvValue(process.env.SINGLE_GAME_PRICE, this.singleGamePrice); this.creditsPackagePrice = parseAtomicEnvValue(process.env.CREDITS_PACKAGE_PRICE, this.creditsPackagePrice); this.creditsPerGameCost = parseAtomicEnvValue(process.env.CREDITS_PER_GAME, 1) || 1; - this.creditsPayoutEnabled = /^true$/i.test(process.env.CREDITS_PAYOUT_ENABLED || 'false'); - this.creditsPayoutBaseValue = this.singleGamePrice; + this.creditsPayoutEnabled = /^true$/i.test(process.env.CREDITS_PAYOUTS_ENABLED || process.env.CREDITS_PAYOUT_ENABLED || 'false'); + this.creditsPayoutBaseValue = parseAtomicEnvValue(process.env.CREDITS_PAYOUT_BASE, this.singleGamePrice); process.env.CREDITS_PER_GAME = String(this.creditsPerGameCost); const directEscape = Number(process.env.DIRECT_PAYOUT_ESCAPE); @@ -370,7 +370,7 @@ class GameModeManager { console.log(`🧮 Payout multipliers - direct: ${JSON.stringify(this.directPayoutMultipliers)}, credits: ${JSON.stringify(this.creditPayoutMultipliers)}`); console.log(`🔁 Mode availability - direct: ${this.directModeEnabled}, credits: ${this.creditsModeEnabled}, preferCreditsFirst: ${this.preferCreditsFirst}`); if (this.creditsPayoutEnabled) { - console.log('🎁 Credits payout mode ENABLED (will pay rewards in PAID_CREDITS).'); + console.log(`🎁 Credits payout mode ENABLED - base value: ${this.creditsPayoutBaseValue} atomic (~${this.formatAtomic(this.creditsPayoutBaseValue)} ${this.cryptoType})`); } console.log(`⚙️ Payments enabled: ${this.paymentsEnabled}`); } @@ -1011,6 +1011,9 @@ class GameModeManager { * Get game mode info for frontend */ getGameModeInfo() { + // Debug: Log credits payout base value being sent + console.log(`📤 getGameModeInfo: creditsPayoutBaseValue = ${this.creditsPayoutBaseValue} (${this.formatAtomic(this.creditsPayoutBaseValue)} ${this.cryptoType})`); + // Determine if we should show a testnet warning // Only for XMR on stagenet/testnet - WOW only has mainnet const showTestnetWarning = this.cryptoType === 'XMR' && this.isTestNetwork; diff --git a/src/network/broadcastManager.js b/src/network/broadcastManager.js index 047e5f4..7be5e43 100644 --- a/src/network/broadcastManager.js +++ b/src/network/broadcastManager.js @@ -8,10 +8,23 @@ class BroadcastManager { constructor(io) { this.io = io; this._lastBroadcastBlock = null; + this._lastUserCount = -1; } // ====== GLOBAL BROADCASTS (All Clients) ====== + /** + * Broadcast connected user count to all clients + */ + broadcastUserCount() { + const count = this.io.engine ? this.io.engine.clientsCount : 0; + // Only broadcast if count changed to avoid spam + if (count !== this._lastUserCount) { + this._lastUserCount = count; + this.io.emit('user_count', { count }); + } + } + /** * Broadcast block height to all connected clients * @param {number} blockHeight - Current block height diff --git a/src/network/connectionHandler.js b/src/network/connectionHandler.js index 1720574..1aa8c18 100644 --- a/src/network/connectionHandler.js +++ b/src/network/connectionHandler.js @@ -64,6 +64,9 @@ class ConnectionHandler { // Send current state this._sendConnectionStatus(socket); + // Broadcast updated user count to all clients + this.broadcastManager.broadcastUserCount(); + return { sessionInfo, memUser }; } catch (error) { @@ -112,6 +115,9 @@ class ConnectionHandler { // Clean up user records user.removeUser(socket.client.id); + // Broadcast updated user count to all clients + this.broadcastManager.broadcastUserCount(); + // Call additional cleanup if provided if (additionalCleanup && typeof additionalCleanup === 'function') { additionalCleanup(socket);