diff --git a/Dockerfile b/Dockerfile index 67c27eb..0d1e006 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ # Stage 1: Builder FROM golang:1.25.5-alpine AS builder -# Build-Dependencies -RUN apk add --no-cache git +# Build-Dependencies (bash für das Cache-Version-Skript) +RUN apk add --no-cache git bash sed WORKDIR /app @@ -21,6 +21,10 @@ RUN if [ ! -f cmd/client/web/assets/assets.json ]; then \ echo "✅ Assets bereits vorhanden"; \ fi +# Cache-Version aktualisieren (für Browser-Cache-Busting) +RUN chmod +x scripts/cache-version.sh && \ + ./scripts/cache-version.sh + # Server binary bauen RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags="-w -s" -o server ./cmd/server diff --git a/cmd/client/connection_wasm.go b/cmd/client/connection_wasm.go index c2aaa76..d986174 100644 --- a/cmd/client/connection_wasm.go +++ b/cmd/client/connection_wasm.go @@ -81,8 +81,15 @@ func (g *Game) connectToServer() { } g.stateMutex.Lock() + oldPlayerCount := len(g.gameState.Players) g.gameState = state + newPlayerCount := len(g.gameState.Players) g.stateMutex.Unlock() + + // Lobby-UI aktualisieren wenn sich Spieleranzahl geändert hat + if oldPlayerCount != newPlayerCount { + g.sendLobbyUpdateToJS() + } } case "leaderboard_response": @@ -192,7 +199,8 @@ func (g *Game) sendInput(input game.ClientInput) { // startGame sendet den Start-Befehl über WebSocket func (g *Game) startGame() { - myID := g.getMyPlayerID() + // PlayerID ist der playerName (Server verwendet req.Name als PlayerID) + myID := g.playerName msg := WebSocketMessage{ Type: "start", Payload: game.StartRequest{ diff --git a/cmd/client/main_wasm.go b/cmd/client/main_wasm.go index c8c4cb1..4dfe4be 100644 --- a/cmd/client/main_wasm.go +++ b/cmd/client/main_wasm.go @@ -18,6 +18,9 @@ func main() { // JavaScript Bridge registrieren (für HTML-Menü Kommunikation) game.setupJavaScriptBridge() + // Signal an JavaScript dass WASM vollständig geladen ist + game.notifyWasmReady() + // Spiel ohne eigenes Menü starten - HTML übernimmt das Menü // Das Spiel wartet im Hintergrund bis startGame() von JavaScript aufgerufen wird log.Println("⏳ Warte auf Start-Signal vom HTML-Menü...") diff --git a/cmd/client/wasm_bridge.go b/cmd/client/wasm_bridge.go index 0a8d78d..cc46f7a 100644 --- a/cmd/client/wasm_bridge.go +++ b/cmd/client/wasm_bridge.go @@ -10,6 +10,14 @@ import ( "time" ) +// notifyWasmReady signalisiert JavaScript dass WASM vollständig geladen ist +func (g *Game) notifyWasmReady() { + if readyFunc := js.Global().Get("onWasmReady"); !readyFunc.IsUndefined() { + readyFunc.Invoke() + log.Println("✅ WASM Ready-Signal an JavaScript gesendet") + } +} + // setupJavaScriptBridge registriert JavaScript-Funktionen für HTML-Menü Interaktion func (g *Game) setupJavaScriptBridge() { // startGame(mode, playerName, roomID, teamName, isHost) @@ -107,6 +115,8 @@ func (g *Game) setupJavaScriptBridge() { js.Global().Set("setTeamName_WASM", setTeamNameFunc) log.Println("✅ JavaScript Bridge registriert") + log.Printf("🔍 window.startGame defined: %v", !js.Global().Get("startGame").IsUndefined()) + log.Printf("🔍 window.startGameFromLobby_WASM defined: %v", !js.Global().Get("startGameFromLobby_WASM").IsUndefined()) } // Leaderboard an JavaScript senden diff --git a/cmd/client/web/game.js b/cmd/client/web/game.js index 631ac8d..4f522d3 100644 --- a/cmd/client/web/game.js +++ b/cmd/client/web/game.js @@ -216,27 +216,65 @@ function requestLeaderboardDirect() { setTimeout(() => clearInterval(checkAndRequest), 3000); } +// Callback von WASM wenn vollständig geladen +window.onWasmReady = function() { + console.log('✅ WASM fully initialized'); + wasmReady = true; + + // Switch to menu state + setUIState(UIState.MENU); + + // Enable all start buttons + enableStartButtons(); + + // Load initial leaderboard via direct WebSocket + setTimeout(() => { + requestLeaderboardDirect(); + }, 500); +}; + +// Cache Management - Version wird bei jedem Build aktualisiert +const CACHE_VERSION = 1767553871926; // Wird durch Build-Prozess ersetzt + +// Fetch mit Cache-Busting +async function fetchWithCache(url) { + const cacheBustedUrl = `${url}?v=${CACHE_VERSION}`; + console.log(`📦 Loading: ${cacheBustedUrl}`); + + try { + const response = await fetch(cacheBustedUrl, { + cache: 'no-cache', // Immer vom Server holen wenn Version neu ist + headers: { + 'Cache-Control': 'no-cache, no-store, must-revalidate', + 'Pragma': 'no-cache' + } + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + return response; + } catch (err) { + console.error(`❌ Failed to fetch ${url}:`, err); + throw err; + } +} + // Initialize WASM async function initWASM() { const go = new Go(); try { - const result = await WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject); + console.log(`🚀 Loading WASM (Cache Version: ${CACHE_VERSION})...`); + + // WASM mit Cache-Busting laden + const response = await fetchWithCache("main.wasm"); + const result = await WebAssembly.instantiateStreaming(response, go.importObject); + go.run(result.instance); - wasmReady = true; - - // Switch to menu state - setUIState(UIState.MENU); - - // Enable all start buttons - enableStartButtons(); - - console.log('✅ WASM loaded successfully'); - - // Load initial leaderboard via direct WebSocket - setTimeout(() => { - requestLeaderboardDirect(); - }, 500); + // WICHTIG: wasmReady wird erst in onWasmReady() gesetzt, nicht hier! + console.log('✅ WASM runtime started, waiting for full initialization...'); } catch (err) { console.error('❌ Failed to load WASM:', err); document.getElementById('loading').innerHTML = '

Fehler beim Laden: ' + err.message + '

'; @@ -322,7 +360,10 @@ function createRoom() { // Trigger WASM game start (im Hintergrund) if (window.startGame) { + console.log('🎮 Calling window.startGame with:', 'coop', playerName, roomID, teamName, true); window.startGame('coop', playerName, roomID, teamName, true); + } else { + console.error('❌ window.startGame is not defined!'); } console.log('🎮 Room created:', roomID); @@ -358,7 +399,10 @@ function joinRoom() { // Trigger WASM game start (im Hintergrund) if (window.startGame) { + console.log('🎮 Calling window.startGame with:', 'coop', playerName, roomID, teamName, false); window.startGame('coop', playerName, roomID, teamName, false); + } else { + console.error('❌ window.startGame is not defined!'); } console.log('🎮 Joining room:', roomID); diff --git a/cmd/client/web/index.html b/cmd/client/web/index.html index 3c7e72c..3320ff4 100644 --- a/cmd/client/web/index.html +++ b/cmd/client/web/index.html @@ -289,8 +289,12 @@ - - +