diff --git a/client/client.js b/client/client.js index 37f073d..bf7d8fe 100644 --- a/client/client.js +++ b/client/client.js @@ -193,24 +193,61 @@ async function readLoop() { } async function connectWT() { + // Check if WebTransport is available + if (typeof WebTransport === 'undefined') { + setStatus('ERROR: WebTransport not supported in this browser. Use Chrome/Edge 97+ or Firefox with flag enabled.'); + return; + } + const url = ui.url.value.trim(); const hashHex = ui.hash.value.trim(); + + if (!url) { + setStatus('ERROR: Please enter a server URL'); + return; + } + setStatus('connecting...'); + console.log('Connecting to:', url); + const opts = {}; if (hashHex) { - const bytes = new Uint8Array(hashHex.match(/.{1,2}/g).map(b => parseInt(b,16))); - opts.serverCertificateHashes = [{ algorithm: 'sha-256', value: bytes }]; + try { + const bytes = new Uint8Array(hashHex.match(/.{1,2}/g).map(b => parseInt(b,16))); + opts.serverCertificateHashes = [{ algorithm: 'sha-256', value: bytes }]; + console.log('Using certificate hash:', hashHex); + } catch (err) { + setStatus('ERROR: Invalid certificate hash format'); + return; + } + } else { + console.warn('No certificate hash provided - connection may fail for self-signed certs'); + } + + try { + const wt = new WebTransport(url, opts); + await wt.ready; + transport = wt; + writer = wt.datagrams.writable.getWriter(); + setStatus('connected to server'); + console.log('WebTransport connected successfully'); + + readLoop(); + requestAnimationFrame(render); + + // Send JOIN immediately (spectator → player upon space handled below) + const pkt = buildJoin(1, nextSeq(), ui.name.value.trim()); + await writer.write(pkt); + } catch (err) { + console.error('WebTransport connection failed:', err); + if (err.message.includes('certificate')) { + setStatus('ERROR: Certificate validation failed. Check cert hash or use valid CA cert.'); + } else if (err.message.includes('net::')) { + setStatus('ERROR: Network error - is server running on ' + url + '?'); + } else { + setStatus('ERROR: ' + err.message); + } } - const wt = new WebTransport(url, opts); - await wt.ready; - transport = wt; - writer = wt.datagrams.writable.getWriter(); - setStatus('connected'); - readLoop(); - requestAnimationFrame(render); - // Send JOIN immediately (spectator → player upon space handled below) - const pkt = buildJoin(1, nextSeq(), ui.name.value.trim()); - await writer.write(pkt); } function dirFromKey(e) { @@ -229,7 +266,47 @@ async function onKey(e) { try { await writer.write(pkt); } catch (err) { /* ignore */ } } +// Auto-configure on page load +async function autoConfigureFromServer() { + try { + // Try to fetch cert hash from the static server + const response = await fetch('/cert-hash.json'); + if (!response.ok) { + setStatus('Auto-config unavailable, please enter manually'); + return; + } + const config = await response.json(); + + // Auto-populate fields + if (config.wtUrl) { + // Use the hostname from browser but with the WT port from server + const hostname = window.location.hostname || '127.0.0.1'; + const wtPort = config.wtPort || 4433; + ui.url.value = `https://${hostname}:${wtPort}/`; + } + if (config.sha256) { + ui.hash.value = config.sha256; + } + + setStatus('Auto-configured from server'); + console.log('Auto-configured:', config); + } catch (err) { + console.warn('Auto-config failed:', err); + // Fallback: just populate URL from browser location + const hostname = window.location.hostname || '127.0.0.1'; + ui.url.value = `https://${hostname}:4433/`; + setStatus('Manual configuration required'); + } +} + ui.connect.onclick = () => { connectWT().catch(e => setStatus('connect failed: ' + e)); }; window.addEventListener('keydown', onKey); window.addEventListener('resize', render); +// Auto-configure when page loads +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', autoConfigureFromServer); +} else { + autoConfigureFromServer(); +} + diff --git a/client/index.html b/client/index.html index 26c48bb..b97783b 100644 --- a/client/index.html +++ b/client/index.html @@ -15,16 +15,15 @@