make sandbagging playbanable

cli
Thibault Duplessis 2017-10-18 18:16:52 -05:00
parent 04b5ef62ee
commit 8e300ddb88
4 changed files with 36 additions and 23 deletions

View File

@ -77,27 +77,37 @@ final class PlaybanApi(
if lastMovetime.toSeconds >= limit
} yield save(Outcome.SitMoving)(userId)
sandbag(game, flaggerColor) >> IfBlameable(game) {
goodFinish(game, !flaggerColor) >> { // winner gets a good game result
sitting orElse
sitMoving getOrElse
goodFinish(game, flaggerColor)
sandbag(game, flaggerColor) flatMap { isSandbag =>
IfBlameable(game) {
goodOrSandbag(game, !flaggerColor, false) >> { // winner gets a good game result
sitting orElse
sitMoving getOrElse
goodOrSandbag(game, flaggerColor, isSandbag)
}
}
}
}
def other(game: Game, status: Status.type => Status, winner: Option[Color]): Funit =
winner.?? { w => sandbag(game, !w) } >> IfBlameable(game) {
((for {
w <- winner
loserId <- game.player(!w).userId
if Status.NoStart is status
} yield List(save(Outcome.NoPlay)(loserId), goodFinish(game, w))) |
game.userIds.map(save(Outcome.Good))).sequenceFu.void
winner.?? { w => sandbag(game, !w) } flatMap { isSandbag =>
IfBlameable(game) {
((for {
w <- winner
loserId <- game.player(!w).userId
if Status.NoStart is status
} yield List(
save(Outcome.NoPlay)(loserId),
goodOrSandbag(game, w, false)
)) | Color.all.map { c =>
goodOrSandbag(game, c, winner.exists(c!=))
}).sequenceFu.void
}
}
private def goodFinish(game: Game, color: Color): Funit =
~(game.player(color).userId.map(save(Outcome.Good)))
private def goodOrSandbag(game: Game, color: Color, isSandbag: Boolean): Funit =
game.player(color).userId ?? {
save(if (isSandbag) Outcome.Sandbag else Outcome.Good)
}
def currentBan(userId: String): Fu[Option[TempBan]] = coll.find(
$doc("_id" -> userId, "b.0" $exists true),

View File

@ -3,23 +3,23 @@ package lila.playban
import com.github.blemale.scaffeine.{ Cache, Scaffeine }
import scala.concurrent.duration._
import chess.Color
import lila.game.{ Game, Pov }
import lila.message.{ MessageApi, ModPreset }
import lila.user.{ User, UserRepo }
import chess.Color
private final class SandbagWatch(messenger: MessageApi) {
import SandbagWatch._
def apply(game: Game, loser: Color): Funit = game.rated ?? {
def apply(game: Game, loser: Color): Fu[Boolean] = game.rated ?? {
game.userIds.map { userId =>
(records getIfPresent userId, isSandbag(game, loser, userId)) match {
case (None, false) => funit
case (Some(record), false) => updateRecord(userId, record + Good)
case (record, true) => updateRecord(userId, (record | newRecord) + Sandbag)
}
}.sequenceFu.void
}.sequenceFu.void inject isSandbag(game)
}
private def sendMessage(userId: User.ID): Funit = for {
@ -43,12 +43,14 @@ private final class SandbagWatch(messenger: MessageApi) {
.build[User.ID, Record]
private def isSandbag(game: Game, loser: Color, userId: User.ID): Boolean =
game.playerByUserId(userId).exists { player =>
player == game.player(loser) && game.turns <= {
if (game.variant == chess.variant.Atomic) 3
else 6
}
game.playerByUserId(userId).exists {
_ == game.player(loser) && isSandbag(game)
}
private def isSandbag(game: Game): Boolean = game.turns <= {
if (game.variant == chess.variant.Atomic) 3
else 6
}
}
private object SandbagWatch {

View File

@ -69,6 +69,7 @@ object Outcome {
case object RageQuit extends Outcome(3, "Quits without resigning")
case object Sitting extends Outcome(4, "Lets time run out")
case object SitMoving extends Outcome(5, "Waits then moves at last moment")
case object Sandbag extends Outcome(6, "Deliberately lost the game")
val all = List(Good, Abort, NoPlay, RageQuit, Sitting, SitMoving)

View File

@ -74,7 +74,7 @@ export function main(ctrl: RoundController): VNode {
score = util.getScore(pieces) * (bottomColor === 'white' ? 1 : -1);
} else material = emptyMaterialDiff;
return h('div.round.cg-512', [
h('div.lichess_game.variant_' + d.game.variant.key, {
h('div.lichess_game.gotomove.variant_' + d.game.variant.key, {
hook: {
insert: () => window.lichess.pubsub.emit('content_loaded')()
}