package coordinator import ( "fmt" "time" . "git.saintnet.tech/tomecraft/tome_game" . "git.saintnet.tech/tomecraft/tome_lib" "github.com/google/uuid" ) type Session struct { ID uuid.UUID p1 uuid.UUID p2 uuid.UUID pMap map[uuid.UUID]int Active bool Game *Game Watcher chan bool Broadcasts map[uuid.UUID]chan SessionResp LastMove time.Time } 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), LastMove: time.Now(), } } func (s *Session) Join(id uuid.UUID) SessionResp { if s.p1 == uuid.Nil { s.p1 = id s.pMap[id] = SentinalID for _, v := range s.Broadcasts { v <- SessionRespBroadcastSenJoin } return SessionRespJoined1 } else if s.p2 == uuid.Nil { s.p2 = id s.pMap[id] = ScourgeID for _, v := range s.Broadcasts { v <- SessionRespBroadcastScoJoin } 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 != StatusDraw || s.Game.Status != StatusScourgeWin || s.Game.Status != StatusSentinalWin { s.Game.Status = StatusStop } } func (s *Session) Play(id uuid.UUID, cmd *Command) *CommandResult { if s.pMap[id] != cmd.PlayerID { return nil } if cmd.Type != SessionCmdPoll { s.LastMove = time.Now() } 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 *Command `json:"game_command,omitempty"` } func (s *SessionCommand) String() string { return fmt.Sprintf("%v %v %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 *CommandResult `json:"game_result,omitempty"` } func (s *SessionCommandResult) String() string { return fmt.Sprintf("%v %v %v\n", s.ID, s.Result, s.GameResult) }