Merge pull request #5455 from ornicar/arena-stallers
Automatically pause stallers in arenas
This commit is contained in:
commit
579448cec6
|
@ -87,7 +87,9 @@ final class PlaybanApi(
|
|||
seconds = nowSeconds - game.movedAt.getSeconds
|
||||
limit <- unreasonableTime
|
||||
if seconds >= limit
|
||||
} yield save(Outcome.Sitting, userId, roughWinEstimate(game, flaggerColor)) >>- feedback.sitting(Pov(game, flaggerColor))
|
||||
} yield save(Outcome.Sitting, userId, roughWinEstimate(game, flaggerColor)) >>-
|
||||
feedback.sitting(Pov(game, flaggerColor)) >>-
|
||||
propagateSitting(game, userId)
|
||||
|
||||
// flagged after waiting a short time;
|
||||
// but the previous move used a long time.
|
||||
|
@ -98,7 +100,9 @@ final class PlaybanApi(
|
|||
lastMovetime <- movetimes.lastOption
|
||||
limit <- unreasonableTime
|
||||
if lastMovetime.toSeconds >= limit
|
||||
} yield save(Outcome.SitMoving, userId, roughWinEstimate(game, flaggerColor)) >>- feedback.sitting(Pov(game, flaggerColor))
|
||||
} yield save(Outcome.SitMoving, userId, roughWinEstimate(game, flaggerColor)) >>-
|
||||
feedback.sitting(Pov(game, flaggerColor)) >>-
|
||||
propagateSitting(game, userId)
|
||||
|
||||
sandbag(game, flaggerColor) flatMap { isSandbag =>
|
||||
IfBlameable(game) {
|
||||
|
@ -109,6 +113,13 @@ final class PlaybanApi(
|
|||
}
|
||||
}
|
||||
|
||||
def propagateSitting(game: Game, userId: String) =
|
||||
sitAndDcCounter(userId) map { counter =>
|
||||
if (counter <= -5) {
|
||||
bus.publish(SittingDetected(game, userId), 'playban)
|
||||
}
|
||||
}
|
||||
|
||||
def other(game: Game, status: Status.type => Status, winner: Option[Color]): Funit =
|
||||
winner.?? { w => sandbag(game, !w) } flatMap { isSandbag =>
|
||||
IfBlameable(game) {
|
||||
|
|
|
@ -3,6 +3,8 @@ package lila.playban
|
|||
import org.joda.time.DateTime
|
||||
import play.api.libs.json._
|
||||
|
||||
import lila.game.Game
|
||||
|
||||
case class UserRecord(
|
||||
_id: String,
|
||||
o: Option[List[Outcome]],
|
||||
|
@ -117,3 +119,5 @@ object Outcome {
|
|||
|
||||
def apply(id: Int): Option[Outcome] = byId get id
|
||||
}
|
||||
|
||||
case class SittingDetected(game: Game, userId: String)
|
||||
|
|
|
@ -15,6 +15,8 @@ private[tournament] final class ApiActor(
|
|||
|
||||
case FinishGame(game, _, _) => api finishGame game
|
||||
|
||||
case lila.playban.SittingDetected(game, player) => api.sittingDetected(game, player)
|
||||
|
||||
case lila.hub.actorApi.mod.MarkCheater(userId, true) =>
|
||||
leaderboard.getAndDeleteRecent(userId, DateTime.now minusDays 3) foreach {
|
||||
api.ejectLame(userId, _)
|
||||
|
|
|
@ -247,21 +247,24 @@ final class TournamentApi(
|
|||
TournamentRepo tourIdsToWithdrawWhenEntering tourId foreach {
|
||||
PlayerRepo.filterExists(_, userId) foreach {
|
||||
_ foreach {
|
||||
withdraw(_, userId, isPause = false)
|
||||
withdraw(_, userId, isPause = false, isStalling = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def selfPause(tourId: Tournament.ID, userId: User.ID): Unit =
|
||||
withdraw(tourId, userId, isPause = true)
|
||||
withdraw(tourId, userId, isPause = true, isStalling = false)
|
||||
|
||||
private def withdraw(tourId: Tournament.ID, userId: User.ID, isPause: Boolean): Unit = {
|
||||
private def stallPause(tourId: Tournament.ID, userId: User.ID): Unit =
|
||||
withdraw(tourId, userId, isPause = false, isStalling = true)
|
||||
|
||||
private def withdraw(tourId: Tournament.ID, userId: User.ID, isPause: Boolean, isStalling: Boolean): Unit = {
|
||||
Sequencing(tourId)(TournamentRepo.enterableById) {
|
||||
case tour if tour.isCreated =>
|
||||
PlayerRepo.remove(tour.id, userId) >> updateNbPlayers(tour.id) >>- socketReload(tour.id) >>- publish()
|
||||
case tour if tour.isStarted => for {
|
||||
_ <- PlayerRepo.withdraw(tour.id, userId)
|
||||
pausable <- isPause ?? cached.ranking(tour).map { _ get userId exists (7>) }
|
||||
pausable <- if (isPause) cached.ranking(tour).map { _ get userId exists (7>) } else fuccess(isStalling)
|
||||
} yield {
|
||||
if (pausable) pause.add(userId, tour)
|
||||
socketReload(tour.id)
|
||||
|
@ -275,7 +278,7 @@ final class TournamentApi(
|
|||
TournamentRepo.nonEmptyEnterableIds foreach {
|
||||
PlayerRepo.filterExists(_, user.id) foreach {
|
||||
_ foreach {
|
||||
withdraw(_, user.id, isPause = false)
|
||||
withdraw(_, user.id, isPause = false, isStalling = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,6 +314,11 @@ final class TournamentApi(
|
|||
}
|
||||
}
|
||||
|
||||
def sittingDetected(game: Game, player: User.ID): Unit =
|
||||
game.tournamentId foreach { tourId =>
|
||||
stallPause(tourId, player)
|
||||
}
|
||||
|
||||
private def updatePlayer(
|
||||
tour: Tournament,
|
||||
finishing: Option[Game] // if set, update the player performance. Leave to none to just recompute the sheet.
|
||||
|
@ -349,7 +357,7 @@ final class TournamentApi(
|
|||
if game.status == chess.Status.NoStart
|
||||
player <- game.playerWhoDidNotMove
|
||||
userId <- player.userId
|
||||
} withdraw(tourId, userId, isPause = false)
|
||||
} withdraw(tourId, userId, isPause = false, isStalling = false)
|
||||
|
||||
def pausePlaybanned(userId: User.ID) =
|
||||
TournamentRepo.startedIds flatMap {
|
||||
|
|
Loading…
Reference in a new issue