Add WebAssembly support for assets and chunks, implement gameover screen rendering, and enhance server gameplay logic with dynamic speeds, team naming, and score components.
This commit is contained in:
@@ -93,7 +93,25 @@ func main() {
|
||||
log.Printf("🔍 RAW NATS: Nachricht empfangen auf game.join: %s", string(m.Data))
|
||||
})
|
||||
|
||||
// 4. HANDLER: INPUT
|
||||
// 4. HANDLER: GAME START
|
||||
_, _ = ec.Subscribe("game.start", func(req *game.StartRequest) {
|
||||
log.Printf("▶️ START empfangen: RoomID=%s", req.RoomID)
|
||||
|
||||
mu.RLock()
|
||||
room, exists := rooms[req.RoomID]
|
||||
mu.RUnlock()
|
||||
|
||||
if exists {
|
||||
room.Mutex.Lock()
|
||||
room.StartCountdown()
|
||||
room.Mutex.Unlock()
|
||||
log.Printf("🎮 Raum '%s' Countdown gestartet", req.RoomID)
|
||||
} else {
|
||||
log.Printf("❌ Raum '%s' nicht gefunden", req.RoomID)
|
||||
}
|
||||
})
|
||||
|
||||
// 5. HANDLER: INPUT
|
||||
_, _ = ec.Subscribe("game.input", func(input *game.ClientInput) {
|
||||
mu.RLock()
|
||||
room, ok := playerSessions[input.PlayerID]
|
||||
@@ -104,23 +122,40 @@ func main() {
|
||||
}
|
||||
})
|
||||
|
||||
// 5. HANDLER: SCORE SUBMISSION
|
||||
// 6. HANDLER: SCORE SUBMISSION
|
||||
_, _ = ec.Subscribe("score.submit", func(submission *game.ScoreSubmission) {
|
||||
log.Printf("📊 Score-Submission: %s (%s) mit %d Punkten", submission.PlayerName, submission.PlayerCode, submission.Score)
|
||||
added := server.GlobalLeaderboard.AddScore(submission.PlayerName, submission.PlayerCode, submission.Score)
|
||||
// Verwende Team-Name wenn vorhanden (Coop-Mode), sonst Player-Name (Solo-Mode)
|
||||
displayName := submission.PlayerName
|
||||
if submission.TeamName != "" {
|
||||
displayName = submission.TeamName
|
||||
}
|
||||
|
||||
log.Printf("📊 Score-Submission: %s (%s) mit %d Punkten [Mode: %s]", displayName, submission.PlayerCode, submission.Score, submission.Mode)
|
||||
added, proofCode := server.GlobalLeaderboard.AddScore(displayName, submission.PlayerCode, submission.Score)
|
||||
if added {
|
||||
log.Printf("✅ Score akzeptiert für %s", submission.PlayerName)
|
||||
log.Printf("✅ Score akzeptiert für %s (Proof: %s)", displayName, proofCode)
|
||||
|
||||
// Sende Response zurück über NATS
|
||||
response := game.ScoreSubmissionResponse{
|
||||
Success: true,
|
||||
ProofCode: proofCode,
|
||||
Score: submission.Score,
|
||||
}
|
||||
// Sende an player-spezifischen Channel
|
||||
channel := "score.response." + submission.PlayerCode
|
||||
ec.Publish(channel, &response)
|
||||
log.Printf("📤 Proof-Code gesendet an Channel: %s", channel)
|
||||
}
|
||||
})
|
||||
|
||||
// 6. HANDLER: LEADERBOARD REQUEST (alt, für Kompatibilität)
|
||||
// 7. HANDLER: LEADERBOARD REQUEST (alt, für Kompatibilität)
|
||||
_, _ = ec.Subscribe("leaderboard.get", func(subject, reply string, _ *struct{}) {
|
||||
top10 := server.GlobalLeaderboard.GetTop10()
|
||||
log.Printf("📊 Leaderboard-Request beantwortet: %d Einträge", len(top10))
|
||||
ec.Publish(reply, top10)
|
||||
})
|
||||
|
||||
// 7. HANDLER: LEADERBOARD REQUEST (neu, für WebSocket-Gateway)
|
||||
// 8. HANDLER: LEADERBOARD REQUEST (neu, für WebSocket-Gateway)
|
||||
_, _ = ec.Subscribe("leaderboard.request", func(req *game.LeaderboardRequest) {
|
||||
top10 := server.GlobalLeaderboard.GetTop10()
|
||||
log.Printf("📊 Leaderboard-Request (Mode=%s): %d Einträge", req.Mode, len(top10))
|
||||
@@ -137,7 +172,7 @@ func main() {
|
||||
|
||||
log.Println("✅ Server bereit. Warte auf Spieler...")
|
||||
|
||||
// 5. WEBSOCKET-GATEWAY STARTEN (für Browser-Clients)
|
||||
// 9. WEBSOCKET-GATEWAY STARTEN (für Browser-Clients)
|
||||
go StartWebSocketGateway("8080", ec)
|
||||
|
||||
// Block forever
|
||||
@@ -145,7 +180,7 @@ func main() {
|
||||
}
|
||||
|
||||
func loadServerAssets(w *game.World) {
|
||||
assetDir := "./cmd/client/assets"
|
||||
assetDir := "./cmd/client/web/assets"
|
||||
chunkDir := filepath.Join(assetDir, "chunks")
|
||||
|
||||
// Manifest laden
|
||||
|
||||
@@ -26,13 +26,15 @@ type WebSocketMessage struct {
|
||||
|
||||
// WebSocketClient repräsentiert einen verbundenen WebSocket-Client
|
||||
type WebSocketClient struct {
|
||||
conn *websocket.Conn
|
||||
natsConn *nats.EncodedConn
|
||||
playerID string
|
||||
roomID string
|
||||
send chan []byte
|
||||
mutex sync.Mutex
|
||||
subUpdates *nats.Subscription
|
||||
conn *websocket.Conn
|
||||
natsConn *nats.EncodedConn
|
||||
playerID string
|
||||
playerCode string
|
||||
roomID string
|
||||
send chan []byte
|
||||
mutex sync.Mutex
|
||||
subUpdates *nats.Subscription
|
||||
subScoreResp *nats.Subscription
|
||||
}
|
||||
|
||||
// handleWebSocket verwaltet eine WebSocket-Verbindung
|
||||
@@ -62,6 +64,9 @@ func (c *WebSocketClient) readPump() {
|
||||
if c.subUpdates != nil {
|
||||
c.subUpdates.Unsubscribe()
|
||||
}
|
||||
if c.subScoreResp != nil {
|
||||
c.subScoreResp.Unsubscribe()
|
||||
}
|
||||
c.conn.Close()
|
||||
log.Printf("🔌 WebSocket-Client getrennt: %s", c.conn.RemoteAddr())
|
||||
}()
|
||||
@@ -208,6 +213,35 @@ func (c *WebSocketClient) handleMessage(msg WebSocketMessage) {
|
||||
}
|
||||
|
||||
log.Printf("📊 WebSocket Score-Submit: Player=%s, Score=%d", submit.PlayerCode, submit.Score)
|
||||
|
||||
// Speichere PlayerCode und subscribe auf Response-Channel
|
||||
if c.playerCode == "" && submit.PlayerCode != "" {
|
||||
c.playerCode = submit.PlayerCode
|
||||
|
||||
// Subscribe auf Score-Response für diesen Spieler
|
||||
responseChannel := "score.response." + submit.PlayerCode
|
||||
sub, err := c.natsConn.Subscribe(responseChannel, func(resp *game.ScoreSubmissionResponse) {
|
||||
// ScoreSubmissionResponse an WebSocket-Client senden
|
||||
data, _ := json.Marshal(map[string]interface{}{
|
||||
"type": "score_response",
|
||||
"payload": resp,
|
||||
})
|
||||
select {
|
||||
case c.send <- data:
|
||||
log.Printf("📤 Proof-Code an Client gesendet: %s", resp.ProofCode)
|
||||
default:
|
||||
log.Printf("⚠️ Send channel voll, Proof-Code verworfen")
|
||||
}
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Printf("❌ Fehler beim Subscribe auf %s: %v", responseChannel, err)
|
||||
} else {
|
||||
c.subScoreResp = sub
|
||||
log.Printf("👂 WebSocket-Client lauscht auf Score-Responses: %s", responseChannel)
|
||||
}
|
||||
}
|
||||
|
||||
c.natsConn.Publish("score.submit", &submit)
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user