137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
package coordinator
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.saintnet.tech/stryan/snengame/internal/game"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type SessionCmd string
|
|
type SessionResp string
|
|
|
|
const (
|
|
SessionCmdQuery SessionCmd = "query"
|
|
SessionCmdJoin = "join"
|
|
SessionCmdLeave = "leave"
|
|
SessionCmdPlay = "play"
|
|
SessionCmdPoll = "poll"
|
|
)
|
|
|
|
const (
|
|
SessionRespFound SessionResp = "found"
|
|
SessionRespJoined1 = "joined p1"
|
|
SessionRespJoined2 = "joined p2"
|
|
SessionRespJoinError = "join error"
|
|
SessionRespLeft = "left"
|
|
SessionRespPlayed = "played"
|
|
SessionRespError = "generic error"
|
|
SessionRespBroadcastSenTurn = "Sentinal turn"
|
|
SessionRespBroadcastScoTrun = "Scourge turn"
|
|
SessionRespBroadcastSenWin = "Sentinal wins"
|
|
SessionRespBroadcastScoWin = "Scourge wins"
|
|
SessionRespBroadcastUpdate = "update"
|
|
SessionRespBroadcastSenJoin = "Sentinal joined"
|
|
SessionRespBroadcastScoJoin = "Scourge joined"
|
|
SessionRespBroadcastSenReady = "Sentinal player is ready"
|
|
SessionRespBroadcastScoReady = "Scourge player is ready"
|
|
SessionRespBroadcastSenLeft = "Sentinal player has left"
|
|
SessionRespBroadcastScoLeft = "Scourge player has left"
|
|
SessionRespBroadcastNone = ""
|
|
)
|
|
|
|
type Session struct {
|
|
ID uuid.UUID
|
|
p1 uuid.UUID
|
|
p2 uuid.UUID
|
|
pMap map[uuid.UUID]int
|
|
Active bool
|
|
Game *game.Game
|
|
Watcher chan bool
|
|
Broadcasts map[uuid.UUID]chan SessionResp
|
|
}
|
|
|
|
func NewSession() *Session {
|
|
return &Session{
|
|
ID: uuid.New(),
|
|
p1: uuid.Nil,
|
|
p2: uuid.Nil,
|
|
pMap: make(map[uuid.UUID]int),
|
|
Active: false,
|
|
Game: nil,
|
|
Watcher: make(chan bool),
|
|
Broadcasts: make(map[uuid.UUID]chan SessionResp),
|
|
}
|
|
}
|
|
|
|
func (s *Session) Join(id uuid.UUID) SessionResp {
|
|
if s.p1 == uuid.Nil {
|
|
s.p1 = id
|
|
s.pMap[id] = game.SentinalID
|
|
for _, v := range s.Broadcasts {
|
|
v <- SessionRespBroadcastSenJoin
|
|
}
|
|
s.Broadcasts[id] = make(chan SessionResp)
|
|
return SessionRespJoined1
|
|
} else if s.p2 == uuid.Nil {
|
|
s.p2 = id
|
|
s.pMap[id] = game.ScourgeID
|
|
for _, v := range s.Broadcasts {
|
|
v <- SessionRespBroadcastScoJoin
|
|
}
|
|
s.Broadcasts[id] = make(chan SessionResp)
|
|
return SessionRespJoined2
|
|
} else {
|
|
return SessionRespJoinError
|
|
}
|
|
}
|
|
|
|
func (s *Session) Leave(id uuid.UUID) {
|
|
if id == s.p1 {
|
|
s.p1 = uuid.Nil
|
|
} else if id == s.p2 {
|
|
s.p2 = uuid.Nil
|
|
}
|
|
delete(s.Broadcasts, id)
|
|
if s.p1 == uuid.Nil && s.p2 == uuid.Nil {
|
|
s.Game = nil
|
|
} else if s.Game.Status != game.StatusDraw || s.Game.Status != game.StatusScourgeWin || s.Game.Status != game.StatusSentinalWin {
|
|
s.Game.Status = game.StatusStop
|
|
}
|
|
}
|
|
|
|
func (s *Session) Play(id uuid.UUID, cmd *game.Command) *game.CommandResult {
|
|
if s.pMap[id] != cmd.PlayerID {
|
|
return nil
|
|
}
|
|
res := s.Game.Parse(cmd)
|
|
return res
|
|
}
|
|
|
|
func (s *Session) PlayerIn(id uuid.UUID) bool {
|
|
_, exists := s.pMap[id]
|
|
return exists
|
|
}
|
|
|
|
type SessionCommand struct {
|
|
ID uuid.UUID `json:"player_id"`
|
|
MatchID uuid.UUID `json:"match_id"`
|
|
Command SessionCmd `json:"command"`
|
|
GameCommand *game.Command `json:"game_command,omitempty"`
|
|
}
|
|
|
|
func (s *SessionCommand) String() string {
|
|
return fmt.Sprintf("%v %v\n%v\n", s.ID, s.Command, s.GameCommand)
|
|
}
|
|
|
|
type SessionCommandResult struct {
|
|
ID uuid.UUID `json:"player_id"`
|
|
MatchID uuid.UUID `json:"match_id"`
|
|
Result SessionResp `json:"result"`
|
|
GameResult *game.CommandResult `json:"game_result,omitempty"`
|
|
}
|
|
|
|
func (s *SessionCommandResult) String() string {
|
|
return fmt.Sprintf("%v %v\n%v\n", s.ID, s.Result, s.GameResult)
|
|
}
|