asd
This commit is contained in:
parent
ef045f9353
commit
ff5d6ab91d
7 changed files with 388 additions and 84 deletions
|
|
@ -7,6 +7,7 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"prsi/internal/engine"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
|
|
@ -49,7 +50,7 @@ type wsMessage struct {
|
|||
PlayerID string `json:"player_id,omitempty"`
|
||||
PlayerName string `json:"player_name,omitempty"`
|
||||
GameID string `json:"game_id,omitempty"`
|
||||
// CardIndices supports multi-card play; CardIdx is kept for single-card backwards compat.
|
||||
// CardIndices carries selected card index; CardIdx is kept for backwards compat.
|
||||
CardIndices []int `json:"card_indices,omitempty"`
|
||||
CardIdx *int `json:"card_idx,omitempty"`
|
||||
ChosenSuit engine.Suit `json:"chosen_suit,omitempty"`
|
||||
|
|
@ -227,6 +228,49 @@ func (h *Hub) HandleGetScript(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(map[string]string{"script": script})
|
||||
}
|
||||
|
||||
type lobbyInfo struct {
|
||||
GameID string `json:"game_id"`
|
||||
PlayerCount int `json:"player_count"`
|
||||
Players []string `json:"players"`
|
||||
State engine.GameState `json:"state"`
|
||||
HasRules bool `json:"has_rules"`
|
||||
}
|
||||
|
||||
// HandleListLobbies returns waiting rooms that can be joined.
|
||||
func (h *Hub) HandleListLobbies(w http.ResponseWriter, r *http.Request) {
|
||||
h.mu.RLock()
|
||||
defer h.mu.RUnlock()
|
||||
|
||||
rooms := make([]lobbyInfo, 0, len(h.games))
|
||||
for id, g := range h.games {
|
||||
g.Mu.RLock()
|
||||
if g.State == engine.Waiting && len(g.Players) < 4 {
|
||||
names := make([]string, 0, len(g.Players))
|
||||
for _, p := range g.Players {
|
||||
names = append(names, p.Name)
|
||||
}
|
||||
rooms = append(rooms, lobbyInfo{
|
||||
GameID: id,
|
||||
PlayerCount: len(g.Players),
|
||||
Players: names,
|
||||
State: g.State,
|
||||
HasRules: len(g.ActiveRules) > 0,
|
||||
})
|
||||
}
|
||||
g.Mu.RUnlock()
|
||||
}
|
||||
|
||||
sort.Slice(rooms, func(i, j int) bool {
|
||||
if rooms[i].PlayerCount != rooms[j].PlayerCount {
|
||||
return rooms[i].PlayerCount > rooms[j].PlayerCount
|
||||
}
|
||||
return rooms[i].GameID < rooms[j].GameID
|
||||
})
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{"lobbies": rooms})
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Broadcast helpers
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
|
@ -262,17 +306,22 @@ func (h *Hub) broadcastRules(gameID string) {
|
|||
// gameView is what we send to each client — identical to Game but Hand only
|
||||
// contains the *receiving* player's cards; others get a count.
|
||||
type gameView struct {
|
||||
ID string `json:"id"`
|
||||
State engine.GameState `json:"state"`
|
||||
CurrentPlayer int `json:"current_player_index"`
|
||||
ActiveSuit engine.Suit `json:"active_suit"`
|
||||
PenaltyCards int `json:"penalty_cards"`
|
||||
SkipNext bool `json:"skip_next"`
|
||||
DiscardPile []engine.Card `json:"discard_pile"`
|
||||
Winner *engine.Player `json:"winner"`
|
||||
PendingChoice *engine.PendingChoice `json:"pending_choice,omitempty"`
|
||||
ActiveRules []engine.ActiveRule `json:"active_rules"`
|
||||
Players []playerView `json:"players"`
|
||||
ID string `json:"id"`
|
||||
State engine.GameState `json:"state"`
|
||||
CurrentPlayer int `json:"current_player_index"`
|
||||
TurnNumber int `json:"turn_number"`
|
||||
RoundNumber int `json:"round_number"`
|
||||
LastActionType string `json:"last_action_type,omitempty"`
|
||||
LastActorIndex int `json:"last_actor_index,omitempty"`
|
||||
ActiveSuit engine.Suit `json:"active_suit"`
|
||||
PenaltyCards int `json:"penalty_cards"`
|
||||
SkipNext bool `json:"skip_next"`
|
||||
DiscardPile []engine.Card `json:"discard_pile"`
|
||||
Winner *engine.Player `json:"winner"`
|
||||
PendingChoice *engine.PendingChoice `json:"pending_choice,omitempty"`
|
||||
ChoiceQueue []engine.PendingChoice `json:"choice_queue,omitempty"`
|
||||
ActiveRules []engine.ActiveRule `json:"active_rules"`
|
||||
Players []playerView `json:"players"`
|
||||
}
|
||||
|
||||
type playerView struct {
|
||||
|
|
@ -306,17 +355,22 @@ func buildView(g *engine.Game, receiverID string) gameView {
|
|||
}
|
||||
|
||||
return gameView{
|
||||
ID: g.ID,
|
||||
State: g.State,
|
||||
CurrentPlayer: g.CurrentPlayer,
|
||||
ActiveSuit: g.ActiveSuit,
|
||||
PenaltyCards: g.PenaltyCards,
|
||||
SkipNext: g.SkipNext,
|
||||
DiscardPile: discardTop,
|
||||
Winner: g.Winner,
|
||||
PendingChoice: g.PendingChoice,
|
||||
ActiveRules: g.ActiveRules,
|
||||
Players: players,
|
||||
ID: g.ID,
|
||||
State: g.State,
|
||||
CurrentPlayer: g.CurrentPlayer,
|
||||
TurnNumber: g.TurnNumber,
|
||||
RoundNumber: g.RoundNumber,
|
||||
LastActionType: g.LastActionType,
|
||||
LastActorIndex: g.LastActorIndex,
|
||||
ActiveSuit: g.ActiveSuit,
|
||||
PenaltyCards: g.PenaltyCards,
|
||||
SkipNext: g.SkipNext,
|
||||
DiscardPile: discardTop,
|
||||
Winner: g.Winner,
|
||||
PendingChoice: g.PendingChoice,
|
||||
ChoiceQueue: g.ChoiceQueue,
|
||||
ActiveRules: g.ActiveRules,
|
||||
Players: players,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue