only create games when match is joined, remove old players from queue
This commit is contained in:
parent
f5eac37b06
commit
deb6d24282
@ -5,6 +5,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.saintnet.tech/stryan/snengame/internal/game"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -12,6 +13,7 @@ type Coordinator struct {
|
|||||||
Matches map[uuid.UUID]*Session
|
Matches map[uuid.UUID]*Session
|
||||||
MatchLock *sync.Mutex
|
MatchLock *sync.Mutex
|
||||||
PlayerQueueChan chan uuid.UUID
|
PlayerQueueChan chan uuid.UUID
|
||||||
|
PlayerPool map[MMRPlayer]bool
|
||||||
CallbackChan map[uuid.UUID]chan uuid.UUID
|
CallbackChan map[uuid.UUID]chan uuid.UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,6 +22,7 @@ func NewCoordinator() *Coordinator {
|
|||||||
Matches: make(map[uuid.UUID]*Session),
|
Matches: make(map[uuid.UUID]*Session),
|
||||||
MatchLock: &sync.Mutex{},
|
MatchLock: &sync.Mutex{},
|
||||||
PlayerQueueChan: make(chan uuid.UUID),
|
PlayerQueueChan: make(chan uuid.UUID),
|
||||||
|
PlayerPool: make(map[MMRPlayer]bool),
|
||||||
CallbackChan: make(map[uuid.UUID]chan uuid.UUID),
|
CallbackChan: make(map[uuid.UUID]chan uuid.UUID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,6 +30,7 @@ func NewCoordinator() *Coordinator {
|
|||||||
func (c *Coordinator) Start() {
|
func (c *Coordinator) Start() {
|
||||||
go MatchMaker(c)
|
go MatchMaker(c)
|
||||||
go MatchCleaner(c)
|
go MatchCleaner(c)
|
||||||
|
go QueueCleaner(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coordinator) Coordinate(cmd *SessionCommand) *SessionCommandResult {
|
func (c *Coordinator) Coordinate(cmd *SessionCommand) *SessionCommandResult {
|
||||||
@ -60,6 +64,11 @@ func (c *Coordinator) Coordinate(cmd *SessionCommand) *SessionCommandResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp := m.Join(cmd.ID)
|
resp := m.Join(cmd.ID)
|
||||||
|
if m.p1 != uuid.Nil && m.p2 != uuid.Nil {
|
||||||
|
log.Printf("Starting game for %v and %v\n", m.p1, m.p2)
|
||||||
|
m.Game = game.NewGame()
|
||||||
|
m.Active = true
|
||||||
|
}
|
||||||
return &SessionCommandResult{
|
return &SessionCommandResult{
|
||||||
ID: cmd.ID,
|
ID: cmd.ID,
|
||||||
MatchID: m.ID,
|
MatchID: m.ID,
|
||||||
|
@ -8,41 +8,48 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type MMRPlayer struct {
|
||||||
|
Id uuid.UUID
|
||||||
|
MMR int
|
||||||
|
QueueTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
func MatchMaker(c *Coordinator) {
|
func MatchMaker(c *Coordinator) {
|
||||||
//in the future the int below will be MMR or something, but for now it's just a set
|
//in the future the int will be MMR or something, but for now it's just a set
|
||||||
pool := make(map[uuid.UUID]int)
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case p := <-c.PlayerQueueChan:
|
case p := <-c.PlayerQueueChan:
|
||||||
//add player to pool
|
//add player to pool
|
||||||
pool[p] = 0
|
c.PlayerPool[MMRPlayer{
|
||||||
|
Id: p,
|
||||||
|
MMR: 0,
|
||||||
|
QueueTime: time.Now()}] = true
|
||||||
log.Printf("Player %v has queued", p)
|
log.Printf("Player %v has queued", p)
|
||||||
default:
|
default:
|
||||||
//no new players, let's try to matchmake
|
//no new players, let's try to matchmake
|
||||||
if len(pool) < 2 {
|
if len(c.PlayerPool) < 2 {
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
//fancy matchmaking math to guarantee a fair game
|
//fancy matchmaking math to guarantee a fair game
|
||||||
var p1, p2 uuid.UUID
|
var p1, p2 MMRPlayer
|
||||||
for key, _ := range pool {
|
for key, _ := range c.PlayerPool {
|
||||||
p1 = key
|
p1 = key
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
delete(pool, p1)
|
delete(c.PlayerPool, p1)
|
||||||
for key, _ := range pool {
|
for key, _ := range c.PlayerPool {
|
||||||
p2 = key
|
p2 = key
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
delete(pool, p2)
|
delete(c.PlayerPool, p2)
|
||||||
m := NewSession()
|
m := NewSession()
|
||||||
log.Printf("Creating match %v for %v and %v", m.ID, p1, p2)
|
log.Printf("Creating match %v for %v and %v", m.ID, p1, p2)
|
||||||
m.Active = true
|
m.Active = false
|
||||||
m.Game = game.NewGame()
|
|
||||||
c.MatchLock.Lock()
|
c.MatchLock.Lock()
|
||||||
c.Matches[m.ID] = m
|
c.Matches[m.ID] = m
|
||||||
c.MatchLock.Unlock()
|
c.MatchLock.Unlock()
|
||||||
c.CallbackChan[p1] <- m.ID
|
c.CallbackChan[p1.Id] <- m.ID
|
||||||
c.CallbackChan[p2] <- m.ID
|
c.CallbackChan[p2.Id] <- m.ID
|
||||||
go MatchWatcher(m)
|
go MatchWatcher(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +57,18 @@ func MatchMaker(c *Coordinator) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func QueueCleaner(c *Coordinator) {
|
||||||
|
for {
|
||||||
|
time.Sleep(5 * time.Minute)
|
||||||
|
for v, _ := range c.PlayerPool {
|
||||||
|
if time.Now().After(v.QueueTime.Add(time.Minute * 5)) {
|
||||||
|
log.Printf("Removing player %v from pool", v.Id)
|
||||||
|
delete(c.PlayerPool, v) //probably should just flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func MatchCleaner(c *Coordinator) {
|
func MatchCleaner(c *Coordinator) {
|
||||||
for {
|
for {
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
|
Loading…
Reference in New Issue
Block a user