ensure that berserk was applied before modifying the pairing

- closes #7013
pull/7028/head
Thibault Duplessis 2020-07-21 13:08:44 +02:00
parent bc5ca4c1b0
commit 3ea9a6d669
5 changed files with 11 additions and 7 deletions

View File

@ -346,7 +346,7 @@ case class Game(
def berserkable = clock.??(_.config.berserkable) && status == Status.Started && playedTurns < 2
def goBerserk(color: Color) =
def goBerserk(color: Color): Option[Progress] =
clock.ifTrue(berserkable && !player(color).berserk).map { c =>
val newClock = c goBerserk color
Progress(

View File

@ -272,11 +272,12 @@ final private[round] class RoundDuct(
pov.game.resignable ?? finisher.other(pov.game, _.Resign, Some(!pov.color))
}
case GoBerserk(color) =>
case GoBerserk(color, promise) =>
handle(color) { pov =>
pov.game.goBerserk(color) ?? { progress =>
val berserked = pov.game.goBerserk(color)
berserked.?? { progress =>
proxy.save(progress) >> gameRepo.goBerserk(pov) inject progress.events
}
} >>- promise.success(berserked.isDefined)
}
case ResignForce(playerId) =>

View File

@ -55,7 +55,7 @@ package round {
case class ForecastPlay(lastMove: chess.Move)
case class Cheat(color: Color)
case class HoldAlert(playerId: PlayerId, mean: Int, sd: Int, ip: IpAddress)
case class GoBerserk(color: Color)
case class GoBerserk(color: Color, promise: Promise[Boolean])
case object NoStart
case object TooManyPlies
}

View File

@ -31,6 +31,7 @@ final class Env(
renderer: lila.hub.actors.Renderer,
chatApi: lila.chat.ChatApi,
tellRound: lila.round.TellRound,
roundSocket: lila.round.RoundSocket,
lightUserApi: lila.user.LightUserApi,
onStart: lila.round.OnStart,
historyApi: lila.history.HistoryApi,

View File

@ -35,6 +35,7 @@ final class TournamentApi(
renderer: lila.hub.actors.Renderer,
socket: TournamentSocket,
tellRound: lila.round.TellRound,
roundSocket: lila.round.RoundSocket,
trophyApi: lila.user.TrophyApi,
verify: Condition.Verify,
duelStore: DuelStore,
@ -405,8 +406,9 @@ final class TournamentApi(
pairingRepo.findPlaying(tour.id, userId) flatMap {
case Some(pairing) if !pairing.berserkOf(userId) =>
(pairing colorOf userId) ?? { color =>
pairingRepo.setBerserk(pairing, userId) >>-
tellRound(gameId, GoBerserk(color))
roundSocket.rounds.ask(gameId) { GoBerserk(color, _) } flatMap {
_ ?? pairingRepo.setBerserk(pairing, userId)
}
}
case _ => funit
}