mirror of
https://github.com/Such-Software/wownerogue.git
synced 2026-10-17 22:31:26 +02:00
295 lines
18 KiB
HTML
295 lines
18 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>Wownerogue - A Wownero Roguelike</title>
|
||
<link rel="stylesheet" type="text/css" href="styles/stylesheet.css">
|
||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||
|
||
<!-- Socket.io -->
|
||
<script src="https://cdn.socket.io/4.8.1/socket.io.min.js"></script>
|
||
|
||
<!-- Initialize socket with resume token (for persistent anonymous session) -->
|
||
<script>
|
||
(function(){
|
||
let opts = {};
|
||
window._localStorageAvailable = false;
|
||
try {
|
||
// Test localStorage availability (fails in private browsing on some browsers)
|
||
localStorage.setItem('_test', '1');
|
||
localStorage.removeItem('_test');
|
||
window._localStorageAvailable = true;
|
||
const existing = localStorage.getItem('wownerogue_token');
|
||
if (existing) {
|
||
opts.query = { resumeToken: existing };
|
||
}
|
||
} catch(_) {
|
||
window._localStorageAvailable = false;
|
||
console.warn('localStorage unavailable - session will not persist');
|
||
}
|
||
window.socket = io(opts);
|
||
// Show warning if localStorage unavailable (after DOM ready)
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
if (!window._localStorageAvailable) {
|
||
const warn = document.getElementById('sessionWarning');
|
||
if (warn) warn.style.display = 'inline';
|
||
}
|
||
// Fetch server config and populate hosted-by footer
|
||
fetch('/api/game-modes')
|
||
.then(function(res) { return res.json(); })
|
||
.then(function(data) {
|
||
if (data.hostedBy && data.hostedBy.url) {
|
||
var container = document.getElementById('hosted-by-container');
|
||
if (container) {
|
||
container.innerHTML = ' | Hosted by: <a href="' +
|
||
data.hostedBy.url + '" target="_blank" rel="noopener" style="color:#888;">' +
|
||
(data.hostedBy.name || data.hostedBy.url) + '</a>';
|
||
}
|
||
}
|
||
})
|
||
.catch(function() { /* ignore errors */ });
|
||
});
|
||
})();
|
||
</script>
|
||
|
||
<!-- Core libraries -->
|
||
<script src="js/lib/jquery-3.4.1.min.js"></script>
|
||
<script src="js/lib/rot.min.js"></script>
|
||
<script src="js/core/options.js"></script>
|
||
<script src="js/ui/teletype.js"></script>
|
||
|
||
<!-- Modular game components (order matters for dependencies) -->
|
||
<script src="js/display/displayManager.js"></script>
|
||
<script src="js/display/waitingScreenAnimator.js"></script>
|
||
<script src="js/display/screenManager.js"></script>
|
||
<script src="js/display/renderEngine.js"></script>
|
||
<script src="js/core/gameState.js"></script>
|
||
<script src="js/core/game.js"></script>
|
||
|
||
<!-- Other modules -->
|
||
<script src="js/ui/ui.js"></script>
|
||
<script src="js/ui/paymentUI.js"></script>
|
||
<script src="js/ui/audioAlerts.js"></script>
|
||
<script src="js/ui/addressModal.js"></script>
|
||
<script src="js/ui/transactionHistory.js"></script>
|
||
<script src="js/network/socketHandlers.js"></script>
|
||
<script src="js/input/inputHandler.js"></script>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<!-- Header area -->
|
||
<header class="banner">
|
||
<div id="staticbanner">
|
||
<span id="banner"></span><span id="bannercursor">|</span>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Status area for block height -->
|
||
<div class="status">
|
||
<div id="blockHeight">Block Height: <span id="heightValue">Loading...</span></div>
|
||
<div id="connectionStatus">Status: <span id="statusValue">Connecting...</span></div>
|
||
<button id="startButton" style="background: #0a5c0a; color: #ff0; border: 2px solid #0f0; padding: 8px 16px; font-weight: bold; cursor: pointer; margin-top: 5px; display: none;">
|
||
🎮 START GAME
|
||
</button>
|
||
<button id="watchGamesButton" style="background: #053655; color: #0af; border: 2px solid #0af; padding: 8px 16px; font-weight: bold; cursor: pointer; margin-top: 5px; margin-left: 10px;">
|
||
👁️ WATCH GAMES
|
||
</button>
|
||
<button id="shopButton" style="background: #004400; color: #0f0; border: 2px solid #0f0; padding: 8px 16px; font-weight: bold; cursor: pointer; margin-top: 5px; margin-left: 10px; display: none;">
|
||
🛒 SHOP
|
||
</button>
|
||
<button id="animationToggleButton" style="background: #5c5c0a; color: #ff0; border: 2px solid #aa0; padding: 6px 12px; font-weight: bold; cursor: pointer; margin-top: 5px; margin-left: 10px; display: none;">
|
||
🎬 DISABLE ANIMATION
|
||
</button>
|
||
<div style="margin-top:6px; font-size:11px; color:#ccc; display:flex; align-items:center; gap:4px;">
|
||
<label style="cursor:pointer; display:flex; align-items:center; gap:4px;">
|
||
<input type="checkbox" id="audioAlertsToggle" style="cursor:pointer;"> Audio Alerts
|
||
</label>
|
||
<button id="historyButton" style="margin-left:auto; background:#1a1a4d; color:#c4b5fd; border:1px solid #8b5cf6; padding:4px 10px; font-size:11px; cursor:pointer; border-radius:3px;" title="View your payment and payout history">📜 History</button>
|
||
<button id="manageAddressButton" style="background:#053655; color:#0ff; border:1px solid #0ff; padding:4px 10px; font-size:11px; cursor:pointer; border-radius:3px;" title="Your payout address and credits are tied to a browser session token. Clearing cookies/localStorage or using incognito mode will lose your session.">⚙️ Manage Payout Address</button>
|
||
<span id="sessionWarning" style="display:none; color:#f59e0b; font-size:10px; margin-left:6px;" title="Private browsing or localStorage blocked - your session won't persist">⚠️ Session not saved</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Payment System UI -->
|
||
<div id="payment-ui" class="payment-section" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2000; background: rgba(0,20,0,0.95); border: 2px solid #0f0; padding: 20px; color: #0f0; min-width: 400px; max-width: 500px; box-shadow: 0 0 20px rgba(0,255,0,0.2);">
|
||
<div class="payment-header">
|
||
<strong>🎮 Choose How to Play</strong>
|
||
<button id="close-payment" style="float: right; background: #500; color: #f00; border: 1px solid #f00; padding: 2px 6px; cursor: pointer;">✕</button>
|
||
</div>
|
||
|
||
<!-- Dynamic game mode options populated by PaymentUI.js -->
|
||
<div class="game-modes" style="margin: 15px 0;">
|
||
<div style="color: #888; text-align: center; padding: 20px;">Loading payment options...</div>
|
||
</div>
|
||
|
||
<div id="credits-display" style="margin: 10px 0; display: none;">
|
||
<strong>Credits remaining: <span id="credits-count">0</span></strong>
|
||
</div>
|
||
|
||
<div id="payment-details" style="display: none; margin: 15px 0;">
|
||
<div style="margin-bottom: 5px;"><strong>Payment Required:</strong></div>
|
||
<div style="font-size: 1.2em; margin-bottom: 10px;">Amount: <span id="payment-amount" style="color: #ff0;">0</span></div>
|
||
<div style="margin-bottom: 5px;">Address:</div>
|
||
<input id="payment-address" type="text" readonly style="width: 100%; background: #000; color: #0f0; border: 1px solid #0f0; padding: 8px; font-family: monospace; margin-bottom: 10px;">
|
||
<div style="margin: 10px 0; display: flex; gap: 10px;">
|
||
<button id="copy-address" style="flex: 1; background: #050; color: #0f0; border: 1px solid #0f0; padding: 8px; cursor: pointer;">📋 Copy Address</button>
|
||
<button id="check-payment" style="flex: 1; background: #005; color: #0f0; border: 1px solid #0f0; padding: 8px; cursor: pointer;">🔄 Check Payment</button>
|
||
</div>
|
||
<div id="payment-status" style="margin: 10px 0; font-weight: bold; text-align: center;"></div>
|
||
<div style="font-size: 0.8em; color: #aaa; text-align: center; margin-top: 15px; border-top: 1px solid #333; padding-top: 10px;">
|
||
ℹ️ You can close this window. The payment information is also available in the sidebar/chat area.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Transaction History Panel -->
|
||
<div id="history-panel" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2000; background: rgba(10,10,30,0.98); border: 2px solid #8b5cf6; padding: 20px; color: #e0e0e0; min-width: 500px; max-width: 600px; max-height: 80vh; overflow-y: auto; box-shadow: 0 0 20px rgba(139,92,246,0.3); border-radius: 8px;">
|
||
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px; border-bottom:1px solid #444; padding-bottom:10px;">
|
||
<strong style="font-size:1.2em; color:#c4b5fd;">📜 Transaction History</strong>
|
||
<button id="close-history" style="background: #500; color: #f00; border: 1px solid #f00; padding: 4px 8px; cursor: pointer; border-radius:3px;">✕</button>
|
||
</div>
|
||
|
||
<!-- Summary Section -->
|
||
<div id="history-summary" style="display:grid; grid-template-columns:1fr 1fr; gap:15px; margin-bottom:20px;">
|
||
<div style="background:#1a1a3d; padding:12px; border-radius:6px; border:1px solid #4c1d95;">
|
||
<div style="color:#888; font-size:0.85em;">Total Received</div>
|
||
<div id="total-received" style="color:#4ade80; font-size:1.3em; font-weight:bold;">0 WOW</div>
|
||
</div>
|
||
<div style="background:#1a1a3d; padding:12px; border-radius:6px; border:1px solid #4c1d95;">
|
||
<div style="color:#888; font-size:0.85em;">Total Payments</div>
|
||
<div id="total-payments" style="color:#60a5fa; font-size:1.3em; font-weight:bold;">0</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tabs -->
|
||
<div style="display:flex; gap:10px; margin-bottom:15px;">
|
||
<button class="history-tab active" data-tab="payouts" style="flex:1; padding:8px; background:#4c1d95; color:#fff; border:none; cursor:pointer; border-radius:4px;">💰 Payouts</button>
|
||
<button class="history-tab" data-tab="payments" style="flex:1; padding:8px; background:#333; color:#aaa; border:none; cursor:pointer; border-radius:4px;">💳 Payments</button>
|
||
</div>
|
||
|
||
<!-- Payouts Tab Content -->
|
||
<div id="payouts-content" class="history-content">
|
||
<div id="payouts-list" style="max-height:300px; overflow-y:auto;"></div>
|
||
<div id="payouts-empty" style="text-align:center; color:#666; padding:20px;">No payouts yet</div>
|
||
</div>
|
||
|
||
<!-- Payments Tab Content -->
|
||
<div id="payments-content" class="history-content" style="display:none;">
|
||
<div id="payments-list" style="max-height:300px; overflow-y:auto;"></div>
|
||
<div id="payments-empty" style="text-align:center; color:#666; padding:20px;">No payments yet</div>
|
||
</div>
|
||
|
||
<div style="margin-top:15px; font-size:0.8em; color:#666; text-align:center;">
|
||
History is tied to your browser session
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Game display -->
|
||
<div id="game-display" class="rotdis"></div>
|
||
|
||
<!-- Debug display area (hidden in production) -->
|
||
<div id="debug-display" style="display: none; background: rgba(0,0,0,0.8); color: #0f0; font-family: monospace; font-size: 12px; padding: 10px; margin: 5px; border: 1px solid #333; max-height: 200px; overflow-y: auto;">
|
||
<div><strong>Debug Information:</strong></div>
|
||
<div id="debug-content">Ready...</div>
|
||
</div>
|
||
|
||
<!-- Chat messages area -->
|
||
<div class="chat-container">
|
||
<div id="messageBox">
|
||
<ul id="messages"></ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Chat input in its own row -->
|
||
<div class="input-container">
|
||
<form id="chatForm" action="">
|
||
<input id="chatInput" autocomplete="off" placeholder="Type a command..." />
|
||
<button type="submit">Send</button>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Footer -->
|
||
<div class="footer">
|
||
<span>Wownero Roguelike v0.1.0 | Use WASD or arrow keys to move</span>
|
||
<span id="hosted-by-container"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Address management modal -->
|
||
<div id="addressModal" class="modal-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="addressModalTitle">
|
||
<div class="modal-content">
|
||
<button type="button" class="modal-close" id="addressModalClose" aria-label="Close">✕</button>
|
||
<h2 id="addressModalTitle">Manage Payout Address</h2>
|
||
<p class="modal-description">Enter your Wownero (WOW) or Monero (XMR) address below. This will be used for payouts when you escape.</p>
|
||
<p class="modal-description" style="font-size:11px; color:#888; margin-top:8px; padding:6px; background:rgba(255,200,0,0.1); border-radius:4px;">💡 <strong>Session Info:</strong> Your address and credits are tied to a browser session token stored locally. They will persist across page refreshes but will be lost if you clear cookies, use incognito mode, or switch browsers.</p>
|
||
<form id="addressModalForm">
|
||
<label for="addressModalInput" class="modal-label">Payout Address</label>
|
||
<textarea id="addressModalInput" autocomplete="off" spellcheck="false" rows="3" placeholder="Paste your payout address here"></textarea>
|
||
<div class="modal-actions">
|
||
<button type="submit" id="addressModalSave">Save Address</button>
|
||
<button type="button" id="addressModalCancel">Cancel</button>
|
||
</div>
|
||
<div id="addressModalFeedback" class="modal-feedback" aria-live="polite"></div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Browser info panel -->
|
||
<div id="browser-info" style="position: fixed; right: 10px; top: 40px; background: rgba(0,0,0,0.7); color: #0f0; padding: 5px; font-family: monospace; font-size: 12px; z-index: 1000; display: none;">
|
||
<div>Browser: <span id="browser-name">checking...</span></div>
|
||
<div>Display: <span id="display-status">checking...</span></div>
|
||
<button onclick="document.getElementById('browser-info').style.display='none'" style="margin-top: 5px; background: #333; border: 1px solid #666; color: white; font-size: 10px; padding: 2px 4px;">
|
||
Close
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Initialize game when ready -->
|
||
<script>
|
||
$(document).ready(function() {
|
||
console.log("Document ready - initializing modules...");
|
||
console.log("Socket available:", !!window.socket);
|
||
console.log("Game object available:", typeof Game !== 'undefined');
|
||
console.log("SocketHandlers available:", typeof SocketHandlers !== 'undefined');
|
||
console.log("UI available:", typeof UI !== 'undefined');
|
||
console.log("InputHandler available:", typeof InputHandler !== 'undefined');
|
||
|
||
// Small delay to ensure all modules are fully loaded
|
||
setTimeout(function() {
|
||
// Initialize Game first
|
||
if (typeof Game !== 'undefined') {
|
||
console.log("Initializing Game...");
|
||
const gameInitResult = Game.init();
|
||
console.log("Game initialization result:", gameInitResult);
|
||
|
||
// Ensure welcome screen is shown after a brief delay
|
||
setTimeout(function() {
|
||
if (gameInitResult && typeof ScreenManager !== 'undefined' && ScreenManager.drawWelcomeScreen) {
|
||
console.log("Ensuring welcome screen is drawn...");
|
||
ScreenManager.drawWelcomeScreen();
|
||
}
|
||
}, 50);
|
||
} else {
|
||
console.error("Game object not found!");
|
||
}
|
||
|
||
// Initialize SocketHandlers (CRITICAL for receiving game_start events!)
|
||
if (typeof SocketHandlers !== 'undefined') {
|
||
console.log("Initializing SocketHandlers...");
|
||
// IMPORTANT: AudioAlerts patches SocketHandlers methods, so must init BEFORE socket bindings
|
||
if (typeof AudioAlerts !== 'undefined') { AudioAlerts.init(); }
|
||
SocketHandlers.init();
|
||
} else {
|
||
console.error("SocketHandlers object not found!");
|
||
}
|
||
|
||
// Initialize InputHandler
|
||
if (typeof InputHandler !== 'undefined') {
|
||
console.log("Initializing InputHandler...");
|
||
InputHandler.init();
|
||
} else {
|
||
console.error("InputHandler object not found!");
|
||
}
|
||
}, 100); // 100ms delay to ensure everything is loaded
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |