/** * Socket event handlers for the Wownerogue game */ const SocketHandlers = { _initialized: false, _didConnect: false, _setBannerStatus: function(text, color) { const el = $('#statusValue'); if (!el.length) return; el.text(text); if (color) el.css('color', color); }, _hasPayoutAddress: false, _creditsBalance: 0, _gameMode: null, // set from the server's game-modes event; was previously declared // twice in this object literal (the later `null` silently won) _directPayoutsEnabled: false, _paymentsEnabled: false, payoutAddressRequired: function() { if (this._gameMode === 'PAID_SINGLE' && this._directPayoutsEnabled) return true; if (this._gameMode === 'PAID_CREDITS' && this._creditsPayoutsEnabled) return true; return false; }, canAffordGame: function() { if (this._gameMode === 'FREE') return true; if (this._gameMode === 'PAID_SINGLE') return true; // Payment will be requested if (this._gameMode === 'PAID_CREDITS') { return this._creditsBalance >= (this._creditsPerGame || 1); } return false; }, _updateAddressButtonStatus: function(hasAddress) { const $btn = $('#manageAddressButton'); this._hasPayoutAddress = !!hasAddress; if (!$btn.length) return; if (hasAddress) { // Address is set - show green indicator $btn.css({ 'background': '#053655', 'color': '#0ff', 'border-color': '#0ff' }); $btn.html('✅ Payout Address Set'); } else { // No address - show warning indicator (yellow/orange) $btn.css({ 'background': '#553300', 'color': '#ffa500', 'border-color': '#ffa500' }); $btn.html('⚠️ Set Payout Address'); } }, init: function() { if (this._initialized) { return; } if (!window.socket) { console.error("Socket not available!"); return; } this.registerEventHandlers(); this._initialized = true; // Delegated handlers for proof copy buttons $(document).on('click', '.copy-hash-btn', function() { const hash = $(this).data('hash'); if (hash) { SocketHandlers._copyToClipboard(hash, $(this)); } }); $(document).on('click', '.copy-seed-btn', function() { const seed = $(this).data('seed'); if (seed) { SocketHandlers._copyToClipboard(seed, $(this)); } }); // If the low-level socket connected before handlers were registered, emulate onConnect. if (window.socket && window.socket.connected) { this.onConnect(); } }, _copyToClipboard: function(text, $btn) { if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(function() { const origText = $btn.text(); $btn.text('Copied!'); setTimeout(function() { $btn.text(origText); }, 1500); }); } else { // Fallback const $temp = $(''); $('body').append($temp); $temp.val(text).select(); document.execCommand('copy'); $temp.remove(); const origText = $btn.text(); $btn.text('Copied!'); setTimeout(function() { $btn.text(origText); }, 1500); } }, registerEventHandlers: function() { // Connection handlers socket.on('connect', this.onConnect); socket.on('welcome', this.onWelcome); socket.on('session_token', this.onSessionToken); socket.on('session_resumed', this.onSessionResumed); socket.on('message', this.onMessage); socket.on('status_update', this.onStatusUpdate); socket.on('chat_broadcast', this.onChatBroadcast); socket.on('chat_history', this.onChatHistory); socket.on('chat_deleted', this.onChatDeleted); socket.on('chat_error', this.onChatError); // Game state handlers socket.on('waiting_status', this.onWaitingStatus); socket.on('queue_joined', this.onQueueJoined); socket.on('game_start', this.onGameStart); socket.on('game_update', this.onGameUpdate); socket.on('game_over', this.onGameOver); // Discrete in-run events. Multi-level DESCEND is the big one — without this, taking the // stairs down silently dumped the player at a new entrance and read as a bug. socket.on('game_event', function (data) { if (!data || !data.event) return; var $m = $('#messages'); if (data.event === 'descend') { var lvl = (data.depth && data.maxDepth) ? ('Level ' + data.depth + ' of ' + data.maxDepth + ' — ') : ''; $m.append($('
' + shortHash + ' ' +
''
);
$('#messages').append($proofMsg);
// Store for later verification display
SocketHandlers._currentGameProof = data.proof;
}
if (typeof Game !== 'undefined' && Game.stopWaitingScreen) {
Game.stopWaitingScreen();
}
if (!data) {
$('#messages').append($('' + shortSeed + ' ' +
'' + shortCommitment + '${message}