parent
4fda166190
commit
14ef3298b4
|
@ -28,15 +28,6 @@ object Irwin extends LilaController {
|
|||
}
|
||||
}
|
||||
|
||||
def getRequest = Open { implicit ctx =>
|
||||
ModExternalBot {
|
||||
Env.irwin.api.requests.getAndStart map {
|
||||
case None => NotFound
|
||||
case Some(req) => Ok(req.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def assessment(username: String) = Open { implicit ctx =>
|
||||
ModExternalBot {
|
||||
OptionFuResult(UserRepo named username) { user =>
|
||||
|
|
|
@ -4,7 +4,7 @@ import lila.api.Context
|
|||
import lila.app._
|
||||
import lila.chat.Chat
|
||||
import lila.common.{ IpAddress, EmailAddress }
|
||||
import lila.report.{ Suspect, Mod => AsMod }
|
||||
import lila.report.{ Suspect, Mod => AsMod, SuspectId }
|
||||
import lila.user.{ UserRepo, User => UserModel }
|
||||
import views._
|
||||
|
||||
|
@ -194,7 +194,7 @@ object Mod extends LilaController {
|
|||
|
||||
def refreshUserAssess(username: String) = Secure(_.MarkEngine) { implicit ctx => me =>
|
||||
assessApi.refreshAssessByUsername(username) >>
|
||||
Env.irwin.api.requests.fromMod(lila.user.User normalize username, me) inject
|
||||
Env.irwin.api.requests.fromMod(SuspectId normalize username, me) inject
|
||||
redirect(username)
|
||||
}
|
||||
|
||||
|
|
|
@ -248,7 +248,7 @@ object User extends LilaController {
|
|||
Env.plan.api.recentChargesOf(user) zip
|
||||
Env.report.api.byAndAbout(user, 20) zip
|
||||
Env.pref.api.getPref(user) zip
|
||||
Env.irwin.api.status(user) flatMap {
|
||||
Env.irwin.api.reports.withPovs(user) flatMap {
|
||||
case emails ~ spy ~ assess ~ history ~ charges ~ reports ~ pref ~ irwin =>
|
||||
val familyUserIds = user.id :: spy.otherUserIds.toList
|
||||
Env.playban.api.bans(familyUserIds) zip
|
||||
|
|
|
@ -28,37 +28,7 @@ moreCss = cssTag("mod-irwin.css")) {
|
|||
</h1>
|
||||
<div class="both">
|
||||
<div class="queue">
|
||||
<table class="slist">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Queued request</th>
|
||||
<th>Created</th>
|
||||
<th>Started</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@dashboard.queue.map { req =>
|
||||
<tr class="request @if(req.isInProgress){started}">
|
||||
<td>
|
||||
@userIdLink(req.id.some, params = "?mod")
|
||||
</td>
|
||||
<td class="little for">
|
||||
@momentFromNow(req.createdAt)<br />
|
||||
@req.notifyUserId.map { modId =>
|
||||
by @userIdSpanMini(modId, withOnline = true)
|
||||
}.getOrElse {
|
||||
by @req.origin
|
||||
}
|
||||
</td>
|
||||
<td class="little">
|
||||
@req.startedAt.map { at =>
|
||||
@momentFromNow(at)
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
We no longer know what irwin is up to.
|
||||
</div>
|
||||
<div class="recent">
|
||||
<table class="slist">
|
||||
|
@ -73,7 +43,7 @@ moreCss = cssTag("mod-irwin.css")) {
|
|||
@dashboard.recent.map { rep =>
|
||||
<tr class="report">
|
||||
<td>
|
||||
@userIdLink(rep.id.some, params = "?mod")
|
||||
@userIdLink(rep.suspectId.value.some, params = "?mod")
|
||||
</td>
|
||||
<td class="little completed">
|
||||
@momentFromNow(rep.date)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(report: lila.irwin.IrwinReport.WithPovs, request: Option[lila.irwin.IrwinRequest])(implicit ctx: Context)
|
||||
@(report: lila.irwin.IrwinReport.WithPovs)(implicit ctx: Context)
|
||||
|
||||
@percentClass(percent: Int) = { @percent match {
|
||||
case p if p < 30 => {green}
|
||||
|
@ -16,12 +16,6 @@ case _ => {red}
|
|||
</a>
|
||||
<div class="infos">
|
||||
<p>Updated @momentFromNow(report.report.date)</p>
|
||||
@request.map { r =>
|
||||
<p>New update is in progress</p>
|
||||
<p>Requested @momentFromNow(r.createdAt) by: @r.origin</p>
|
||||
}.getOrElse {
|
||||
<p>Hit "Evaluate" to update</p>
|
||||
}
|
||||
</div>
|
||||
<div class="assess text">
|
||||
<strong class="@percentClass(report.report.activation)">@report.report.activation%</strong>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(u: User, emails: User.Emails, spy: lila.security.UserSpy, optionAggregateAssessment: Option[lila.evaluation.PlayerAggregateAssessment.WithGames], bans: Map[String, Int], history: List[lila.mod.Modlog], charges: List[lila.plan.Charge], reports: lila.report.Report.ByAndAbout, pref: lila.pref.Pref, irwinStatus: lila.irwin.IrwinStatus, notes: List[lila.user.Note])(implicit ctx: Context)
|
||||
@(u: User, emails: User.Emails, spy: lila.security.UserSpy, optionAggregateAssessment: Option[lila.evaluation.PlayerAggregateAssessment.WithGames], bans: Map[String, Int], history: List[lila.mod.Modlog], charges: List[lila.plan.Charge], reports: lila.report.Report.ByAndAbout, pref: lila.pref.Pref, irwinReport: Option[lila.irwin.IrwinReport.WithPovs], notes: List[lila.user.Note])(implicit ctx: Context)
|
||||
|
||||
@import lila.evaluation.Display
|
||||
@import lila.pref.Pref
|
||||
|
@ -105,13 +105,8 @@
|
|||
<strong class="text inline" data-icon="%">Notable preferences:</strong>
|
||||
@if(pref.keyboardMove != Pref.KeyboardMove.NO) { [keyboard moves] } else { none }
|
||||
</div>
|
||||
@irwinStatus.report.map { report =>
|
||||
@views.html.irwin.irwinReport(report, irwinStatus.request)
|
||||
}.getOrElse {
|
||||
@irwinStatus.request.map { request =>
|
||||
<strong class="inline text" data-icon="">Irwin request:</strong>
|
||||
in progress, requested @momentFromNow(request.createdAt) by: @request.origin
|
||||
}
|
||||
@irwinReport.map { report =>
|
||||
@views.html.irwin.irwinReport(report)
|
||||
}
|
||||
@optionAggregateAssessment.map { pag =>
|
||||
<div class="evaluation results">
|
||||
|
|
|
@ -405,7 +405,6 @@ POST /mod/chat-panic controllers.Mod.chatPanicPost
|
|||
GET /irwin controllers.Irwin.dashboard
|
||||
GET /irwin/stream controllers.Irwin.eventStream
|
||||
POST /irwin/report controllers.Irwin.saveReport
|
||||
GET /irwin/request controllers.Irwin.getRequest
|
||||
GET /irwin/:username/assessment controllers.Irwin.assessment(username: String)
|
||||
GET /irwin/users-mark-and-current-report controllers.Irwin.usersMarkAndCurrentReport(ids: String)
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package lila.irwin
|
||||
|
||||
import reactivemongo.bson._
|
||||
|
||||
import lila.db.dsl._
|
||||
import lila.db.BSON
|
||||
import reactivemongo.bson._
|
||||
import lila.report.ReporterId
|
||||
|
||||
object BSONHandlers {
|
||||
|
||||
|
@ -35,19 +37,6 @@ object BSONHandlers {
|
|||
|
||||
private implicit val GameReportBSONHandler = Macros.handler[GameReport]
|
||||
private implicit val PvBSONHandler = nullableHandler[Int, BSONInteger]
|
||||
private implicit val ReporterIdBSONHandler = stringIsoHandler[ReporterId](ReporterId.reporterIdIso)
|
||||
implicit val ReportBSONHandler = Macros.handler[IrwinReport]
|
||||
|
||||
private implicit val RequestOriginBSONHandler: BSONHandler[BSONString, IrwinRequest.Origin] =
|
||||
new BSONHandler[BSONString, IrwinRequest.Origin] {
|
||||
import IrwinRequest.Origin, Origin._
|
||||
def read(bs: BSONString) = bs.value match {
|
||||
case "moderator" => Moderator
|
||||
case "report" => Report
|
||||
case "tournament" => Tournament
|
||||
case "leaderboard" => Leaderboard
|
||||
case _ => sys error s"Invalid origin ${bs.value}"
|
||||
}
|
||||
def write(x: Origin) = BSONString(x.key)
|
||||
}
|
||||
implicit val RequestBSONHandler = Macros.handler[IrwinRequest]
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ final class Env(
|
|||
) {
|
||||
|
||||
private val reportColl = db(config getString "collection.report")
|
||||
private val requestColl = db(config getString "collection.request")
|
||||
|
||||
lazy val irwinModeSetting = settingStore[String](
|
||||
"irwinMode",
|
||||
|
@ -28,31 +27,23 @@ final class Env(
|
|||
text = "Allow Irwin to: [mark|report|none]".some
|
||||
)
|
||||
|
||||
val api = new IrwinApi(
|
||||
val stream = new IrwinStream(system)
|
||||
|
||||
lazy val api = new IrwinApi(
|
||||
reportColl = reportColl,
|
||||
requestColl = requestColl,
|
||||
modApi = modApi,
|
||||
reportApi = reportApi,
|
||||
notifyApi = notifyApi,
|
||||
bus = system.lilaBus,
|
||||
mode = irwinModeSetting.get
|
||||
)
|
||||
|
||||
lazy val stream = new IrwinStream(system)
|
||||
|
||||
scheduler.future(5 minutes, "irwin tournament leaders") {
|
||||
tournamentApi.allCurrentLeadersInStandard flatMap api.requests.fromTournamentLeaders
|
||||
}
|
||||
scheduler.future(15 minutes, "irwin leaderboards") {
|
||||
userCache.getTop50Online flatMap api.requests.fromLeaderboard
|
||||
}
|
||||
|
||||
system.lilaBus.subscribe(system.actorOf(Props(new Actor {
|
||||
import lila.hub.actorApi.report._
|
||||
def receive = {
|
||||
case Created(userId, "cheat" | "cheatprint", reporterId) => api.requests.insert(userId, _.Report, none)
|
||||
case Processed(userId, "cheat" | "cheatprint") => api.requests.drop(userId)
|
||||
}
|
||||
})), 'report)
|
||||
}
|
||||
|
||||
object Env {
|
||||
|
|
|
@ -5,38 +5,31 @@ import reactivemongo.bson._
|
|||
|
||||
import lila.db.dsl._
|
||||
import lila.game.{ Pov, GameRepo }
|
||||
import lila.report.{ Report, Mod, Suspect, Reporter }
|
||||
import lila.report.{ Report, Mod, Suspect, Reporter, SuspectId, ModId }
|
||||
import lila.tournament.{ Tournament, TournamentTop }
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
final class IrwinApi(
|
||||
reportColl: Coll,
|
||||
requestColl: Coll,
|
||||
modApi: lila.mod.ModApi,
|
||||
reportApi: lila.report.ReportApi,
|
||||
notifyApi: lila.notify.NotifyApi,
|
||||
bus: lila.common.Bus,
|
||||
mode: () => String
|
||||
) {
|
||||
|
||||
import BSONHandlers._
|
||||
|
||||
def status(user: User): Fu[IrwinStatus] =
|
||||
reports.withPovs(user) zip requests.get(user.id) map { (IrwinStatus.apply _).tupled }
|
||||
|
||||
def dashboard: Fu[IrwinDashboard] = for {
|
||||
queue <- requestColl.find($empty).sort($sort asc "priority").list[IrwinRequest](20)
|
||||
recent <- reportColl.find($empty).sort($sort desc "date").list[IrwinReport](20)
|
||||
} yield IrwinDashboard(queue, recent)
|
||||
def dashboard: Fu[IrwinDashboard] =
|
||||
reportColl.find($empty).sort($sort desc "date").list[IrwinReport](20) map IrwinDashboard.apply
|
||||
|
||||
object reports {
|
||||
|
||||
def insert(report: IrwinReport) = (mode() != "none") ?? {
|
||||
for {
|
||||
_ <- reportColl.update($id(report.id), report, upsert = true)
|
||||
request <- requests get report.id
|
||||
_ <- request.??(r => requests.drop(r.id))
|
||||
_ <- request.??(notifyRequester)
|
||||
_ <- reportColl.update($id(report._id), report, upsert = true)
|
||||
_ <- markOrReport(report)
|
||||
_ <- notification(report)
|
||||
} yield ()
|
||||
}
|
||||
|
||||
|
@ -59,10 +52,10 @@ final class IrwinApi(
|
|||
|
||||
private def markOrReport(report: IrwinReport): Funit =
|
||||
if (report.activation > 90 && mode() == "mark")
|
||||
modApi.autoMark(report.userId, "irwin") >>-
|
||||
modApi.autoMark(report.suspectId, ModId.irwin) >>-
|
||||
lila.mon.mod.irwin.mark()
|
||||
else if (report.activation >= 60 && mode() != "none") for {
|
||||
suspect <- getSuspect(report.userId)
|
||||
suspect <- getSuspect(report.suspectId.value)
|
||||
irwin <- UserRepo byId "irwin" flatten s"Irwin user not found" map Mod.apply
|
||||
_ <- reportApi.create(Report.Candidate(
|
||||
reporter = Reporter(irwin.user),
|
||||
|
@ -78,32 +71,17 @@ final class IrwinApi(
|
|||
|
||||
import IrwinRequest.Origin
|
||||
|
||||
def getAndStart: Fu[Option[IrwinRequest]] =
|
||||
requestColl
|
||||
.find($doc("startedAt" $exists false))
|
||||
.sort($sort asc "priority")
|
||||
.uno[IrwinRequest] flatMap {
|
||||
_ ?? { request =>
|
||||
requestColl.updateField($id(request.id), "startedAt", DateTime.now) inject request.some
|
||||
}
|
||||
}
|
||||
def fromMod(suspectId: SuspectId, mod: User) = {
|
||||
notification.add(suspectId, ModId(mod.id))
|
||||
insert(suspectId, _.Moderator)
|
||||
}
|
||||
|
||||
def get(reportedId: User.ID): Fu[Option[IrwinRequest]] =
|
||||
requestColl.byId[IrwinRequest](reportedId)
|
||||
|
||||
def fromMod(reportedId: User.ID, mod: User) = insert(reportedId, _.Moderator, mod.id.some)
|
||||
|
||||
private[irwin] def drop(reportedId: User.ID): Funit = requestColl.remove($id(reportedId)).void
|
||||
|
||||
private[irwin] def insert(reportedId: User.ID, origin: Origin.type => Origin, notifyUserId: Option[User.ID]) = {
|
||||
val request = IrwinRequest.make(reportedId, origin(Origin), notifyUserId)
|
||||
get(reportedId) flatMap {
|
||||
case Some(prev) if prev.isInProgress => funit
|
||||
case Some(prev) if prev.priority isAfter request.priority =>
|
||||
requestColl.update($id(request.id), request).void
|
||||
case Some(prev) => funit
|
||||
case None => requestColl.insert(request).void
|
||||
}
|
||||
private[irwin] def insert(suspectId: SuspectId, origin: Origin.type => Origin): Funit = fuccess {
|
||||
bus.publish(IrwinRequest(
|
||||
suspect = suspectId,
|
||||
origin = origin(Origin),
|
||||
date = DateTime.now
|
||||
), 'irwin)
|
||||
}
|
||||
|
||||
private[irwin] def fromTournamentLeaders(leaders: Map[Tournament, TournamentTop]): Funit =
|
||||
|
@ -111,20 +89,29 @@ final class IrwinApi(
|
|||
case (tour, top) =>
|
||||
val userIds = top.value.zipWithIndex.filter(_._2 <= tour.nbPlayers * 2 / 100).map(_._1.userId)
|
||||
lila.common.Future.applySequentially(userIds) { userId =>
|
||||
insert(userId, _.Tournament, none)
|
||||
insert(SuspectId(userId), _.Tournament)
|
||||
}
|
||||
}
|
||||
|
||||
private[irwin] def fromLeaderboard(leaders: List[User]): Funit =
|
||||
lila.common.Future.applySequentially(leaders) { user =>
|
||||
insert(user.id, _.Leaderboard, none)
|
||||
insert(SuspectId(user.id), _.Leaderboard)
|
||||
}
|
||||
}
|
||||
|
||||
private def notifyRequester(request: IrwinRequest): Funit = request.notifyUserId ?? { userId =>
|
||||
import lila.notify.{ Notification, IrwinDone }
|
||||
notifyApi.addNotification(
|
||||
Notification.make(Notification.Notifies(userId), IrwinDone(request.id))
|
||||
)
|
||||
object notification {
|
||||
|
||||
private var subs = Map.empty[SuspectId, ModId]
|
||||
|
||||
def add(suspectId: SuspectId, modId: ModId): Unit = subs += (suspectId -> modId)
|
||||
|
||||
private[IrwinApi] def apply(report: IrwinReport): Funit =
|
||||
subs.get(report.suspectId) ?? { modId =>
|
||||
subs = subs - report.suspectId
|
||||
import lila.notify.{ Notification, IrwinDone }
|
||||
notifyApi.addNotification(
|
||||
Notification.make(Notification.Notifies(modId.value), IrwinDone(report.suspectId.value))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,7 @@ package lila.irwin
|
|||
|
||||
import org.joda.time.DateTime
|
||||
|
||||
case class IrwinDashboard(
|
||||
queue: List[IrwinRequest],
|
||||
recent: List[IrwinReport]
|
||||
) {
|
||||
case class IrwinDashboard(recent: List[IrwinReport]) {
|
||||
|
||||
def lastSeenAt = recent.headOption.map(_.date)
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package lila.irwin
|
||||
|
||||
import lila.game.{ Game, Pov }
|
||||
|
||||
import org.joda.time.DateTime
|
||||
|
||||
import lila.game.{ Game, Pov }
|
||||
import lila.report.{ SuspectId, ReporterId }
|
||||
|
||||
case class IrwinReport(
|
||||
_id: String, // user id
|
||||
activation: Int, // 0 = clean, 100 = cheater
|
||||
|
@ -11,12 +12,9 @@ case class IrwinReport(
|
|||
date: DateTime
|
||||
) {
|
||||
|
||||
def id = _id
|
||||
def userId = _id
|
||||
def suspectId = SuspectId(_id)
|
||||
}
|
||||
|
||||
case class IrwinStatus(report: Option[IrwinReport.WithPovs], request: Option[IrwinRequest])
|
||||
|
||||
object IrwinReport {
|
||||
|
||||
case class GameReport(
|
||||
|
|
|
@ -2,21 +2,14 @@ package lila.irwin
|
|||
|
||||
import org.joda.time.DateTime
|
||||
|
||||
import lila.report.{ SuspectId, ReporterId }
|
||||
import lila.user.User
|
||||
|
||||
case class IrwinRequest(
|
||||
_id: User.ID,
|
||||
suspect: SuspectId,
|
||||
origin: IrwinRequest.Origin,
|
||||
priority: DateTime, // older = more prioritary; affected by origin
|
||||
createdAt: DateTime,
|
||||
startedAt: Option[DateTime],
|
||||
notifyUserId: Option[User.ID]
|
||||
) {
|
||||
|
||||
def id = _id
|
||||
|
||||
def isInProgress = startedAt.isDefined
|
||||
}
|
||||
date: DateTime
|
||||
)
|
||||
|
||||
object IrwinRequest {
|
||||
|
||||
|
@ -26,24 +19,7 @@ object IrwinRequest {
|
|||
|
||||
object Origin {
|
||||
case object Moderator extends Origin
|
||||
case object Report extends Origin
|
||||
case object Tournament extends Origin
|
||||
case object Leaderboard extends Origin
|
||||
}
|
||||
|
||||
def make(userId: User.ID, origin: Origin, notifyUserId: Option[User.ID]) = IrwinRequest(
|
||||
_id = userId,
|
||||
origin = origin,
|
||||
priority = DateTime.now minusHours originPriorityDays(origin),
|
||||
createdAt = DateTime.now,
|
||||
startedAt = none,
|
||||
notifyUserId = notifyUserId
|
||||
)
|
||||
|
||||
private def originPriorityDays(origin: Origin) = origin match {
|
||||
case Origin.Moderator => 1000
|
||||
case Origin.Report => 20
|
||||
case Origin.Tournament => -1000
|
||||
case Origin.Leaderboard => -1000
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,25 @@ final class IrwinStream(system: ActorSystem) {
|
|||
onStart = channel => {
|
||||
val actor = system.actorOf(Props(new Actor {
|
||||
def receive = {
|
||||
case request: IrwinRequest =>
|
||||
channel push Json.obj(
|
||||
"t" -> "request",
|
||||
"origin" -> request.origin.key,
|
||||
"user" -> request.suspect.value
|
||||
)
|
||||
case lila.hub.actorApi.report.Created(userId, "cheat" | "cheatprint", _) =>
|
||||
channel push Json.obj(
|
||||
"t" -> "report",
|
||||
"t" -> "reportCreated",
|
||||
"user" -> userId
|
||||
)
|
||||
case lila.hub.actorApi.report.Processed(userId, "cheat" | "cheatprint") =>
|
||||
lila.user.UserRepo.isEngine(userId) foreach { marked =>
|
||||
channel push Json.obj(
|
||||
"t" -> "reportProcessed",
|
||||
"user" -> userId,
|
||||
"marked" -> marked
|
||||
)
|
||||
}
|
||||
case lila.hub.actorApi.mod.MarkCheater(userId, value) =>
|
||||
channel push Json.obj(
|
||||
"t" -> "mark",
|
||||
|
@ -30,7 +44,7 @@ final class IrwinStream(system: ActorSystem) {
|
|||
)
|
||||
}
|
||||
}))
|
||||
system.lilaBus.subscribe(actor, 'report, 'adjustCheater)
|
||||
system.lilaBus.subscribe(actor, 'report, 'adjustCheater, 'irwin)
|
||||
},
|
||||
onComplete = {
|
||||
stream.foreach { actor =>
|
||||
|
|
|
@ -8,6 +8,7 @@ import lila.evaluation.Statistics
|
|||
import lila.evaluation.{ AccountAction, Analysed, PlayerAssessment, PlayerAggregateAssessment, PlayerFlags, PlayerAssessments, Assessible }
|
||||
import lila.game.{ Game, Player, GameRepo, Source, Pov }
|
||||
import lila.user.{ User, UserRepo }
|
||||
import lila.report.{ SuspectId, ModId }
|
||||
|
||||
import reactivemongo.api.ReadPreference
|
||||
import reactivemongo.bson._
|
||||
|
@ -112,7 +113,7 @@ final class AssessApi(
|
|||
case Some(playerAggregateAssessment) => playerAggregateAssessment.action match {
|
||||
case AccountAction.Engine | AccountAction.EngineAndBan =>
|
||||
UserRepo.getTitle(userId).flatMap {
|
||||
case None => modApi.autoMark(userId, "lichess")
|
||||
case None => modApi.autoMark(SuspectId(userId), ModId.lichess)
|
||||
case Some(title) => fuccess {
|
||||
val reason = s"Would mark as engine, but has a $title title"
|
||||
reporter ! lila.hub.actorApi.report.Cheater(userId, playerAggregateAssessment.reportText(reason, 3))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package lila.mod
|
||||
|
||||
import lila.common.{ IpAddress, EmailAddress }
|
||||
import lila.report.{ Mod, Suspect, Room }
|
||||
import lila.report.{ Mod, ModId, Suspect, SuspectId, Room }
|
||||
import lila.security.Permission
|
||||
import lila.security.{ Firewall, UserSpy, Store => SecurityStore }
|
||||
import lila.user.{ User, UserRepo, LightUserApi }
|
||||
|
@ -33,10 +33,10 @@ final class ModApi(
|
|||
}
|
||||
}
|
||||
|
||||
def autoMark(username: String, modId: User.ID): Funit = for {
|
||||
sus <- reportApi.getSuspect(username) flatten s"No such suspect $username"
|
||||
def autoMark(suspectId: SuspectId, modId: ModId): Funit = for {
|
||||
sus <- reportApi.getSuspect(suspectId.value) flatten s"No such suspect $suspectId"
|
||||
unengined <- logApi.wasUnengined(sus)
|
||||
_ <- if (unengined) funit else reportApi.getMod(modId) flatMap {
|
||||
_ <- if (unengined) funit else reportApi.getMod(modId.value) flatMap {
|
||||
_ ?? { mod =>
|
||||
lila.mon.cheat.autoMark.count()
|
||||
setEngine(mod, sus, true)
|
||||
|
|
|
@ -4,10 +4,20 @@ import lila.user.User
|
|||
|
||||
case class Mod(user: User) extends AnyVal
|
||||
|
||||
case class ModId(value: User.ID) extends AnyVal
|
||||
object ModId {
|
||||
def lichess = ModId("lichess")
|
||||
def irwin = ModId("irwin")
|
||||
def normalize(username: String) = ModId(User normalize username)
|
||||
}
|
||||
|
||||
case class Suspect(user: User) extends AnyVal {
|
||||
def set(f: User => User) = copy(user = f(user))
|
||||
}
|
||||
case class SuspectId(value: User.ID) extends AnyVal
|
||||
object SuspectId {
|
||||
def normalize(username: String) = SuspectId(User normalize username)
|
||||
}
|
||||
|
||||
case class Victim(user: User) extends AnyVal
|
||||
|
||||
|
|
Loading…
Reference in New Issue