93 lines
3.3 KiB
Scala
93 lines
3.3 KiB
Scala
package lila.round
|
|
|
|
import chess.Centis
|
|
|
|
import lila.common.Bus
|
|
import lila.game.{ Event, Game, Pov, Progress }
|
|
import lila.i18n.{ I18nKeys => trans, defaultLang }
|
|
import lila.pref.{ Pref, PrefApi }
|
|
|
|
final private[round] class Drawer(
|
|
messenger: Messenger,
|
|
finisher: Finisher,
|
|
prefApi: PrefApi,
|
|
isBotSync: lila.common.LightUser.IsBotSync
|
|
)(implicit ec: scala.concurrent.ExecutionContext) {
|
|
|
|
implicit private val chatLang = defaultLang
|
|
|
|
def autoThreefold(game: Game): Fu[Option[Pov]] = game.playable ??
|
|
Pov(game)
|
|
.map { pov =>
|
|
import Pref.PrefZero
|
|
if (game.playerHasOfferedDrawRecently(pov.color)) fuccess(pov.some)
|
|
else
|
|
pov.player.userId ?? { uid => prefApi.getPref(uid, _.autoThreefold) } map { autoThreefold =>
|
|
autoThreefold == Pref.AutoThreefold.ALWAYS || {
|
|
autoThreefold == Pref.AutoThreefold.TIME &&
|
|
game.clock ?? { _.remainingTime(pov.color) < Centis.ofSeconds(30) }
|
|
} || pov.player.userId.exists(isBotSync)
|
|
} map (_ option pov)
|
|
}
|
|
.sequenceFu
|
|
.dmap(_.flatten.headOption)
|
|
|
|
def yes(pov: Pov)(implicit proxy: GameProxy): Fu[Events] = pov.game.playable ?? {
|
|
pov match {
|
|
case pov if pov.game.history.threefoldRepetition =>
|
|
finisher.other(pov.game, _.Draw, None)
|
|
case pov if pov.opponent.isOfferingDraw =>
|
|
finisher.other(pov.game, _.Draw, None, Messenger.Persistent(trans.drawOfferAccepted.txt()).some)
|
|
case Pov(g, color) if g playerCanOfferDraw color =>
|
|
val progress = Progress(g) map { _ offerDraw color }
|
|
messenger.system(g, color.fold(trans.whiteOffersDraw, trans.blackOffersDraw).txt())
|
|
proxy.save(progress) >>-
|
|
publishDrawOffer(progress.game) inject
|
|
List(Event.DrawOffer(by = color.some))
|
|
case _ => fuccess(List(Event.ReloadOwner))
|
|
}
|
|
}
|
|
|
|
def no(pov: Pov)(implicit proxy: GameProxy): Fu[Events] = pov.game.playable ?? {
|
|
pov match {
|
|
case Pov(g, color) if pov.player.isOfferingDraw =>
|
|
proxy.save {
|
|
messenger.system(g, trans.drawOfferCanceled.txt())
|
|
Progress(g) map { g =>
|
|
g.updatePlayer(color, _.removeDrawOffer)
|
|
}
|
|
} inject List(Event.DrawOffer(by = none))
|
|
case Pov(g, color) if pov.opponent.isOfferingDraw =>
|
|
proxy.save {
|
|
messenger.system(g, color.fold(trans.whiteDeclinesDraw, trans.blackDeclinesDraw).txt())
|
|
Progress(g) map { g =>
|
|
g.updatePlayer(!color, _.removeDrawOffer)
|
|
}
|
|
} inject List(Event.DrawOffer(by = none))
|
|
case _ => fuccess(List(Event.ReloadOwner))
|
|
}
|
|
}
|
|
|
|
def claim(pov: Pov)(implicit proxy: GameProxy): Fu[Events] =
|
|
(pov.game.playable && pov.game.history.threefoldRepetition) ?? finisher.other(
|
|
pov.game,
|
|
_.Draw,
|
|
None
|
|
)
|
|
|
|
def force(game: Game)(implicit proxy: GameProxy): Fu[Events] = finisher.other(game, _.Draw, None, None)
|
|
|
|
private def publishDrawOffer(game: Game): Unit = if (game.nonAi) {
|
|
if (game.isCorrespondence)
|
|
Bus.publish(
|
|
lila.hub.actorApi.round.CorresDrawOfferEvent(game.id),
|
|
"offerEventCorres"
|
|
)
|
|
if (lila.game.Game.isBoardCompatible(game))
|
|
Bus.publish(
|
|
lila.game.actorApi.BoardDrawOffer(game),
|
|
lila.game.actorApi.BoardDrawOffer makeChan game.id
|
|
)
|
|
}
|
|
}
|