Terminate matches with only ony client after fifteen minutes of inactivity

This commit is contained in:
Trevor Slocum 2024-11-07 18:45:59 -08:00
parent 09f8a7b36b
commit f08ac95eeb
4 changed files with 31 additions and 9 deletions

View file

@ -1,5 +1,5 @@
# bgammon - Backgammon server powering [bgammon.org](https://bgammon.org)
[![GoDoc](https://code.rocket9labs.com/tslocum/godoc-static/raw/branch/master/badge.svg)](https://docs.rocket9labs.com/code.rocket9labs.com/tslocum/bgammon)
[![GoDoc](https://code.rocket9labs.com/tslocum/godoc-static/raw/branch/main/badge.svg)](https://docs.rocket9labs.com/code.rocket9labs.com/tslocum/bgammon)
[![Translate](https://translate.codeberg.org/widget/bgammon/server/svg-badge.svg)](https://translate.codeberg.org/projects/bgammon/)
[![Donate via LiberaPay](https://img.shields.io/liberapay/receives/rocket9labs.com.svg?logo=liberapay)](https://liberapay.com/rocket9labs.com)

14
game.go
View file

@ -52,6 +52,8 @@ type Game struct {
partialTime time.Time
partialHandled bool
lastActive time.Time
boardStates [][]int8 // One board state for each move to allow undoing a move.
enteredStates [][2]bool // Player 1 entered state and Player 2 entered state for each move.
@ -105,6 +107,8 @@ func (g *Game) Copy(shallow bool) *Game {
partialTurn: g.partialTurn,
partialTime: g.partialTime,
partialHandled: g.partialHandled,
lastActive: g.lastActive,
}
copy(newGame.Board, g.Board)
copy(newGame.Moves, g.Moves)
@ -142,6 +146,14 @@ func (g *Game) SetPartialHandled(handled bool) {
g.partialHandled = handled
}
func (g *Game) LastActive() time.Time {
return g.lastActive
}
func (g *Game) UpdateLastActive() {
g.lastActive = time.Now()
}
func (g *Game) NextPartialTurn(player int8) {
if g.Started == 0 || g.Winner != 0 {
return
@ -159,6 +171,8 @@ func (g *Game) NextPartialTurn(player int8) {
g.partialTurn = player
g.partialTime = time.Now()
g.UpdateLastActive()
}
func (g *Game) NextTurn(reroll bool) {

View file

@ -305,6 +305,8 @@ func (g *serverGame) addClient(client *serverClient) (spectator bool) {
return spectator
}
g.UpdateLastActive()
var playerNumber int8
defer func() {
ev := &bgammon.EventJoined{
@ -400,6 +402,8 @@ func (g *serverGame) removeClient(client *serverClient) {
return
}
g.UpdateLastActive()
ev := &bgammon.EventLeft{}
ev.Player = string(client.name)

View file

@ -333,14 +333,18 @@ func (s *server) handleGames() {
}
// Terminate completed matches after two minutes when only one client remains connected.
if !g.terminated() && g.Ended != 0 && g.Winner != 0 && ((g.client1 != nil && g.client2 == nil) || (g.client1 == nil && g.client2 != nil)) && time.Now().Unix()-g.Ended >= 120 {
var clients []*serverClient
g.eachClient(func(client *serverClient) {
clients = append(clients, client)
})
for _, sc := range clients {
sc.sendNotice(gotext.GetD(sc.language, "Left completed match."))
g.removeClient(sc)
if !g.terminated() && ((g.client1 != nil && g.client2 == nil) || (g.client1 == nil && g.client2 != nil)) {
matchTimeout := (g.allowed1 != nil || g.allowed2 != nil) && time.Since(g.LastActive()) >= 15*time.Minute
matchEnded := g.Ended != 0 && g.Winner != 0 && time.Now().Unix()-g.Ended >= 120
if matchTimeout || matchEnded {
var clients []*serverClient
g.eachClient(func(client *serverClient) {
clients = append(clients, client)
})
for _, sc := range clients {
sc.sendNotice(gotext.GetD(sc.language, "Left completed match."))
g.removeClient(sc)
}
}
}