allow disabling moretime in user settings - closes #5357
parent
f0538e22f6
commit
8308a64713
|
@ -157,6 +157,12 @@ trait SetupHelper { self: I18nHelper =>
|
|||
(Pref.Takeback.CASUAL, trans.inCasualGamesOnly.txt())
|
||||
)
|
||||
|
||||
def translatedMoretimeChoices(implicit ctx: Context) = List(
|
||||
(Pref.Moretime.NEVER, trans.never.txt()),
|
||||
(Pref.Moretime.ALWAYS, trans.always.txt()),
|
||||
(Pref.Moretime.CASUAL, trans.inCasualGamesOnly.txt())
|
||||
)
|
||||
|
||||
def translatedAutoQueenChoices(implicit ctx: Context) = List(
|
||||
(Pref.AutoQueen.NEVER, trans.never.txt()),
|
||||
(Pref.AutoQueen.PREMOVE, trans.whenPremoving.txt()),
|
||||
|
|
|
@ -111,6 +111,10 @@ object pref {
|
|||
trans.takebacksWithOpponentApproval(),
|
||||
radios(form("behavior.takeback"), translatedTakebackChoices)
|
||||
),
|
||||
setting(
|
||||
trans.giveMoreTime(),
|
||||
radios(form("behavior.moretime"), translatedMoretimeChoices)
|
||||
),
|
||||
setting(
|
||||
trans.promoteToQueenAutomatically(),
|
||||
radios(form("behavior.autoQueen"), translatedAutoQueenChoices)
|
||||
|
|
|
@ -31,6 +31,7 @@ object DataForm {
|
|||
"moveEvent" -> optional(number.verifying(Set(0, 1, 2) contains _)),
|
||||
"premove" -> booleanNumber,
|
||||
"takeback" -> checkedNumber(Pref.Takeback.choices),
|
||||
"moretime" -> checkedNumber(Pref.Moretime.choices),
|
||||
"autoQueen" -> checkedNumber(Pref.AutoQueen.choices),
|
||||
"autoThreefold" -> checkedNumber(Pref.AutoThreefold.choices),
|
||||
"submitMove" -> checkedNumber(Pref.SubmitMove.choices),
|
||||
|
@ -65,6 +66,7 @@ object DataForm {
|
|||
moveEvent: Option[Int],
|
||||
premove: Int,
|
||||
takeback: Int,
|
||||
moretime: Int,
|
||||
autoQueen: Int,
|
||||
autoThreefold: Int,
|
||||
submitMove: Int,
|
||||
|
@ -90,6 +92,7 @@ object DataForm {
|
|||
autoQueen = behavior.autoQueen,
|
||||
autoThreefold = behavior.autoThreefold,
|
||||
takeback = behavior.takeback,
|
||||
moretime = behavior.moretime,
|
||||
clockTenths = clockTenths,
|
||||
clockBar = clockBar == 1,
|
||||
clockSound = clockSound == 1,
|
||||
|
@ -135,6 +138,7 @@ object DataForm {
|
|||
moveEvent = pref.moveEvent.some,
|
||||
premove = if (pref.premove) 1 else 0,
|
||||
takeback = pref.takeback,
|
||||
moretime = pref.moretime,
|
||||
autoQueen = pref.autoQueen,
|
||||
autoThreefold = pref.autoThreefold,
|
||||
submitMove = pref.submitMove,
|
||||
|
|
|
@ -19,6 +19,7 @@ object JsonView {
|
|||
"autoQueen" -> p.autoQueen,
|
||||
"autoThreefold" -> p.autoThreefold,
|
||||
"takeback" -> p.takeback,
|
||||
"moretime" -> p.moretime,
|
||||
"clockTenths" -> p.clockTenths,
|
||||
"clockBar" -> p.clockBar,
|
||||
"clockSound" -> p.clockSound,
|
||||
|
|
|
@ -15,6 +15,7 @@ case class Pref(
|
|||
autoQueen: Int,
|
||||
autoThreefold: Int,
|
||||
takeback: Int,
|
||||
moretime: Int,
|
||||
clockTenths: Int,
|
||||
clockBar: Boolean,
|
||||
clockSound: Boolean,
|
||||
|
@ -236,6 +237,18 @@ object Pref {
|
|||
)
|
||||
}
|
||||
|
||||
object Moretime {
|
||||
val NEVER = 1
|
||||
val CASUAL = 2
|
||||
val ALWAYS = 3
|
||||
|
||||
val choices = Seq(
|
||||
NEVER -> "Never",
|
||||
ALWAYS -> "Always",
|
||||
CASUAL -> "In casual games only"
|
||||
)
|
||||
}
|
||||
|
||||
object Animation {
|
||||
val NONE = 0
|
||||
val FAST = 1
|
||||
|
@ -364,6 +377,7 @@ object Pref {
|
|||
autoQueen = AutoQueen.PREMOVE,
|
||||
autoThreefold = AutoThreefold.TIME,
|
||||
takeback = Takeback.ALWAYS,
|
||||
moretime = Moretime.ALWAYS,
|
||||
clockBar = true,
|
||||
clockSound = true,
|
||||
premove = true,
|
||||
|
|
|
@ -42,6 +42,7 @@ final class PrefApi(
|
|||
autoQueen = r.getD("autoQueen", Pref.default.autoQueen),
|
||||
autoThreefold = r.getD("autoThreefold", Pref.default.autoThreefold),
|
||||
takeback = r.getD("takeback", Pref.default.takeback),
|
||||
moretime = r.getD("moretime", Pref.default.moretime),
|
||||
clockTenths = r.getD("clockTenths", Pref.default.clockTenths),
|
||||
clockBar = r.getD("clockBar", Pref.default.clockBar),
|
||||
clockSound = r.getD("clockSound", Pref.default.clockSound),
|
||||
|
@ -84,6 +85,7 @@ final class PrefApi(
|
|||
"autoQueen" -> o.autoQueen,
|
||||
"autoThreefold" -> o.autoThreefold,
|
||||
"takeback" -> o.takeback,
|
||||
"moretime" -> o.moretime,
|
||||
"clockTenths" -> o.clockTenths,
|
||||
"clockBar" -> o.clockBar,
|
||||
"clockSound" -> o.clockSound,
|
||||
|
|
|
@ -8,10 +8,10 @@ import scala.concurrent.duration._
|
|||
import actorApi.{ GetSocketStatus, SocketStatus }
|
||||
|
||||
import lila.game.{ Game, GameRepo, Pov }
|
||||
import lila.hub.actorApi.{ DeployPost, Announce }
|
||||
import lila.hub.actorApi.map.Tell
|
||||
import lila.hub.actorApi.round.{ Abort, Resign, FishnetPlay }
|
||||
import lila.hub.actorApi.socket.HasUserId
|
||||
import lila.hub.actorApi.{ DeployPost, Announce }
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
|
@ -63,13 +63,13 @@ final class Env(
|
|||
private lazy val roundDependencies = Round.Dependencies(
|
||||
messenger = messenger,
|
||||
takebacker = takebacker,
|
||||
moretimer = moretimer,
|
||||
finisher = finisher,
|
||||
rematcher = rematcher,
|
||||
player = player,
|
||||
drawer = drawer,
|
||||
forecastApi = forecastApi,
|
||||
socketMap = socketMap,
|
||||
moretimeDuration = MoretimeDuration
|
||||
socketMap = socketMap
|
||||
)
|
||||
val roundMap = new lila.hub.DuctMap[Round](
|
||||
mkDuct = id => {
|
||||
|
@ -216,7 +216,8 @@ final class Env(
|
|||
noteApi = noteApi,
|
||||
userJsonView = userJsonView,
|
||||
getSocketStatus = getSocketStatus,
|
||||
canTakeback = takebacker.isAllowedByPrefs,
|
||||
canTakeback = takebacker.isAllowedIn,
|
||||
canMoretime = moretimer.isAllowedIn,
|
||||
divider = divider,
|
||||
evalCache = evalCache,
|
||||
baseAnimationDuration = AnimationDuration,
|
||||
|
@ -234,12 +235,17 @@ final class Env(
|
|||
|
||||
private val corresAlarm = new CorresAlarm(system, db(CollectionAlarm), socketMap)
|
||||
|
||||
lazy val takebacker = new Takebacker(
|
||||
private lazy val takebacker = new Takebacker(
|
||||
messenger = messenger,
|
||||
uciMemo = uciMemo,
|
||||
prefApi = prefApi,
|
||||
bus = bus
|
||||
)
|
||||
private lazy val moretimer = new Moretimer(
|
||||
messenger = messenger,
|
||||
prefApi = prefApi,
|
||||
defaultDuration = MoretimeDuration
|
||||
)
|
||||
|
||||
val tvBroadcast = system.actorOf(Props(classOf[TvBroadcast]))
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ final class JsonView(
|
|||
userJsonView: lila.user.JsonView,
|
||||
getSocketStatus: Game.ID => Fu[SocketStatus],
|
||||
canTakeback: Game => Fu[Boolean],
|
||||
canMoretime: Game => Fu[Boolean],
|
||||
divider: lila.game.Divider,
|
||||
evalCache: lila.evalCache.EvalCacheApi,
|
||||
baseAnimationDuration: Duration,
|
||||
|
@ -58,8 +59,9 @@ final class JsonView(
|
|||
): Fu[JsObject] =
|
||||
getSocketStatus(pov.gameId) zip
|
||||
(pov.opponent.userId ?? UserRepo.byId) zip
|
||||
canTakeback(pov.game) map {
|
||||
case ((socket, opponentUser), takebackable) =>
|
||||
canTakeback(pov.game) zip
|
||||
canMoretime(pov.game) map {
|
||||
case socket ~ opponentUser ~ takebackable ~ moretimeable =>
|
||||
import pov._
|
||||
Json.obj(
|
||||
"game" -> gameJson(game, initialFen),
|
||||
|
@ -112,6 +114,7 @@ final class JsonView(
|
|||
).add("clock" -> game.clock.map(clockJson))
|
||||
.add("correspondence" -> game.correspondenceClock)
|
||||
.add("takebackable" -> takebackable)
|
||||
.add("moretimeable" -> moretimeable)
|
||||
.add("crazyhouse" -> pov.game.board.crazyData)
|
||||
.add("possibleMoves" -> possibleMoves(pov, apiVersion))
|
||||
.add("possibleDrops" -> possibleDrops(pov))
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package lila.round
|
||||
|
||||
import chess.Color
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
import lila.game.{ GameRepo, Game, UciMemo, Pov, Rewind, Event, Progress }
|
||||
import lila.pref.{ Pref, PrefApi }
|
||||
|
||||
private final class Moretimer(
|
||||
messenger: Messenger,
|
||||
prefApi: PrefApi,
|
||||
defaultDuration: FiniteDuration
|
||||
) {
|
||||
|
||||
// pov of the player giving more time
|
||||
def apply(pov: Pov): Fu[Option[Progress]] = IfAllowed(pov.game) {
|
||||
(pov.game moretimeable !pov.color) ?? {
|
||||
if (pov.game.hasClock) give(pov.game, List(!pov.color), defaultDuration).some
|
||||
else pov.game.correspondenceClock map { clock =>
|
||||
messenger.system(pov.game, (_.untranslated(s"${!pov.color} gets more time")))
|
||||
val p = pov.game.correspondenceGiveTime
|
||||
p.game.correspondenceClock.map(Event.CorrespondenceClock.apply).fold(p)(p + _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def isAllowedIn(game: Game): Fu[Boolean] =
|
||||
if (game.isMandatory) fuFalse
|
||||
else isAllowedByPrefs(game)
|
||||
|
||||
private[round] def give(game: Game, colors: List[Color], duration: FiniteDuration): Progress =
|
||||
game.clock.fold(Progress(game)) { clock =>
|
||||
val centis = duration.toCentis
|
||||
val newClock = colors.foldLeft(clock) {
|
||||
case (c, color) => c.giveTime(color, centis)
|
||||
}
|
||||
colors.foreach { c =>
|
||||
messenger.system(game, (_.untranslated(s"$c + ${duration.toSeconds} seconds")))
|
||||
}
|
||||
(game withClock newClock) ++ colors.map { Event.ClockInc(_, centis) }
|
||||
}
|
||||
|
||||
private def isAllowedByPrefs(game: Game): Fu[Boolean] =
|
||||
game.userIds.map {
|
||||
prefApi.getPref(_, (p: Pref) => p.moretime)
|
||||
}.sequenceFu map {
|
||||
_.forall { p =>
|
||||
p == Pref.Takeback.ALWAYS || (p == Pref.Takeback.CASUAL && game.casual)
|
||||
}
|
||||
}
|
||||
|
||||
private def IfAllowed[A](game: Game)(f: => A): Fu[A] =
|
||||
if (!game.playable) fufail(ClientError("[moretimer] game is over " + game.id))
|
||||
else if (game.isMandatory) fufail(ClientError("[moretimer] game disallows it " + game.id))
|
||||
else isAllowedByPrefs(game) flatMap {
|
||||
case true => fuccess(f)
|
||||
case _ => fufail(ClientError("[moretimer] disallowed by preferences " + game.id))
|
||||
}
|
||||
}
|
|
@ -162,15 +162,10 @@ private[round] final class Round(
|
|||
}
|
||||
|
||||
case Moretime(playerRef) => handle(playerRef) { pov =>
|
||||
(pov.game moretimeable !pov.color) ?? {
|
||||
val progress =
|
||||
if (pov.game.hasClock) giveMoretime(pov.game, List(!pov.color), moretimeDuration)
|
||||
else pov.game.correspondenceClock.fold(Progress(pov.game)) { clock =>
|
||||
messenger.system(pov.game, (_.untranslated(s"${!pov.color} gets more time")))
|
||||
val p = pov.game.correspondenceGiveTime
|
||||
p.game.correspondenceClock.map(Event.CorrespondenceClock.apply).fold(p)(p + _)
|
||||
}
|
||||
proxy save progress inject progress.events
|
||||
moretimer(pov) flatMap {
|
||||
_ ?? { progress =>
|
||||
proxy save progress inject progress.events
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +182,7 @@ private[round] final class Round(
|
|||
game.playable ?? {
|
||||
val freeTime = 20.seconds
|
||||
messenger.system(game, (_.untranslated("Lichess has been updated! Sorry for the inconvenience.")))
|
||||
val progress = giveMoretime(game, Color.all, freeTime)
|
||||
val progress = moretimer.give(game, Color.all, freeTime)
|
||||
proxy save progress inject progress.events
|
||||
}
|
||||
}
|
||||
|
@ -206,20 +201,6 @@ private[round] final class Round(
|
|||
}
|
||||
}
|
||||
|
||||
private[this] def giveMoretime(game: Game, colors: List[Color], duration: FiniteDuration): Progress =
|
||||
game.clock.fold(Progress(game)) { clock =>
|
||||
val centis = duration.toCentis
|
||||
val newClock = colors.foldLeft(clock) {
|
||||
case (c, color) => c.giveTime(color, centis)
|
||||
}
|
||||
colors.foreach { c =>
|
||||
messenger.system(game, (_.untranslated(
|
||||
"%s + %d seconds".format(c, duration.toSeconds)
|
||||
)))
|
||||
}
|
||||
(game withClock newClock) ++ colors.map { Event.ClockInc(_, centis) }
|
||||
}
|
||||
|
||||
private[this] def recordLag(pov: Pov) =
|
||||
if ((pov.game.playedTurns & 30) == 10) {
|
||||
// Triggers every 32 moves starting on ply 10.
|
||||
|
@ -290,13 +271,13 @@ object Round {
|
|||
private[round] case class Dependencies(
|
||||
messenger: Messenger,
|
||||
takebacker: Takebacker,
|
||||
moretimer: Moretimer,
|
||||
finisher: Finisher,
|
||||
rematcher: Rematcher,
|
||||
player: Player,
|
||||
drawer: Drawer,
|
||||
forecastApi: ForecastApi,
|
||||
socketMap: SocketMap,
|
||||
moretimeDuration: FiniteDuration
|
||||
socketMap: SocketMap
|
||||
)
|
||||
|
||||
private[round] case class TakebackSituation(nbDeclined: Int, lastDeclined: Option[DateTime]) {
|
||||
|
|
|
@ -3,7 +3,7 @@ package lila.round
|
|||
import lila.game.{ GameRepo, Game, UciMemo, Pov, Rewind, Event, Progress }
|
||||
import lila.pref.{ Pref, PrefApi }
|
||||
|
||||
private[round] final class Takebacker(
|
||||
private final class Takebacker(
|
||||
messenger: Messenger,
|
||||
uciMemo: UciMemo,
|
||||
prefApi: PrefApi,
|
||||
|
@ -45,10 +45,14 @@ private[round] final class Takebacker(
|
|||
case _ => fufail(ClientError("[takebacker] invalid no " + pov))
|
||||
}
|
||||
|
||||
def isAllowedByPrefs(game: Game): Fu[Boolean] =
|
||||
def isAllowedIn(game: Game): Fu[Boolean] =
|
||||
if (game.isMandatory) fuFalse
|
||||
else isAllowedByPrefs(game)
|
||||
|
||||
private def isAllowedByPrefs(game: Game): Fu[Boolean] =
|
||||
if (game.hasAi) fuTrue
|
||||
else game.userIds.map { userId =>
|
||||
prefApi.getPref(userId, (p: Pref) => p.takeback)
|
||||
else game.userIds.map {
|
||||
prefApi.getPref(_, (p: Pref) => p.takeback)
|
||||
}.sequenceFu map {
|
||||
_.forall { p =>
|
||||
p == Pref.Takeback.ALWAYS || (p == Pref.Takeback.CASUAL && game.casual)
|
||||
|
@ -65,6 +69,7 @@ private[round] final class Takebacker(
|
|||
|
||||
private def IfAllowed[A](game: Game)(f: => Fu[A]): Fu[A] =
|
||||
if (!game.playable) fufail(ClientError("[takebacker] game is over " + game.id))
|
||||
else if (game.isMandatory) fufail(ClientError("[takebacker] game disallows it " + game.id))
|
||||
else isAllowedByPrefs(game) flatMap {
|
||||
case true => f
|
||||
case _ => fufail(ClientError("[takebacker] disallowed by preferences " + game.id))
|
||||
|
|
|
@ -30,6 +30,7 @@ export interface AnalyseData {
|
|||
orientation: Color;
|
||||
spectator?: boolean; // for compat with GameData, for game functions
|
||||
takebackable: boolean;
|
||||
moretimeable: boolean;
|
||||
analysis?: Analysis;
|
||||
userAnalysis: boolean;
|
||||
forecast?: ForecastData;
|
||||
|
|
|
@ -46,8 +46,6 @@ export function abortable(data: GameData): boolean {
|
|||
export function takebackable(data: GameData): boolean {
|
||||
return playable(data) &&
|
||||
data.takebackable &&
|
||||
!data.tournament &&
|
||||
!data.simul &&
|
||||
bothPlayersHavePlayed(data) &&
|
||||
!data.player.proposingTakeback &&
|
||||
!data.opponent.proposingTakeback;
|
||||
|
@ -73,7 +71,7 @@ export function berserkableBy(data: GameData): boolean {
|
|||
}
|
||||
|
||||
export function moretimeable(data: GameData): boolean {
|
||||
return isPlayerPlaying(data) && !mandatory(data) && (
|
||||
return isPlayerPlaying(data) && data.moretimeable && (
|
||||
!!data.clock ||
|
||||
(!!data.correspondence &&
|
||||
data.correspondence[data.opponent.color] < (data.correspondence.increment - 3600)
|
||||
|
|
|
@ -6,6 +6,7 @@ export interface GameData {
|
|||
tournament?: Tournament;
|
||||
simul?: Simul;
|
||||
takebackable: boolean;
|
||||
moretimeable: boolean;
|
||||
clock?: Clock;
|
||||
correspondence?: CorrespondenceClock;
|
||||
}
|
||||
|
|
|
@ -45,11 +45,13 @@ export function make(send: SocketSend, ctrl: RoundController): RoundSocket {
|
|||
});
|
||||
};
|
||||
|
||||
const d = ctrl.data;
|
||||
|
||||
const handlers: Handlers = {
|
||||
takebackOffers(o) {
|
||||
ctrl.setLoading(false);
|
||||
ctrl.data.player.proposingTakeback = o[ctrl.data.player.color];
|
||||
const fromOp = ctrl.data.opponent.proposingTakeback = o[ctrl.data.opponent.color];
|
||||
d.player.proposingTakeback = o[d.player.color];
|
||||
const fromOp = d.opponent.proposingTakeback = o[d.opponent.color];
|
||||
if (fromOp) notify(ctrl.trans('yourOpponentProposesATakeback'));
|
||||
ctrl.redraw();
|
||||
},
|
||||
|
@ -65,35 +67,34 @@ export function make(send: SocketSend, ctrl: RoundController): RoundSocket {
|
|||
},
|
||||
cclock(o) {
|
||||
if (ctrl.corresClock) {
|
||||
ctrl.data.correspondence.white = o.white;
|
||||
ctrl.data.correspondence.black = o.black;
|
||||
d.correspondence.white = o.white;
|
||||
d.correspondence.black = o.black;
|
||||
ctrl.corresClock.update(o.white, o.black);
|
||||
ctrl.redraw();
|
||||
}
|
||||
},
|
||||
crowd(o) {
|
||||
game.setOnGame(ctrl.data, 'white', o['white']);
|
||||
game.setOnGame(ctrl.data, 'black', o['black']);
|
||||
game.setOnGame(d, 'white', o['white']);
|
||||
game.setOnGame(d, 'black', o['black']);
|
||||
ctrl.redraw();
|
||||
},
|
||||
// end: function(winner) { } // use endData instead
|
||||
endData(o: ApiEnd) {
|
||||
ctrl.endWithData(o);
|
||||
},
|
||||
rematchOffer(by: Color) {
|
||||
ctrl.data.player.offeringRematch = by === ctrl.data.player.color;
|
||||
const fromOp = ctrl.data.opponent.offeringRematch = by === ctrl.data.opponent.color;
|
||||
d.player.offeringRematch = by === d.player.color;
|
||||
const fromOp = d.opponent.offeringRematch = by === d.opponent.color;
|
||||
if (fromOp) notify(ctrl.trans('yourOpponentWantsToPlayANewGameWithYou'));
|
||||
ctrl.redraw();
|
||||
},
|
||||
rematchTaken(nextId: string) {
|
||||
ctrl.data.game.rematch = nextId;
|
||||
if (!ctrl.data.player.spectator) ctrl.setLoading(true);
|
||||
d.game.rematch = nextId;
|
||||
if (!d.player.spectator) ctrl.setLoading(true);
|
||||
else ctrl.redraw();
|
||||
},
|
||||
drawOffer(by) {
|
||||
ctrl.data.player.offeringDraw = by === ctrl.data.player.color;
|
||||
const fromOp = ctrl.data.opponent.offeringDraw = by === ctrl.data.opponent.color;
|
||||
d.player.offeringDraw = by === d.player.color;
|
||||
const fromOp = d.opponent.offeringDraw = by === d.opponent.color;
|
||||
if (fromOp) notify(ctrl.trans('yourOpponentOffersADraw'));
|
||||
ctrl.redraw();
|
||||
},
|
||||
|
@ -101,22 +102,22 @@ export function make(send: SocketSend, ctrl: RoundController): RoundSocket {
|
|||
ctrl.setBerserk(color);
|
||||
},
|
||||
gone(isGone) {
|
||||
if (!ctrl.data.opponent.ai) {
|
||||
game.setIsGone(ctrl.data, ctrl.data.opponent.color, isGone);
|
||||
if (!d.opponent.ai) {
|
||||
game.setIsGone(d, d.opponent.color, isGone);
|
||||
ctrl.redraw();
|
||||
}
|
||||
},
|
||||
checkCount(e) {
|
||||
ctrl.data.player.checks = ctrl.data.player.color == 'white' ? e.white : e.black;
|
||||
ctrl.data.opponent.checks = ctrl.data.opponent.color == 'white' ? e.white : e.black;
|
||||
d.player.checks = d.player.color == 'white' ? e.white : e.black;
|
||||
d.opponent.checks = d.opponent.color == 'white' ? e.white : e.black;
|
||||
ctrl.redraw();
|
||||
},
|
||||
simulPlayerMove(gameId: string) {
|
||||
if (
|
||||
ctrl.opts.userId &&
|
||||
ctrl.data.simul &&
|
||||
ctrl.opts.userId == ctrl.data.simul.hostId &&
|
||||
gameId !== ctrl.data.game.id &&
|
||||
d.simul &&
|
||||
ctrl.opts.userId == d.simul.hostId &&
|
||||
gameId !== d.game.id &&
|
||||
ctrl.moveOn.get() &&
|
||||
ctrl.chessground.state.turnColor !== ctrl.chessground.state.movable.color) {
|
||||
ctrl.setRedirecting();
|
||||
|
@ -140,7 +141,7 @@ export function make(send: SocketSend, ctrl: RoundController): RoundSocket {
|
|||
send,
|
||||
handlers,
|
||||
moreTime: throttle(300, () => send('moretime')),
|
||||
outoftime: throttle(500, () => send('flag', ctrl.data.game.player)),
|
||||
outoftime: throttle(500, () => send('flag', d.game.player)),
|
||||
berserk: throttle(200, () => send('berserk', null, { ackable: true })),
|
||||
sendLoading(typ: string, data?: any) {
|
||||
ctrl.setLoading(true);
|
||||
|
|
Loading…
Reference in New Issue