Files
doucan/app/internal/handlers/handlers.go
2026-02-19 21:18:12 +08:00

97 lines
2.4 KiB
Go

package handlers
import (
"doudizhu-server/internal/game"
"doudizhu-server/internal/models"
"doudizhu-server/internal/ws"
"encoding/json"
"net/http"
"strings"
)
type Handler struct {
GameMgr *game.GameManager
Hub *ws.Hub
}
func NewHandler(gameMgr *game.GameManager, hub *ws.Hub) *Handler {
return &Handler{GameMgr: gameMgr, Hub: hub}
}
func (h *Handler) CreateRoom(w http.ResponseWriter, r *http.Request) {
var req models.CreateRoomRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
h.jsonError(w, http.StatusBadRequest, "invalid request")
return
}
if req.PlayerName == "" {
h.jsonError(w, http.StatusBadRequest, "player name required")
return
}
if req.MaxPlayers < 2 || req.MaxPlayers > 10 {
req.MaxPlayers = 4
}
room, player := h.GameMgr.CreateRoom(req.PlayerName, req.MaxPlayers)
h.jsonSuccess(w, map[string]string{"roomId": room.ID, "playerId": player.ID})
}
func (h *Handler) JoinRoom(w http.ResponseWriter, r *http.Request) {
roomID := strings.ToLower(extractRoomID(r.URL.Path))
if roomID == "" {
h.jsonError(w, http.StatusBadRequest, "room id required")
return
}
var req models.JoinRoomRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
h.jsonError(w, http.StatusBadRequest, "invalid request")
return
}
if req.PlayerName == "" {
h.jsonError(w, http.StatusBadRequest, "player name required")
return
}
room, player, err := h.GameMgr.JoinRoom(roomID, req.PlayerName)
if err != nil {
h.jsonError(w, http.StatusBadRequest, err.Error())
return
}
h.jsonSuccess(w, map[string]string{"roomId": room.ID, "playerId": player.ID})
}
func (h *Handler) WebSocket(w http.ResponseWriter, r *http.Request) {
ws.ServeWs(h.Hub, w, r)
}
func (h *Handler) jsonSuccess(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(models.ApiResponse{
Status: 200,
Code: 0,
Message: "success",
Data: data,
})
}
func (h *Handler) jsonError(w http.ResponseWriter, status int, msg string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(models.ApiResponse{
Status: status,
Code: 1,
Message: msg,
})
}
func extractRoomID(path string) string {
parts := strings.Split(strings.Trim(path, "/"), "/")
for i, p := range parts {
if p == "rooms" && i+1 < len(parts) && parts[i+1] != "join" {
return parts[i+1]
}
}
return ""
}