tournament pauser WIP

pull/4195/merge
Thibault Duplessis 2018-04-05 01:54:13 +02:00
parent aa21e991b8
commit f059a9c419
5 changed files with 58 additions and 8 deletions

View File

@ -179,10 +179,10 @@ object Tournament extends LilaController {
}
}
def withdraw(id: String) = Auth { implicit ctx => me =>
def pause(id: String) = Auth { implicit ctx => me =>
OptionResult(repo byId id) { tour =>
env.api.withdraw(tour.id, me.id)
if (HTTPRequest.isXhr(ctx.req)) Ok(Json.obj("ok" -> true)) as JSON
env.api.selfPause(tour.id, me.id)
if (HTTPRequest.isXhr(ctx.req)) jsonOkResult
else Redirect(routes.Tournament.show(tour.id))
}
}

View File

@ -225,7 +225,7 @@ GET /tournament/$id<\w{8}>/standing/:page controllers.Tournament.standing(id
GET /tournament/$id<\w{8}>/page-of/:userId controllers.Tournament.pageOf(id: String, userId: String)
GET /tournament/$id<\w{8}>/socket/v:apiVersion controllers.Tournament.websocket(id: String, apiVersion: Int)
POST /tournament/$id<\w{8}>/join controllers.Tournament.join(id: String)
POST /tournament/$id<\w{8}>/withdraw controllers.Tournament.withdraw(id: String)
POST /tournament/$id<\w{8}>/withdraw controllers.Tournament.pause(id: String)
GET /tournament/$id<\w{8}>/mini/:user/:nb controllers.Tournament.userGameNbMini(id: String, user: String, nb: Int)
GET /tournament/$id<\w{8}>/show/:user/:nb controllers.Tournament.userGameNbShow(id: String, user: String, nb: Int)
GET /tournament/$id<\w{8}>/player/:user controllers.Tournament.player(id: String, user: String)

View File

@ -0,0 +1,45 @@
package lila.tournament
import com.github.blemale.scaffeine.{ Cache, Scaffeine }
import org.joda.time.DateTime
import scala.concurrent.duration._
/*
* Computes the delay before a player can rejoin a tournament after pausing.
* The first pause results in a delay of gameTotalTime / 5 (e.g. 60 seconds for 5+0)
* with a minimum of 30 seconds and a maximum of 180 seconds.
* Following pauses accumulate delays (2x delay, 3x delay, etc...).
* After 20 minutes without a pause, the delay is reinitialized.
*/
private final class Pauser {
import Pauser._
private val cache: Cache[Player.ID, Pauses] = Scaffeine()
.expireAfterWrite(20 minutes)
.build[Player.ID, Pauses]
private def getPauses(player: Player) = cache.get(player.id, _ => Pauses(0))
private def initialDelayOf(tour: Tournament) = Delay {
(tour.clock.estimateTotalSeconds / 5) atLeast 30 atMost 120
}
def add(player: Player, tour: Tournament): Delay = {
val pauses = getPauses(player).add
initialDelayOf(tour) * pauses
}
}
object Pauser {
// pause counter of a player
case class Pauses(count: Int) extends AnyVal {
def add = copy(count = count + 1)
}
// pause counter of a player
case class Delay(seconds: Int) extends AnyVal {
def *(pauses: Pauses) = copy(seconds = seconds * pauses.count)
}
}

View File

@ -4,7 +4,7 @@ import lila.rating.Perf
import lila.user.{ User, Perfs }
private[tournament] case class Player(
_id: String, // random
_id: Player.ID, // random
tourId: Tournament.ID,
userId: User.ID,
rating: Int,
@ -19,7 +19,7 @@ private[tournament] case class Player(
def active = !withdraw
def is(uid: String): Boolean = uid == userId
def is(uid: User.ID): Boolean = uid == userId
def is(user: User): Boolean = is(user.id)
def is(other: Player): Boolean = is(other.userId)
@ -33,9 +33,11 @@ private[tournament] case class Player(
private[tournament] object Player {
type ID = String
case class WithUser(player: Player, user: User)
private[tournament] def make(tourId: String, user: User, perfLens: Perfs => Perf): Player = new Player(
private[tournament] def make(tourId: Tournament.ID, user: User, perfLens: Perfs => Perf): Player = new Player(
_id = lila.game.IdGenerator.game,
tourId = tourId,
userId = user.id,

View File

@ -235,7 +235,10 @@ final class TournamentApi(
}
}
def withdraw(tourId: Tournament.ID, userId: User.ID): Unit = {
def selfPause(tourId: Tournament.ID, userId: User.ID): Unit =
withdraw(tourId, userId)
private def withdraw(tourId: Tournament.ID, userId: User.ID): Unit = {
Sequencing(tourId)(TournamentRepo.enterableById) {
case tour if tour.isCreated =>
PlayerRepo.remove(tour.id, userId) >> updateNbPlayers(tour.id) >>- socketReload(tour.id) >>- publish()