Remove previous cheat evaluator. Farewell, good cop, you did a great job
parent
49d3f497ca
commit
fb85cd0207
|
@ -16,9 +16,6 @@
|
||||||
[submodule "submodules/boardcreator"]
|
[submodule "submodules/boardcreator"]
|
||||||
path = submodules/boardcreator
|
path = submodules/boardcreator
|
||||||
url = https://github.com/clarkerubber/board-creator
|
url = https://github.com/clarkerubber/board-creator
|
||||||
[submodule "submodules/evaluator"]
|
|
||||||
path = submodules/evaluator
|
|
||||||
url = https://github.com/ornicar/engine-evaluator
|
|
||||||
[submodule "ui/chessli"]
|
[submodule "ui/chessli"]
|
||||||
path = ui/chessli
|
path = ui/chessli
|
||||||
url = https://github.com/ornicar/chess.js
|
url = https://github.com/ornicar/chess.js
|
||||||
|
|
|
@ -65,7 +65,6 @@ final class Env(
|
||||||
Env.notification,
|
Env.notification,
|
||||||
Env.bookmark,
|
Env.bookmark,
|
||||||
Env.pref,
|
Env.pref,
|
||||||
Env.evaluation,
|
|
||||||
Env.chat,
|
Env.chat,
|
||||||
Env.puzzle,
|
Env.puzzle,
|
||||||
Env.tv,
|
Env.tv,
|
||||||
|
@ -119,7 +118,6 @@ object Env {
|
||||||
def relation = lila.relation.Env.current
|
def relation = lila.relation.Env.current
|
||||||
def report = lila.report.Env.current
|
def report = lila.report.Env.current
|
||||||
def pref = lila.pref.Env.current
|
def pref = lila.pref.Env.current
|
||||||
def evaluation = lila.evaluation.Env.current
|
|
||||||
def chat = lila.chat.Env.current
|
def chat = lila.chat.Env.current
|
||||||
def puzzle = lila.puzzle.Env.current
|
def puzzle = lila.puzzle.Env.current
|
||||||
def coordinate = lila.coordinate.Env.current
|
def coordinate = lila.coordinate.Env.current
|
||||||
|
|
|
@ -147,18 +147,12 @@ object User extends LilaController {
|
||||||
|
|
||||||
def mod(username: String) = Secure(_.UserSpy) { implicit ctx =>
|
def mod(username: String) = Secure(_.UserSpy) { implicit ctx =>
|
||||||
me => OptionFuOk(UserRepo named username) { user =>
|
me => OptionFuOk(UserRepo named username) { user =>
|
||||||
(Env.evaluation.evaluator find user) zip (Env.security userSpy user.id) zip (Env.mod.assessApi.getPlayerAggregateAssessment(user.id)) map {
|
(Env.security userSpy user.id) zip (Env.mod.assessApi.getPlayerAggregateAssessment(user.id)) map {
|
||||||
case ((eval, spy), playerAggregateAssessment) => html.user.mod(user, spy, eval, playerAggregateAssessment)
|
case (spy, playerAggregateAssessment) => html.user.mod(user, spy, playerAggregateAssessment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def evaluate(username: String) = Secure(_.UserEvaluate) { implicit ctx =>
|
|
||||||
me => OptionFuResult(UserRepo named username) { user =>
|
|
||||||
Env.evaluation.evaluator.generate(user.id, true) inject Redirect(routes.User.show(username).url + "?mod")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def writeNote(username: String) = AuthBody { implicit ctx =>
|
def writeNote(username: String) = AuthBody { implicit ctx =>
|
||||||
me => OptionFuResult(UserRepo named username) { user =>
|
me => OptionFuResult(UserRepo named username) { user =>
|
||||||
implicit val req = ctx.body
|
implicit val req = ctx.body
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
@(u: User, spy: lila.security.UserSpy, eval: Option[lila.evaluation.Evaluation], optionAggregateAssessment: Option[lila.evaluation.PlayerAggregateAssessment])(implicit ctx: Context)
|
@(u: User, spy: lila.security.UserSpy, optionAggregateAssessment: Option[lila.evaluation.PlayerAggregateAssessment])(implicit ctx: Context)
|
||||||
|
|
||||||
@import lila.evaluation.Display
|
@import lila.evaluation.Display
|
||||||
|
|
||||||
<div class="actions clearfix">
|
<div class="actions clearfix">
|
||||||
@if(isGranted(_.UserEvaluate)) {
|
@if(isGranted(_.UserEvaluate)) {
|
||||||
<form method="post" action="@routes.User.evaluate(u.username)">
|
|
||||||
<input class="button" type="submit" value="@{eval.isDefined.??("(Re)")}Evaluate (old)" />
|
|
||||||
</form>
|
|
||||||
<form method="post" action="@routes.Mod.refreshUserAssess(u.username)">
|
<form method="post" action="@routes.Mod.refreshUserAssess(u.username)">
|
||||||
<input class="button" type="submit" value="Evaluate (new)" />
|
<input class="button" type="submit" value="Evaluate" />
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
@if(isGranted(_.MarkEngine)) {
|
@if(isGranted(_.MarkEngine)) {
|
||||||
|
@ -52,39 +49,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="user_spy">
|
<div class="user_spy">
|
||||||
@eval.map { e =>
|
|
||||||
<div class="evaluation">
|
|
||||||
<p>
|
|
||||||
<strong>@e.verdict(u.perfs)</strong> @e.isDeep.fold("Thoroughly", "Quickly") evaluated @momentFromNow(e.date) as @e.percent%
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
</p>
|
|
||||||
@if(e.games.nonEmpty) {
|
|
||||||
<table class="slist">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Most suspicious games found</th>
|
|
||||||
<th>Move time</th>
|
|
||||||
<th>Blur</th>
|
|
||||||
<th>Analysis</th>
|
|
||||||
<th>Bot</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@e.games.map { g =>
|
|
||||||
<tr>
|
|
||||||
<td><a href="@g.path">@g.path</a></td>
|
|
||||||
<td>@g.moveTime.map(_ + "%")</td>
|
|
||||||
<td>@g.blur.map(_ + "%")</td>
|
|
||||||
<td>@g.error.map(_ + "%")</td>
|
|
||||||
<td>@g.hold.map(_ + "%")</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@optionAggregateAssessment.fold{
|
@optionAggregateAssessment.fold{
|
||||||
<div class="evaluation">
|
<div class="evaluation">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -30,7 +30,6 @@ GET /rel/blocks controllers.Relation.blocks
|
||||||
# User
|
# User
|
||||||
GET /@/:username/opponents controllers.User.opponents(username: String)
|
GET /@/:username/opponents controllers.User.opponents(username: String)
|
||||||
GET /@/:username/mod controllers.User.mod(username: String)
|
GET /@/:username/mod controllers.User.mod(username: String)
|
||||||
POST /@/:username/evaluate controllers.User.evaluate(username: String)
|
|
||||||
POST /@/:username/note controllers.User.writeNote(username: String)
|
POST /@/:username/note controllers.User.writeNote(username: String)
|
||||||
GET /@/:username/mini controllers.User.showMini(username: String)
|
GET /@/:username/mini controllers.User.showMini(username: String)
|
||||||
GET /@/:username/tv controllers.User.tv(username: String)
|
GET /@/:username/tv controllers.User.tv(username: String)
|
||||||
|
|
|
@ -20,7 +20,6 @@ case class ConcurrentAnalysisException(userId: String, progressId: String, gameI
|
||||||
final class Analyser(
|
final class Analyser(
|
||||||
ai: ActorSelection,
|
ai: ActorSelection,
|
||||||
indexer: ActorSelection,
|
indexer: ActorSelection,
|
||||||
evaluator: ActorSelection,
|
|
||||||
modActor: ActorSelection) {
|
modActor: ActorSelection) {
|
||||||
|
|
||||||
def get(id: String): Fu[Option[Analysis]] = AnalysisRepo byId id flatMap evictStalled
|
def get(id: String): Fu[Option[Analysis]] = AnalysisRepo byId id flatMap evictStalled
|
||||||
|
@ -77,9 +76,6 @@ final class Analyser(
|
||||||
if (analysis.valid) {
|
if (analysis.valid) {
|
||||||
indexer ! InsertGame(game)
|
indexer ! InsertGame(game)
|
||||||
AnalysisRepo.done(id, analysis) >>- {
|
AnalysisRepo.done(id, analysis) >>- {
|
||||||
game.userIds foreach { userId =>
|
|
||||||
evaluator ! lila.hub.actorApi.evaluation.Refresh(userId)
|
|
||||||
}
|
|
||||||
modActor ! actorApi.AnalysisReady(game, analysis)
|
modActor ! actorApi.AnalysisReady(game, analysis)
|
||||||
} >>- GameRepo.setAnalysed(game.id) inject analysis
|
} >>- GameRepo.setAnalysed(game.id) inject analysis
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ final class Env(
|
||||||
ai: ActorSelection,
|
ai: ActorSelection,
|
||||||
system: ActorSystem,
|
system: ActorSystem,
|
||||||
indexer: ActorSelection,
|
indexer: ActorSelection,
|
||||||
evaluator: ActorSelection,
|
|
||||||
modActor: ActorSelection) {
|
modActor: ActorSelection) {
|
||||||
|
|
||||||
private val CollectionAnalysis = config getString "collection.analysis"
|
private val CollectionAnalysis = config getString "collection.analysis"
|
||||||
|
@ -28,7 +27,6 @@ final class Env(
|
||||||
lazy val analyser = new Analyser(
|
lazy val analyser = new Analyser(
|
||||||
ai = ai,
|
ai = ai,
|
||||||
indexer = indexer,
|
indexer = indexer,
|
||||||
evaluator = evaluator,
|
|
||||||
modActor = modActor)
|
modActor = modActor)
|
||||||
|
|
||||||
lazy val paginator = new PaginatorBuilder(
|
lazy val paginator = new PaginatorBuilder(
|
||||||
|
@ -66,6 +64,5 @@ object Env {
|
||||||
ai = lila.hub.Env.current.actor.ai,
|
ai = lila.hub.Env.current.actor.ai,
|
||||||
system = lila.common.PlayApp.system,
|
system = lila.common.PlayApp.system,
|
||||||
indexer = lila.hub.Env.current.actor.gameIndexer,
|
indexer = lila.hub.Env.current.actor.gameIndexer,
|
||||||
evaluator = lila.hub.Env.current.actor.evaluator,
|
|
||||||
modActor = lila.hub.Env.current.actor.mod)
|
modActor = lila.hub.Env.current.actor.mod)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
package lila.evaluation
|
|
||||||
|
|
||||||
import akka.actor._
|
|
||||||
import com.typesafe.config.Config
|
|
||||||
|
|
||||||
final class Env(
|
|
||||||
config: Config,
|
|
||||||
db: lila.db.Env,
|
|
||||||
hub: lila.hub.Env,
|
|
||||||
system: ActorSystem) {
|
|
||||||
|
|
||||||
private val CollectionEvaluation = config getString "collection.evaluation"
|
|
||||||
private val EvaluatorExecPath = config getString "evaluator.exec_path"
|
|
||||||
private val ActorName = config getString "actor.name"
|
|
||||||
private val ApiToken = config getString "api.token"
|
|
||||||
private val ApiUrl = config getString "api.url"
|
|
||||||
|
|
||||||
lazy val evaluator = new Evaluator(
|
|
||||||
coll = db(CollectionEvaluation),
|
|
||||||
execPath = EvaluatorExecPath,
|
|
||||||
reporter = hub.actor.report,
|
|
||||||
analyser = hub.actor.analyser,
|
|
||||||
marker = hub.actor.mod,
|
|
||||||
token = ApiToken,
|
|
||||||
apiUrl = ApiUrl)
|
|
||||||
|
|
||||||
system.actorOf(Props(new Listener(evaluator)), name = ActorName)
|
|
||||||
}
|
|
||||||
|
|
||||||
object Env {
|
|
||||||
|
|
||||||
lazy val current = "[boot] evaluation" describes new Env(
|
|
||||||
config = lila.common.PlayApp loadConfig "evaluation",
|
|
||||||
db = lila.db.Env.current,
|
|
||||||
hub = lila.hub.Env.current,
|
|
||||||
system = lila.common.PlayApp.system)
|
|
||||||
}
|
|
|
@ -1,142 +0,0 @@
|
||||||
package lila.evaluation
|
|
||||||
|
|
||||||
import scala.util.{ Try, Success, Failure }
|
|
||||||
|
|
||||||
import akka.actor.ActorSelection
|
|
||||||
import akka.pattern.ask
|
|
||||||
import org.joda.time.DateTime
|
|
||||||
import play.api.libs.json._
|
|
||||||
import play.api.libs.json.Json
|
|
||||||
import play.modules.reactivemongo.json.ImplicitBSONHandlers._
|
|
||||||
import reactivemongo.bson._
|
|
||||||
|
|
||||||
import lila.db.api._
|
|
||||||
import lila.db.BSON.BSONJodaDateTimeHandler
|
|
||||||
import lila.db.JsTube.Helpers.{ rename, writeDate, readDate }
|
|
||||||
import lila.db.Types._
|
|
||||||
import lila.rating.{ Perf, PerfType }
|
|
||||||
import lila.user.{ User, UserRepo, Perfs }
|
|
||||||
|
|
||||||
final class Evaluator(
|
|
||||||
coll: Coll,
|
|
||||||
execPath: String,
|
|
||||||
reporter: ActorSelection,
|
|
||||||
analyser: ActorSelection,
|
|
||||||
marker: ActorSelection,
|
|
||||||
token: String,
|
|
||||||
apiUrl: String) {
|
|
||||||
|
|
||||||
import Evaluation._, heuristics._
|
|
||||||
|
|
||||||
def find(user: User): Fu[Option[Evaluation]] =
|
|
||||||
coll.find(BSONDocument("_id" -> user.id)).one[JsObject] map { _ map readEvaluation }
|
|
||||||
|
|
||||||
def evaluatedAt(user: User): Fu[Option[DateTime]] =
|
|
||||||
coll.find(
|
|
||||||
BSONDocument("_id" -> user.id),
|
|
||||||
BSONDocument("date" -> true)
|
|
||||||
).one[BSONDocument] map { _ flatMap (_.getAs[DateTime]("date")) }
|
|
||||||
|
|
||||||
def generate(userId: String, deep: Boolean): Fu[Option[Evaluation]] =
|
|
||||||
UserRepo byId userId flatMap {
|
|
||||||
_ ?? { user =>
|
|
||||||
(run(userId, deep) match {
|
|
||||||
case Failure(e: Exception) if e.getMessage.contains("exit value: 1") => fuccess(none)
|
|
||||||
case Failure(e: Exception) if e.getMessage.contains("exit value: 2") => fuccess(none)
|
|
||||||
case Failure(e: Exception) => fufail(e)
|
|
||||||
case Success(output) => for {
|
|
||||||
evalJs ← (Json parse output).transform(evaluationTransformer) match {
|
|
||||||
case JsSuccess(v, _) => fuccess(v)
|
|
||||||
case JsError(e) => fufail(lila.common.LilaException(s"Can't parse evaluator output: $e on $output"))
|
|
||||||
}
|
|
||||||
eval = readEvaluation(evalJs)
|
|
||||||
_ ← coll.update(Json.obj("_id" -> userId), evalJs, upsert = true)
|
|
||||||
} yield eval.some
|
|
||||||
}) andThen {
|
|
||||||
case Success(Some(eval)) if Evaluation.watchPerfs(user.perfs) exists eval.mark =>
|
|
||||||
UserRepo byId userId foreach {
|
|
||||||
_ filterNot (_.engine) foreach { user =>
|
|
||||||
marker ! lila.hub.actorApi.mod.MarkCheater(user.id)
|
|
||||||
reporter ! lila.hub.actorApi.report.Check(user.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Failure(e) => logger.warn(s"generate: $e")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private[evaluation] def autoGenerate(
|
|
||||||
user: User,
|
|
||||||
perfType: PerfType,
|
|
||||||
important: Boolean,
|
|
||||||
forceRefresh: Boolean,
|
|
||||||
suspiciousHold: Boolean) {
|
|
||||||
val perf = user.perfs(perfType)
|
|
||||||
if (!user.engine && (
|
|
||||||
important || suspiciousHold ||
|
|
||||||
(deviationIsLow(perf) && (progressIsHigh(perf) || ratingIsHigh(perf)))
|
|
||||||
)) {
|
|
||||||
evaluatedAt(user) foreach { date =>
|
|
||||||
def freshness = if (progressIsVeryHigh(perf)) DateTime.now minusMinutes 20
|
|
||||||
else if (progressIsHigh(perf)) DateTime.now minusHours 1
|
|
||||||
else DateTime.now minusDays 2
|
|
||||||
if (suspiciousHold || forceRefresh || date.fold(true)(_ isBefore freshness)) {
|
|
||||||
generate(user.id, true) foreach {
|
|
||||||
_ foreach { eval =>
|
|
||||||
eval.gameIdsToAnalyse foreach { gameId =>
|
|
||||||
analyser ! lila.hub.actorApi.ai.AutoAnalyse(gameId)
|
|
||||||
if (eval report perf)
|
|
||||||
reporter ! lila.hub.actorApi.report.Cheater(user.id, eval reportText 3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private[evaluation] def autoGenerate(
|
|
||||||
user: User,
|
|
||||||
important: Boolean,
|
|
||||||
forceRefresh: Boolean,
|
|
||||||
suspiciousHold: Boolean) {
|
|
||||||
user.perfs.bestPerf foreach {
|
|
||||||
case (pt, _) => autoGenerate(user, pt, important, forceRefresh, suspiciousHold)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private[evaluation] def autoGenerate(userId: String, important: Boolean, forceRefresh: Boolean) {
|
|
||||||
UserRepo byId userId foreach {
|
|
||||||
_ foreach { autoGenerate(_, important, forceRefresh, false) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private def readEvaluation(js: JsValue): Evaluation =
|
|
||||||
(readDate('date) andThen Evaluation.reader) reads js match {
|
|
||||||
case JsSuccess(v, _) => v
|
|
||||||
case JsError(e) => throw lila.common.LilaException(s"Can't parse evaluator json: $e on $js")
|
|
||||||
}
|
|
||||||
|
|
||||||
private def run(userId: String, deep: Boolean): Try[String] = {
|
|
||||||
import scala.sys.process._
|
|
||||||
import java.io.File
|
|
||||||
val exec = Process(Seq("php", "engine-evaluator.php", userId, deep.fold("true", "false"), token, s"$apiUrl/"), new File(execPath))
|
|
||||||
Try {
|
|
||||||
exec.!!
|
|
||||||
} match {
|
|
||||||
case Failure(e) => Failure(new Exception(s"$exec $e"))
|
|
||||||
case x => x
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private def evaluationTransformer =
|
|
||||||
rename('userId, '_id) andThen
|
|
||||||
rename('cheatIndex, 'shallow) andThen
|
|
||||||
rename('deepIndex, 'deep) andThen
|
|
||||||
rename('computerAnalysis, 'analysis) andThen
|
|
||||||
rename('knownEngineIP, 'sharedIP) andThen
|
|
||||||
__.json.update(
|
|
||||||
__.read[JsObject].map { o => o ++ Json.obj("date" -> $date(DateTime.now)) }
|
|
||||||
) andThen
|
|
||||||
(__ \ 'Error).json.prune
|
|
||||||
|
|
||||||
private val logger = play.api.Logger("evaluator")
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package lila.evaluation
|
|
||||||
|
|
||||||
import akka.actor._
|
|
||||||
import lila.game.PerfPicker
|
|
||||||
import chess.{ Speed, White, Black }
|
|
||||||
import lila.hub.actorApi.evaluation._
|
|
||||||
import lila.user.User
|
|
||||||
import lila.rating.PerfType
|
|
||||||
|
|
||||||
private[evaluation] final class Listener(evaluator: Evaluator) extends Actor {
|
|
||||||
|
|
||||||
context.system.lilaBus.subscribe(self, 'finishGame)
|
|
||||||
|
|
||||||
def receive = {
|
|
||||||
|
|
||||||
case lila.game.actorApi.FinishGame(game, white, black) =>
|
|
||||||
PerfType(PerfPicker key game) ifTrue game.rated map { perfType =>
|
|
||||||
List(
|
|
||||||
game.whitePlayer -> white,
|
|
||||||
game.blackPlayer -> black
|
|
||||||
) foreach {
|
|
||||||
case (p, Some(u)) => evaluator.autoGenerate(
|
|
||||||
user = u,
|
|
||||||
perfType = perfType,
|
|
||||||
important = p.wins && game.isTournament && game.speed != Speed.Bullet,
|
|
||||||
forceRefresh = false,
|
|
||||||
suspiciousHold = p.hasSuspiciousHoldAlert)
|
|
||||||
case _ =>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case user: User => evaluator.generate(user.id, true)
|
|
||||||
|
|
||||||
case AutoCheck(userId) => evaluator.autoGenerate(userId, true, false)
|
|
||||||
|
|
||||||
case Refresh(userId) => evaluator.autoGenerate(userId, false, true)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -27,7 +27,6 @@ final class Env(config: Config, system: ActorSystem) {
|
||||||
val challenger = select("actor.challenger")
|
val challenger = select("actor.challenger")
|
||||||
val report = select("actor.report")
|
val report = select("actor.report")
|
||||||
val mod = select("actor.mod")
|
val mod = select("actor.mod")
|
||||||
val evaluator = select("actor.evaluator")
|
|
||||||
val chat = select("actor.chat")
|
val chat = select("actor.chat")
|
||||||
val analyser = select("actor.analyser")
|
val analyser = select("actor.analyser")
|
||||||
val moveBroadcast = select("actor.move_broadcast")
|
val moveBroadcast = select("actor.move_broadcast")
|
||||||
|
|
|
@ -16,7 +16,7 @@ final class Env(
|
||||||
|
|
||||||
lazy val forms = new DataForm(hub.actor.captcher)
|
lazy val forms = new DataForm(hub.actor.captcher)
|
||||||
|
|
||||||
lazy val api = new ReportApi(hub.actor.evaluator)
|
lazy val api = new ReportApi
|
||||||
|
|
||||||
// api actor
|
// api actor
|
||||||
system.actorOf(Props(new Actor {
|
system.actorOf(Props(new Actor {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import lila.db.Implicits._
|
||||||
import lila.user.{ User, UserRepo }
|
import lila.user.{ User, UserRepo }
|
||||||
import tube.reportTube
|
import tube.reportTube
|
||||||
|
|
||||||
private[report] final class ReportApi(evaluator: ActorSelection) {
|
private[report] final class ReportApi {
|
||||||
|
|
||||||
def create(setup: ReportSetup, by: User): Funit =
|
def create(setup: ReportSetup, by: User): Funit =
|
||||||
Reason(setup.reason).fold[Funit](fufail("Invalid report reason " + setup.reason)) { reason =>
|
Reason(setup.reason).fold[Funit](fufail("Invalid report reason " + setup.reason)) { reason =>
|
||||||
|
@ -25,15 +25,9 @@ private[report] final class ReportApi(evaluator: ActorSelection) {
|
||||||
selectRecent(user, reason),
|
selectRecent(user, reason),
|
||||||
Json.obj("$set" -> (reportTube.toMongo(report).get - "processedBy" - "_id"))
|
Json.obj("$set" -> (reportTube.toMongo(report).get - "processedBy" - "_id"))
|
||||||
) flatMap { res =>
|
) flatMap { res =>
|
||||||
(!res.updatedExisting) ?? {
|
(!res.updatedExisting) ?? $insert(report)
|
||||||
if (report.isCheat) evaluator ! user
|
|
||||||
$insert(report)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else $insert(report)
|
||||||
if (report.isCheat) evaluator ! user
|
|
||||||
$insert(report)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,7 @@ final class Env(
|
||||||
renderer = hub.actor.renderer
|
renderer = hub.actor.renderer
|
||||||
)), name = ReminderName),
|
)), name = ReminderName),
|
||||||
isOnline = isOnline,
|
isOnline = isOnline,
|
||||||
socketHub = socketHub,
|
socketHub = socketHub
|
||||||
evaluator = hub.actor.evaluator
|
|
||||||
)), name = OrganizerName)
|
)), name = OrganizerName)
|
||||||
|
|
||||||
private val tournamentScheduler = system.actorOf(Props(new Scheduler(api)))
|
private val tournamentScheduler = system.actorOf(Props(new Scheduler(api)))
|
||||||
|
@ -123,10 +122,6 @@ final class Env(
|
||||||
organizer -> actorApi.StartedTournaments
|
organizer -> actorApi.StartedTournaments
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduler.message(6 minutes) {
|
|
||||||
organizer -> actorApi.CheckLeaders
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler.message(5 minutes) {
|
scheduler.message(5 minutes) {
|
||||||
tournamentScheduler -> actorApi.ScheduleNow
|
tournamentScheduler -> actorApi.ScheduleNow
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,7 @@ private[tournament] final class Organizer(
|
||||||
api: TournamentApi,
|
api: TournamentApi,
|
||||||
reminder: ActorRef,
|
reminder: ActorRef,
|
||||||
isOnline: String => Boolean,
|
isOnline: String => Boolean,
|
||||||
socketHub: ActorRef,
|
socketHub: ActorRef) extends Actor {
|
||||||
evaluator: ActorSelection) extends Actor {
|
|
||||||
|
|
||||||
context.system.lilaBus.subscribe(self, 'finishGame, 'adjustCheater)
|
context.system.lilaBus.subscribe(self, 'finishGame, 'adjustCheater)
|
||||||
|
|
||||||
|
@ -42,12 +41,6 @@ private[tournament] final class Organizer(
|
||||||
reminder ! RemindTournaments(tours)
|
reminder ! RemindTournaments(tours)
|
||||||
}
|
}
|
||||||
|
|
||||||
case CheckLeaders => TournamentRepo.started foreach {
|
|
||||||
_.flatMap(_.leaders).map(_.id).distinct foreach { id =>
|
|
||||||
evaluator ! lila.hub.actorApi.evaluation.AutoCheck(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case FinishGame(game, _, _) => api finishGame game
|
case FinishGame(game, _, _) => api finishGame game
|
||||||
|
|
||||||
case lila.hub.actorApi.mod.MarkCheater(userId) => api ejectCheater userId
|
case lila.hub.actorApi.mod.MarkCheater(userId) => api ejectCheater userId
|
||||||
|
|
|
@ -32,7 +32,6 @@ private[tournament] case class Connected(enumerator: JsEnumerator, member: Membe
|
||||||
// organizer
|
// organizer
|
||||||
private[tournament] case object AllCreatedTournaments
|
private[tournament] case object AllCreatedTournaments
|
||||||
private[tournament] case object StartedTournaments
|
private[tournament] case object StartedTournaments
|
||||||
private[tournament] case object CheckLeaders
|
|
||||||
case class RemindTournaments(tours: List[Started])
|
case class RemindTournaments(tours: List[Started])
|
||||||
case class RemindTournament(tour: Started)
|
case class RemindTournament(tour: Started)
|
||||||
case class TournamentTable(tours: List[Enterable])
|
case class TournamentTable(tours: List[Enterable])
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 16586282ce3d6cf67459582a612aa17571ffc9d0
|
|
Loading…
Reference in New Issue