allow server to handle multiple matches

This commit is contained in:
stryan 2021-07-25 17:22:57 -04:00
parent 907cf269cd
commit 37d0702d5c
3 changed files with 77 additions and 38 deletions

View File

@ -21,6 +21,7 @@ import (
var done chan interface{}
var interrupt chan os.Signal
var pid int
var matchID uuid.UUID
func receiveHandler(connection *websocket.Conn, output chan string) {
defer close(done)
@ -37,6 +38,7 @@ func receiveHandler(connection *websocket.Conn, output chan string) {
pid = game.ScourgeID
output <- "joined as scourge"
} else if resp.Result == coordinator.SessionRespFound {
matchID = resp.MatchID
output <- "game found"
} else if resp.Result == coordinator.SessionRespPlayed {
if resp.GameResult != nil {
@ -149,11 +151,13 @@ func GetCommand(uid uuid.UUID, resp chan coordinator.SessionCommand) {
case coordinator.SessionCmdJoin:
resp <- coordinator.SessionCommand{
ID: uid,
MatchID: matchID,
Command: coordinator.SessionCmdJoin,
}
case coordinator.SessionCmdLeave:
resp <- coordinator.SessionCommand{
ID: uid,
MatchID: matchID,
Command: coordinator.SessionCmdLeave,
}
default:
@ -163,6 +167,7 @@ func GetCommand(uid uuid.UUID, resp chan coordinator.SessionCommand) {
//state
resp <- coordinator.SessionCommand{
ID: uid,
MatchID: matchID,
Command: coordinator.SessionCmdPlay,
GameCommand: &game.Command{
PlayerID: pid,
@ -174,6 +179,7 @@ func GetCommand(uid uuid.UUID, resp chan coordinator.SessionCommand) {
//action
resp <- coordinator.SessionCommand{
ID: uid,
MatchID: matchID,
Command: coordinator.SessionCmdPlay,
GameCommand: &game.Command{
PlayerID: pid,

View File

@ -10,16 +10,16 @@ import (
)
type Coordinator struct {
Match *Session
Matches map[uuid.UUID]*Session
PlayerQueueChan chan uuid.UUID
CallbackChan map[uuid.UUID]chan bool
CallbackChan map[uuid.UUID]chan uuid.UUID
}
func NewCoordinator() *Coordinator {
return &Coordinator{
Match: NewSession(),
Matches: make(map[uuid.UUID]*Session),
PlayerQueueChan: make(chan uuid.UUID),
CallbackChan: make(map[uuid.UUID]chan bool),
CallbackChan: make(map[uuid.UUID]chan uuid.UUID),
}
}
@ -31,16 +31,21 @@ func (c *Coordinator) Start() {
fmt.Println("p1 join")
p2 = <-c.PlayerQueueChan
fmt.Println("p2 join")
c.Match = m
m.Active = true
m.Game = game.NewGame()
c.CallbackChan[p1] <- true
c.CallbackChan[p2] <- true
c.Matches[m.ID] = m
c.CallbackChan[p1] <- m.ID
c.CallbackChan[p2] <- m.ID
}()
go func() {
time.Sleep(5)
if c.Match.Game == nil {
log.Println("clearing old match")
c.Match = nil
for {
time.Sleep(10)
for _, v := range c.Matches {
if v.Game == nil && v.Active {
log.Println("clearing match with no game")
delete(c.Matches, v.ID)
}
}
}
}()
@ -49,47 +54,64 @@ func (c *Coordinator) Start() {
func (c *Coordinator) Coordinate(cmd *SessionCommand) *SessionCommandResult {
switch cmd.Command {
case SessionCmdQuery:
c.CallbackChan[cmd.ID] = make(chan bool)
c.CallbackChan[cmd.ID] = make(chan uuid.UUID)
c.PlayerQueueChan <- cmd.ID
<-c.CallbackChan[cmd.ID]
m := <-c.CallbackChan[cmd.ID]
return &SessionCommandResult{
ID: cmd.ID,
Result: SessionRespFound,
ID: cmd.ID,
MatchID: m,
Result: SessionRespFound,
}
case SessionCmdJoin:
if c.Match == nil {
m, exists := c.Matches[cmd.MatchID]
if !exists {
return &SessionCommandResult{
ID: cmd.ID,
Result: SessionRespJoinError,
ID: cmd.ID,
MatchID: uuid.Nil,
Result: SessionRespJoinError,
}
}
resp := c.Match.Join(cmd.ID)
resp := m.Join(cmd.ID)
return &SessionCommandResult{
ID: cmd.ID,
Result: resp,
ID: cmd.ID,
MatchID: m.ID,
Result: resp,
}
case SessionCmdLeave:
if c.Match == nil {
m, exists := c.Matches[cmd.MatchID]
if !exists || !m.PlayerIn(cmd.ID) {
return &SessionCommandResult{
ID: cmd.ID,
Result: SessionRespLeft,
ID: cmd.ID,
MatchID: uuid.Nil,
Result: SessionRespLeft,
}
}
c.Match.Leave(cmd.ID)
m.Leave(cmd.ID)
return &SessionCommandResult{
ID: cmd.ID,
Result: SessionRespLeft,
ID: cmd.ID,
MatchID: uuid.Nil,
Result: SessionRespLeft,
}
case SessionCmdPlay:
resp := c.Match.Play(cmd.ID, cmd.GameCommand)
m, exists := c.Matches[cmd.MatchID]
if !exists || !m.PlayerIn(cmd.ID) {
return &SessionCommandResult{
ID: cmd.ID,
MatchID: uuid.Nil,
Result: SessionRespLeft,
}
}
resp := m.Play(cmd.ID, cmd.GameCommand)
return &SessionCommandResult{
ID: cmd.ID,
MatchID: m.ID,
Result: SessionRespPlayed,
GameResult: resp,
}
}
return &SessionCommandResult{
ID: cmd.ID,
Result: SessionRespError,
ID: cmd.ID,
MatchID: uuid.Nil,
Result: SessionRespError,
}
}

View File

@ -28,18 +28,22 @@ const (
)
type Session struct {
p1 uuid.UUID
p2 uuid.UUID
pMap map[uuid.UUID]int
Game *game.Game
ID uuid.UUID
p1 uuid.UUID
p2 uuid.UUID
pMap map[uuid.UUID]int
Active bool
Game *game.Game
}
func NewSession() *Session {
return &Session{
p1: uuid.Nil,
p2: uuid.Nil,
pMap: make(map[uuid.UUID]int),
Game: nil,
ID: uuid.New(),
p1: uuid.Nil,
p2: uuid.Nil,
pMap: make(map[uuid.UUID]int),
Active: false,
Game: nil,
}
}
@ -78,8 +82,14 @@ func (s *Session) Play(id uuid.UUID, cmd *game.Command) *game.CommandResult {
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"`
}
@ -90,6 +100,7 @@ func (s *SessionCommand) String() string {
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"`
}