prevent changing tournament perf type after players have joined

closes #9730
pull/9812/head
Thibault Duplessis 2021-09-15 19:21:41 +02:00
parent 12e7dc63a8
commit 6639987c7a
2 changed files with 53 additions and 34 deletions

View File

@ -26,12 +26,12 @@ object form {
else trans.createANewTournament()
),
postForm(cls := "form3", action := routes.Tournament.create)(
form3.globalError(form),
fields.name,
form3.split(fields.rated, fields.variant),
fields.clock,
form3.split(fields.minutes, fields.waitMinutes),
form3.split(fields.description(true), fields.startPosition),
form3.globalError(form),
fieldset(cls := "conditions")(
fields.advancedSettings,
div(cls := "form")(
@ -192,7 +192,8 @@ final private class TourFields(form: Form[_], tour: Option[Tournament])(implicit
def isTeamBattle = tour.exists(_.isTeamBattle) || form("teamBattleByTeam").value.nonEmpty
private def disabledAfterStart = tour.exists(!_.isCreated)
private def disabledAfterStart = tour.exists(!_.isCreated)
private def disabledAfterCreate = tour.isDefined
def name =
form3.group(form("name"), trans.name()) { f =>
@ -225,7 +226,7 @@ final private class TourFields(form: Form[_], tour: Option[Tournament])(implicit
form3.select(
_,
translatedVariantChoicesWithVariants.map(x => x._1 -> x._2),
disabled = disabledAfterStart
disabled = disabledAfterCreate
)
)
def startPosition =

View File

@ -8,6 +8,7 @@ import play.api.data._
import play.api.data.Forms._
import play.api.data.validation
import play.api.data.validation.Constraint
import scala.util.chaining._
import lila.common.Form._
import lila.hub.LeaderTeam
@ -19,7 +20,7 @@ final class TournamentForm {
import TournamentForm._
def create(user: User, leaderTeams: List[LeaderTeam], teamBattleId: Option[TeamID] = None) =
form(user, leaderTeams) fill TournamentSetup(
form(user, leaderTeams, none) fill TournamentSetup(
name = teamBattleId.isEmpty option user.titleUsername,
clockTime = clockTimeDefault,
clockIncrement = clockIncrementDefault,
@ -40,7 +41,7 @@ final class TournamentForm {
)
def edit(user: User, leaderTeams: List[LeaderTeam], tour: Tournament) =
form(user, leaderTeams) fill TournamentSetup(
form(user, leaderTeams, tour.some) fill TournamentSetup(
name = tour.name.some,
clockTime = tour.clock.limitInMinutes,
clockIncrement = tour.clock.incrementSeconds,
@ -62,35 +63,50 @@ final class TournamentForm {
private val blockList = List("lichess", "liсhess")
private def form(user: User, leaderTeams: List[LeaderTeam]) =
Form(
mapping(
"name" -> optional(eventName(2, 30, user.isVerifiedOrAdmin)),
"clockTime" -> numberInDouble(clockTimeChoices),
"clockIncrement" -> numberIn(clockIncrementChoices),
"minutes" -> {
if (lila.security.Granter(_.ManageTournament)(user)) number
else numberIn(minuteChoices)
},
"waitMinutes" -> optional(numberIn(waitMinuteChoices)),
"startDate" -> optional(inTheFuture(ISODateTimeOrTimestamp.isoDateTimeOrTimestamp)),
"variant" -> optional(text.verifying(v => guessVariant(v).isDefined)),
"position" -> optional(lila.common.Form.fen.playableStrict),
"mode" -> optional(number.verifying(Mode.all.map(_.id) contains _)), // deprecated, use rated
"rated" -> optional(boolean),
"password" -> optional(cleanNonEmptyText),
"conditions" -> Condition.DataForm.all(leaderTeams),
"teamBattleByTeam" -> optional(nonEmptyText.verifying(id => leaderTeams.exists(_.id == id))),
"berserkable" -> optional(boolean),
"streakable" -> optional(boolean),
"description" -> optional(cleanNonEmptyText),
"hasChat" -> optional(boolean)
)(TournamentSetup.apply)(TournamentSetup.unapply)
.verifying("Invalid clock", _.validClock)
.verifying("15s and 0+1 variant games cannot be rated", _.validRatedVariant)
.verifying("Increase tournament duration, or decrease game clock", _.sufficientDuration)
.verifying("Reduce tournament duration, or increase game clock", _.excessiveDuration)
)
private def form(user: User, leaderTeams: List[LeaderTeam], prev: Option[Tournament]) =
Form {
makeMapping(user, leaderTeams) pipe { m =>
prev.fold(m) { tour =>
m
.verifying(
"Can't change variant after players have joined",
_.realVariant == tour.variant || tour.nbPlayers == 0
)
.verifying(
"Can't change time control after players have joined",
_.speed == tour.speed || tour.nbPlayers == 0
)
}
}
}
private def makeMapping(user: User, leaderTeams: List[LeaderTeam]) =
mapping(
"name" -> optional(eventName(2, 30, user.isVerifiedOrAdmin)),
"clockTime" -> numberInDouble(clockTimeChoices),
"clockIncrement" -> numberIn(clockIncrementChoices),
"minutes" -> {
if (lila.security.Granter(_.ManageTournament)(user)) number
else numberIn(minuteChoices)
},
"waitMinutes" -> optional(numberIn(waitMinuteChoices)),
"startDate" -> optional(inTheFuture(ISODateTimeOrTimestamp.isoDateTimeOrTimestamp)),
"variant" -> optional(text.verifying(v => guessVariant(v).isDefined)),
"position" -> optional(lila.common.Form.fen.playableStrict),
"mode" -> optional(number.verifying(Mode.all.map(_.id) contains _)), // deprecated, use rated
"rated" -> optional(boolean),
"password" -> optional(cleanNonEmptyText),
"conditions" -> Condition.DataForm.all(leaderTeams),
"teamBattleByTeam" -> optional(nonEmptyText.verifying(id => leaderTeams.exists(_.id == id))),
"berserkable" -> optional(boolean),
"streakable" -> optional(boolean),
"description" -> optional(cleanNonEmptyText),
"hasChat" -> optional(boolean)
)(TournamentSetup.apply)(TournamentSetup.unapply)
.verifying("Invalid clock", _.validClock)
.verifying("15s and 0+1 variant games cannot be rated", _.validRatedVariant)
.verifying("Increase tournament duration, or decrease game clock", _.sufficientDuration)
.verifying("Reduce tournament duration, or increase game clock", _.excessiveDuration)
}
object TournamentForm {
@ -176,6 +192,8 @@ private[tournament] case class TournamentSetup(
def clockConfig = chess.Clock.Config((clockTime * 60).toInt, clockIncrement)
def speed = chess.Speed(clockConfig)
def validRatedVariant =
realMode == Mode.Casual ||
lila.game.Game.allowRated(realVariant, clockConfig.some)